diff options
89 files changed, 1478 insertions, 942 deletions
diff --git a/api/current.txt b/api/current.txt index 691ec04a6cbf..e01ddb62ee23 100644 --- a/api/current.txt +++ b/api/current.txt @@ -338,6 +338,7 @@ package android { field public static final int calendarViewStyle = 16843613; // 0x101035d field public static final int canControlMagnification = 16844040; // 0x1010508 field public static final int canPerformGestures = 16844046; // 0x101050e + field public static final int canRecord = 16844061; // 0x101051d field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8 field public static final int canRequestFilterKeyEvents = 16843737; // 0x10103d9 field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7 @@ -1359,6 +1360,7 @@ package android { field public static final int trimPathEnd = 16843785; // 0x1010409 field public static final int trimPathOffset = 16843786; // 0x101040a field public static final int trimPathStart = 16843784; // 0x1010408 + field public static final int tunerCount = 16844062; // 0x101051e field public static final int type = 16843169; // 0x10101a1 field public static final int typeface = 16842902; // 0x1010096 field public static final int uiOptions = 16843672; // 0x1010398 @@ -5885,6 +5887,7 @@ package android.app.admin { method public boolean hasGrantedPolicy(android.content.ComponentName, int); method public boolean installCaCert(android.content.ComponentName, byte[]); method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String); + method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String, boolean); method public boolean isActivePasswordSufficient(); method public boolean isAdminActive(android.content.ComponentName); method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String); @@ -29544,6 +29547,7 @@ package android.preference { method protected int getPersistedInt(int); method protected long getPersistedLong(long); method protected java.lang.String getPersistedString(java.lang.String); + method public java.util.Set<java.lang.String> getPersistedStringSet(java.util.Set<java.lang.String>); method public android.preference.PreferenceManager getPreferenceManager(); method public android.content.SharedPreferences getSharedPreferences(); method public boolean getShouldDisableView(); @@ -29578,6 +29582,7 @@ package android.preference { method protected boolean persistInt(int); method protected boolean persistLong(long); method protected boolean persistString(java.lang.String); + method public boolean persistStringSet(java.util.Set<java.lang.String>); method public void restoreHierarchyState(android.os.Bundle); method public void saveHierarchyState(android.os.Bundle); method public void setDefaultValue(java.lang.Object); @@ -37135,12 +37140,18 @@ package android.telephony { method public int getVoiceNetworkType(int); method public android.net.Uri getVoicemailRingtoneUri(android.telecom.PhoneAccountHandle); method public boolean hasCarrierPrivileges(); + method public boolean hasCarrierPrivileges(int); method public boolean hasIccCard(); method public boolean iccCloseLogicalChannel(int); + method public boolean iccCloseLogicalChannel(int, int); method public byte[] iccExchangeSimIO(int, int, int, int, int, java.lang.String); + method public byte[] iccExchangeSimIO(int, int, int, int, int, int, java.lang.String); method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String); + method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(int, java.lang.String); method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String); + method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, int, java.lang.String); method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String); + method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, int, java.lang.String); method public boolean isHearingAidCompatibilitySupported(); method public boolean isNetworkRoaming(); method public boolean isNetworkRoaming(int); @@ -37151,10 +37162,13 @@ package android.telephony { method public boolean isWorldPhone(); method public void listen(android.telephony.PhoneStateListener, int); method public java.lang.String sendEnvelopeWithStatus(java.lang.String); + method public java.lang.String sendEnvelopeWithStatus(int, java.lang.String); method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String); method public boolean setLine1NumberForDisplay(int, java.lang.String, java.lang.String); method public boolean setOperatorBrandOverride(java.lang.String); + method public boolean setOperatorBrandOverride(int, java.lang.String); method public boolean setPreferredNetworkTypeToGlobal(); + method public boolean setPreferredNetworkTypeToGlobal(int); method public boolean setVoiceMailNumber(java.lang.String, java.lang.String); method public boolean setVoiceMailNumber(int, java.lang.String, java.lang.String); field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL"; diff --git a/api/system-current.txt b/api/system-current.txt index 2374f0168f8b..de251b06b8f9 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -433,6 +433,7 @@ package android { field public static final int calendarViewStyle = 16843613; // 0x101035d field public static final int canControlMagnification = 16844040; // 0x1010508 field public static final int canPerformGestures = 16844046; // 0x101050e + field public static final int canRecord = 16844061; // 0x101051d field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8 field public static final int canRequestFilterKeyEvents = 16843737; // 0x10103d9 field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7 @@ -1458,6 +1459,7 @@ package android { field public static final int trimPathEnd = 16843785; // 0x1010409 field public static final int trimPathOffset = 16843786; // 0x101040a field public static final int trimPathStart = 16843784; // 0x1010408 + field public static final int tunerCount = 16844062; // 0x101051e field public static final int type = 16843169; // 0x10101a1 field public static final int typeface = 16842902; // 0x1010096 field public static final int uiOptions = 16843672; // 0x1010398 @@ -6031,6 +6033,7 @@ package android.app.admin { method public boolean hasGrantedPolicy(android.content.ComponentName, int); method public boolean installCaCert(android.content.ComponentName, byte[]); method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String); + method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String, boolean); method public boolean isActivePasswordSufficient(); method public boolean isAdminActive(android.content.ComponentName); method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String); @@ -9703,25 +9706,6 @@ package android.content.pm { field public int reqTouchScreen; } - public deprecated class ContainerEncryptionParams implements android.os.Parcelable { - ctor public ContainerEncryptionParams(java.lang.String, java.security.spec.AlgorithmParameterSpec, javax.crypto.SecretKey) throws java.security.InvalidAlgorithmParameterException; - ctor public ContainerEncryptionParams(java.lang.String, java.security.spec.AlgorithmParameterSpec, javax.crypto.SecretKey, java.lang.String, java.security.spec.AlgorithmParameterSpec, javax.crypto.SecretKey, byte[], long, long, long) throws java.security.InvalidAlgorithmParameterException; - method public int describeContents(); - method public long getAuthenticatedDataStart(); - method public long getDataEnd(); - method public long getEncryptedDataStart(); - method public java.lang.String getEncryptionAlgorithm(); - method public javax.crypto.SecretKey getEncryptionKey(); - method public java.security.spec.AlgorithmParameterSpec getEncryptionSpec(); - method public java.lang.String getMacAlgorithm(); - method public javax.crypto.SecretKey getMacKey(); - method public java.security.spec.AlgorithmParameterSpec getMacSpec(); - method public byte[] getMacTag(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.content.pm.ContainerEncryptionParams> CREATOR; - field protected static final java.lang.String TAG = "ContainerEncryptionParams"; - } - public final class EphemeralResolveInfo implements android.os.Parcelable { ctor public EphemeralResolveInfo(android.net.Uri, java.lang.String, java.util.List<android.content.IntentFilter>); method public int describeContents(); @@ -31913,6 +31897,7 @@ package android.preference { method protected int getPersistedInt(int); method protected long getPersistedLong(long); method protected java.lang.String getPersistedString(java.lang.String); + method public java.util.Set<java.lang.String> getPersistedStringSet(java.util.Set<java.lang.String>); method public android.preference.PreferenceManager getPreferenceManager(); method public android.content.SharedPreferences getSharedPreferences(); method public boolean getShouldDisableView(); @@ -31947,6 +31932,7 @@ package android.preference { method protected boolean persistInt(int); method protected boolean persistLong(long); method protected boolean persistString(java.lang.String); + method public boolean persistStringSet(java.util.Set<java.lang.String>); method public void restoreHierarchyState(android.os.Bundle); method public void saveHierarchyState(android.os.Bundle); method public void setDefaultValue(java.lang.Object); @@ -37147,6 +37133,7 @@ package android.service.persistentdata { public abstract interface IPersistentDataBlockService implements android.os.IInterface { method public abstract int getDataBlockSize() throws android.os.RemoteException; + method public abstract int getFlashLockState() throws android.os.RemoteException; method public abstract long getMaximumDataBlockSize() throws android.os.RemoteException; method public abstract boolean getOemUnlockEnabled() throws android.os.RemoteException; method public abstract byte[] read() throws android.os.RemoteException; @@ -37158,12 +37145,19 @@ package android.service.persistentdata { public class PersistentDataBlockManager { ctor public PersistentDataBlockManager(android.service.persistentdata.IPersistentDataBlockService); method public int getDataBlockSize(); + method public int getFlashLockState(); method public long getMaximumDataBlockSize(); method public boolean getOemUnlockEnabled(); method public byte[] read(); method public void setOemUnlockEnabled(boolean); method public void wipe(); method public int write(byte[]); + field public static final int FLASH_LOCK_LOCKED = 1; // 0x1 + field public static final int FLASH_LOCK_UNKNOWN = -1; // 0xffffffff + field public static final int FLASH_LOCK_UNLOCKED = 0; // 0x0 + } + + public static abstract class PersistentDataBlockManager.FlashLockState implements java.lang.annotation.Annotation { } } @@ -39865,12 +39859,18 @@ package android.telephony { method public boolean handlePinMmi(java.lang.String); method public boolean handlePinMmiForSubscriber(int, java.lang.String); method public boolean hasCarrierPrivileges(); + method public boolean hasCarrierPrivileges(int); method public boolean hasIccCard(); method public boolean iccCloseLogicalChannel(int); + method public boolean iccCloseLogicalChannel(int, int); method public byte[] iccExchangeSimIO(int, int, int, int, int, java.lang.String); + method public byte[] iccExchangeSimIO(int, int, int, int, int, int, java.lang.String); method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String); + method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(int, java.lang.String); method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String); + method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, int, java.lang.String); method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String); + method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, int, java.lang.String); method public boolean isDataConnectivityPossible(); method public boolean isHearingAidCompatibilitySupported(); method public boolean isIdle(); @@ -39888,12 +39888,15 @@ package android.telephony { method public void listen(android.telephony.PhoneStateListener, int); method public boolean needsOtaServiceProvisioning(); method public java.lang.String sendEnvelopeWithStatus(java.lang.String); + method public java.lang.String sendEnvelopeWithStatus(int, java.lang.String); method public void setDataEnabled(boolean); method public void setDataEnabled(int, boolean); method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String); method public boolean setLine1NumberForDisplay(int, java.lang.String, java.lang.String); method public boolean setOperatorBrandOverride(java.lang.String); + method public boolean setOperatorBrandOverride(int, java.lang.String); method public boolean setPreferredNetworkTypeToGlobal(); + method public boolean setPreferredNetworkTypeToGlobal(int); method public boolean setRadio(boolean); method public boolean setRadioPower(boolean); method public boolean setVoiceMailNumber(java.lang.String, java.lang.String); diff --git a/api/test-current.txt b/api/test-current.txt index a86be5479e00..5cfbf63e2b80 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -338,6 +338,7 @@ package android { field public static final int calendarViewStyle = 16843613; // 0x101035d field public static final int canControlMagnification = 16844040; // 0x1010508 field public static final int canPerformGestures = 16844046; // 0x101050e + field public static final int canRecord = 16844061; // 0x101051d field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8 field public static final int canRequestFilterKeyEvents = 16843737; // 0x10103d9 field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7 @@ -1359,6 +1360,7 @@ package android { field public static final int trimPathEnd = 16843785; // 0x1010409 field public static final int trimPathOffset = 16843786; // 0x101040a field public static final int trimPathStart = 16843784; // 0x1010408 + field public static final int tunerCount = 16844062; // 0x101051e field public static final int type = 16843169; // 0x10101a1 field public static final int typeface = 16842902; // 0x1010096 field public static final int uiOptions = 16843672; // 0x1010398 @@ -5887,6 +5889,7 @@ package android.app.admin { method public boolean hasGrantedPolicy(android.content.ComponentName, int); method public boolean installCaCert(android.content.ComponentName, byte[]); method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String); + method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String, boolean); method public boolean isActivePasswordSufficient(); method public boolean isAdminActive(android.content.ComponentName); method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String); @@ -29554,6 +29557,7 @@ package android.preference { method protected int getPersistedInt(int); method protected long getPersistedLong(long); method protected java.lang.String getPersistedString(java.lang.String); + method public java.util.Set<java.lang.String> getPersistedStringSet(java.util.Set<java.lang.String>); method public android.preference.PreferenceManager getPreferenceManager(); method public android.content.SharedPreferences getSharedPreferences(); method public boolean getShouldDisableView(); @@ -29588,6 +29592,7 @@ package android.preference { method protected boolean persistInt(int); method protected boolean persistLong(long); method protected boolean persistString(java.lang.String); + method public boolean persistStringSet(java.util.Set<java.lang.String>); method public void restoreHierarchyState(android.os.Bundle); method public void saveHierarchyState(android.os.Bundle); method public void setDefaultValue(java.lang.Object); @@ -37150,12 +37155,18 @@ package android.telephony { method public int getVoiceNetworkType(int); method public android.net.Uri getVoicemailRingtoneUri(android.telecom.PhoneAccountHandle); method public boolean hasCarrierPrivileges(); + method public boolean hasCarrierPrivileges(int); method public boolean hasIccCard(); method public boolean iccCloseLogicalChannel(int); + method public boolean iccCloseLogicalChannel(int, int); method public byte[] iccExchangeSimIO(int, int, int, int, int, java.lang.String); + method public byte[] iccExchangeSimIO(int, int, int, int, int, int, java.lang.String); method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String); + method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(int, java.lang.String); method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String); + method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, int, java.lang.String); method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String); + method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, int, java.lang.String); method public boolean isHearingAidCompatibilitySupported(); method public boolean isNetworkRoaming(); method public boolean isNetworkRoaming(int); @@ -37166,10 +37177,13 @@ package android.telephony { method public boolean isWorldPhone(); method public void listen(android.telephony.PhoneStateListener, int); method public java.lang.String sendEnvelopeWithStatus(java.lang.String); + method public java.lang.String sendEnvelopeWithStatus(int, java.lang.String); method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String); method public boolean setLine1NumberForDisplay(int, java.lang.String, java.lang.String); method public boolean setOperatorBrandOverride(java.lang.String); + method public boolean setOperatorBrandOverride(int, java.lang.String); method public boolean setPreferredNetworkTypeToGlobal(); + method public boolean setPreferredNetworkTypeToGlobal(int); method public boolean setVoiceMailNumber(java.lang.String, java.lang.String); method public boolean setVoiceMailNumber(int, java.lang.String, java.lang.String); field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL"; diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 91eabcc36d09..1bd70b88a85d 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -30,7 +30,6 @@ import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ComponentInfo; -import android.content.pm.ContainerEncryptionParams; import android.content.pm.EphemeralApplicationInfo; import android.content.pm.FeatureInfo; import android.content.pm.IOnPermissionsChangeListener; @@ -54,7 +53,6 @@ import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; -import android.content.pm.VerificationParams; import android.content.pm.VerifierDeviceIdentity; import android.content.res.Resources; import android.content.res.XmlResourceParser; @@ -1470,80 +1468,27 @@ public class ApplicationPackageManager extends PackageManager { @Override public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName) { - final VerificationParams verificationParams = new VerificationParams(null, null, - null, VerificationParams.NO_UID); installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags, - installerPackageName, verificationParams, null, mContext.getUserId()); - } - - @Override - public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, - int flags, String installerPackageName, Uri verificationURI, - ContainerEncryptionParams encryptionParams) { - final VerificationParams verificationParams = new VerificationParams(verificationURI, null, - null, VerificationParams.NO_UID); - installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags, - installerPackageName, verificationParams, encryptionParams, mContext.getUserId()); - } - - @Override - public void installPackageWithVerificationAndEncryption(Uri packageURI, - IPackageInstallObserver observer, int flags, String installerPackageName, - VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { - installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags, - installerPackageName, verificationParams, encryptionParams, mContext.getUserId()); + installerPackageName, mContext.getUserId()); } @Override public void installPackage(Uri packageURI, PackageInstallObserver observer, int flags, String installerPackageName) { - installPackageAsUser(packageURI, observer, flags, installerPackageName, - mContext.getUserId()); - } - - @Override - public void installPackageAsUser(Uri packageURI, PackageInstallObserver observer, int flags, - String installerPackageName, int userId) { - final VerificationParams verificationParams = new VerificationParams(null, null, - null, VerificationParams.NO_UID); - installCommon(packageURI, observer, flags, installerPackageName, verificationParams, null, - userId); - } - - @Override - public void installPackageWithVerification(Uri packageURI, - PackageInstallObserver observer, int flags, String installerPackageName, - Uri verificationURI, - ContainerEncryptionParams encryptionParams) { - final VerificationParams verificationParams = new VerificationParams(verificationURI, null, - null, VerificationParams.NO_UID); - installCommon(packageURI, observer, flags, installerPackageName, verificationParams, - encryptionParams, mContext.getUserId()); - } - - @Override - public void installPackageWithVerificationAndEncryption(Uri packageURI, - PackageInstallObserver observer, int flags, String installerPackageName, - VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { - installCommon(packageURI, observer, flags, installerPackageName, verificationParams, - encryptionParams, mContext.getUserId()); + installCommon(packageURI, observer, flags, installerPackageName, mContext.getUserId()); } private void installCommon(Uri packageURI, PackageInstallObserver observer, int flags, String installerPackageName, - VerificationParams verificationParams, ContainerEncryptionParams encryptionParams, int userId) { if (!"file".equals(packageURI.getScheme())) { throw new UnsupportedOperationException("Only file:// URIs are supported"); } - if (encryptionParams != null) { - throw new UnsupportedOperationException("ContainerEncryptionParams not supported"); - } final String originPath = packageURI.getPath(); try { mPM.installPackageAsUser(originPath, observer.getBinder(), flags, installerPackageName, - verificationParams, null, userId); + userId); } catch (RemoteException ignored) { } } diff --git a/core/java/android/app/JobSchedulerImpl.java b/core/java/android/app/JobSchedulerImpl.java index dacf4ea997dc..b3a486f450bf 100644 --- a/core/java/android/app/JobSchedulerImpl.java +++ b/core/java/android/app/JobSchedulerImpl.java @@ -46,9 +46,9 @@ public class JobSchedulerImpl extends JobScheduler { } @Override - public int scheduleAsPackage(JobInfo job, String packageName, int userId) { + public int scheduleAsPackage(JobInfo job, String packageName, int userId, String tag) { try { - return mBinder.scheduleAsPackage(job, packageName, userId); + return mBinder.scheduleAsPackage(job, packageName, userId, tag); } catch (RemoteException e) { return JobScheduler.RESULT_FAILURE; } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index ba8f1f4e152c..27f098c597d5 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -2686,8 +2686,16 @@ public class DevicePolicyManager { } /** - * Called by a device or profile owner to install a certificate and private key pair. The - * keypair will be visible to all apps within the profile. + * Called by a device or profile owner, or delegated certificate installer, to install a + * certificate and corresponding private key. All apps within the profile will be able to access + * the certificate and use the private key, given direct user approval. + * + * <p>Access to the installed credentials will not be granted to the caller of this API without + * direct user approval. This is for security - should a certificate installer become + * compromised, certificates it had already installed will be protected. + * + * <p>If the installer must have access to the credentials, call + * {@link #installKeyPair(ComponentName, PrivateKey, Certificate, String, boolean)} instead. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if calling from a delegated certificate installer. @@ -2699,11 +2707,35 @@ public class DevicePolicyManager { */ public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey, @NonNull Certificate cert, @NonNull String alias) { + return installKeyPair(admin, privKey, cert, alias, false); + } + + /** + * Called by a device or profile owner, or delegated certificate installer, to install a + * certificate and corresponding private key. All apps within the profile will be able to access + * the certificate and use the private key, given direct user approval. + * + * <p>The caller of this API may grant itself access to the credential immediately, without user + * approval. It is a best practice not to request this unless strictly necessary since it opens + * up additional security vulnerabilities. + * + * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or + * {@code null} if calling from a delegated certificate installer. + * @param privKey The private key to install. + * @param cert The certificate to install. + * @param alias The private key alias under which to install the certificate. If a certificate + * with that alias already exists, it will be overwritten. + * @param requestAccess {@code true} to request that the calling app be granted access to the + * credentials immediately. Otherwise, access to the credentials will be gated by user approval. + * @return {@code true} if the keys were installed, {@code false} otherwise. + */ + public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey, + @NonNull Certificate cert, @NonNull String alias, boolean requestAccess) { try { final byte[] pemCert = Credentials.convertToPem(cert); final byte[] pkcs8Key = KeyFactory.getInstance(privKey.getAlgorithm()) .getKeySpec(privKey, PKCS8EncodedKeySpec.class).getEncoded(); - return mService.installKeyPair(admin, pkcs8Key, pemCert, alias); + return mService.installKeyPair(admin, pkcs8Key, pemCert, alias, requestAccess); } catch (RemoteException e) { Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { @@ -2715,8 +2747,8 @@ public class DevicePolicyManager { } /** - * Called by a device or profile owner to remove all user credentials installed under a given - * alias. + * Called by a device or profile owner, or delegated certificate installer, to remove all user + * credentials installed under a given alias. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if calling from a delegated certificate installer. diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index e78c0ac9714f..b7a16aa0dc07 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -145,7 +145,8 @@ interface IDevicePolicyManager { void uninstallCaCerts(in ComponentName admin, in String[] aliases); void enforceCanManageCaCerts(in ComponentName admin); - boolean installKeyPair(in ComponentName who, in byte[] privKeyBuffer, in byte[] certBuffer, String alias); + boolean installKeyPair(in ComponentName who, in byte[] privKeyBuffer, in byte[] certBuffer, + String alias, boolean requestAccess); boolean removeKeyPair(in ComponentName who, String alias); void choosePrivateKeyAlias(int uid, in Uri uri, in String alias, IBinder aliasCallback); diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java index 2268400ed573..7fcca0969f75 100644 --- a/core/java/android/app/backup/BackupManager.java +++ b/core/java/android/app/backup/BackupManager.java @@ -468,7 +468,7 @@ public class BackupManager { * * @param packages List of package names to backup. * @param observer The {@link BackupObserver} to receive callbacks during the backup - * operation. + * operation. Could be {@code null}. * @return {@link BackupManager#SUCCESS} on success; nonzero on error. * @exception IllegalArgumentException on null or empty {@code packages} param. * @@ -479,8 +479,9 @@ public class BackupManager { checkServiceBinder(); if (sService != null) { try { - BackupObserverWrapper observerWrapper = - new BackupObserverWrapper(mContext, observer); + BackupObserverWrapper observerWrapper = observer == null + ? null + : new BackupObserverWrapper(mContext, observer); return sService.requestBackup(packages, observerWrapper); } catch (RemoteException e) { Log.e(TAG, "requestBackup() couldn't connect"); diff --git a/core/java/android/app/job/IJobScheduler.aidl b/core/java/android/app/job/IJobScheduler.aidl index f0c33023292b..3379f2ec7c9c 100644 --- a/core/java/android/app/job/IJobScheduler.aidl +++ b/core/java/android/app/job/IJobScheduler.aidl @@ -24,7 +24,7 @@ import android.app.job.JobInfo; */ interface IJobScheduler { int schedule(in JobInfo job); - int scheduleAsPackage(in JobInfo job, String packageName, int userId); + int scheduleAsPackage(in JobInfo job, String packageName, int userId, String tag); void cancel(int jobId); void cancelAll(); List<JobInfo> getAllPendingJobs(); diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java index 5398e7f2dc95..4cbaf6cbf087 100644 --- a/core/java/android/app/job/JobInfo.java +++ b/core/java/android/app/job/JobInfo.java @@ -83,6 +83,31 @@ public class JobInfo implements Parcelable { */ public static final int DEFAULT_BACKOFF_POLICY = BACKOFF_POLICY_EXPONENTIAL; + /** + * Default of {@link #getPriority}. + * @hide + */ + public static final int PRIORITY_DEFAULT = 0; + + /** + * Value of {@link #getPriority} for expedited syncs. + * @hide + */ + public static final int PRIORITY_SYNC_EXPEDITED = 10; + + /** + * Value of {@link #getPriority} for first time initialization syncs. + * @hide + */ + public static final int PRIORITY_SYNC_INITIALIZATION = 20; + + /** + * Value of {@link #getPriority} for the current foreground app (overrides the supplied + * JobInfo priority if it is smaller). + * @hide + */ + public static final int PRIORITY_FOREGROUND_APP = 30; + private final int jobId; private final PersistableBundle extras; private final ComponentName service; @@ -406,7 +431,7 @@ public class JobInfo implements Parcelable { private int mJobId; private PersistableBundle mExtras = PersistableBundle.EMPTY; private ComponentName mJobService; - private int mPriority; + private int mPriority = PRIORITY_DEFAULT; // Requirements. private boolean mRequiresCharging; private boolean mRequiresDeviceIdle; diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java index 5e1a425606f3..d1e563f90f2d 100644 --- a/core/java/android/app/job/JobScheduler.java +++ b/core/java/android/app/job/JobScheduler.java @@ -68,10 +68,11 @@ public abstract class JobScheduler { * @param packageName The package on behalf of which the job is to be scheduled. This will be * used to track battery usage and appIdleState. * @param userId User on behalf of whom this job is to be scheduled. + * @param tag Debugging tag for dumps associated with this job (instead of the service class) * @return {@link #RESULT_SUCCESS} or {@link #RESULT_FAILURE} * @hide */ - public abstract int scheduleAsPackage(JobInfo job, String packageName, int userId); + public abstract int scheduleAsPackage(JobInfo job, String packageName, int userId, String tag); /** * Cancel a job that is pending in the JobScheduler. diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl index a9328bce0612..342c2858ab0f 100644 --- a/core/java/android/app/usage/IUsageStatsManager.aidl +++ b/core/java/android/app/usage/IUsageStatsManager.aidl @@ -33,4 +33,5 @@ interface IUsageStatsManager { void setAppInactive(String packageName, boolean inactive, int userId); boolean isAppInactive(String packageName, int userId); void whitelistAppTemporarily(String packageName, long duration, int userId); + void onCarrierPrivilegedAppsChanged(); } diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index c74b0f2d8e43..2aeecfabd48c 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -267,4 +267,15 @@ public final class UsageStatsManager { } catch (RemoteException re) { } } + + /** + * Inform usage stats that the carrier privileged apps access rules have changed. + * @hide + */ + public void onCarrierPrivilegedAppsChanged() { + try { + mService.onCarrierPrivilegedAppsChanged(); + } catch (RemoteException re) { + } + } } diff --git a/core/java/android/content/pm/ContainerEncryptionParams.java b/core/java/android/content/pm/ContainerEncryptionParams.java deleted file mode 100644 index ab3aa27cfeb6..000000000000 --- a/core/java/android/content/pm/ContainerEncryptionParams.java +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.content.pm; - -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; -import android.util.Slog; - -import java.security.InvalidAlgorithmParameterException; -import java.security.spec.AlgorithmParameterSpec; -import java.util.Arrays; - -import javax.crypto.SecretKey; -import javax.crypto.spec.IvParameterSpec; - -/** - * Represents encryption parameters used to read a container. - * - * @deprecated encrypted containers are legacy. - * @hide - */ -@SystemApi -@Deprecated -public class ContainerEncryptionParams implements Parcelable { - protected static final String TAG = "ContainerEncryptionParams"; - - /** What we print out first when toString() is called. */ - private static final String TO_STRING_PREFIX = "ContainerEncryptionParams{"; - - /** - * Parameter type for parceling that indicates the next parameters are - * IvParameters. - */ - private static final int ENC_PARAMS_IV_PARAMETERS = 1; - - /** Parameter type for paceling that indicates there are no MAC parameters. */ - private static final int MAC_PARAMS_NONE = 1; - - /** The encryption algorithm used. */ - private final String mEncryptionAlgorithm; - - /** The parameter spec to be used for encryption. */ - private final IvParameterSpec mEncryptionSpec; - - /** Secret key to be used for decryption. */ - private final SecretKey mEncryptionKey; - - /** Algorithm name for the MAC to be used. */ - private final String mMacAlgorithm; - - /** The parameter spec to be used for the MAC tag authentication. */ - private final AlgorithmParameterSpec mMacSpec; - - /** Secret key to be used for MAC tag authentication. */ - private final SecretKey mMacKey; - - /** MAC tag authenticating the data in the container. */ - private final byte[] mMacTag; - - /** Offset into file where authenticated (e.g., MAC protected) data begins. */ - private final long mAuthenticatedDataStart; - - /** Offset into file where encrypted data begins. */ - private final long mEncryptedDataStart; - - /** - * Offset into file for the end of encrypted data (and, by extension, - * authenticated data) in file. - */ - private final long mDataEnd; - - public ContainerEncryptionParams(String encryptionAlgorithm, - AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey) - throws InvalidAlgorithmParameterException { - this(encryptionAlgorithm, encryptionSpec, encryptionKey, null, null, null, null, -1, -1, - -1); - } - - /** - * Creates container encryption specifications for installing from encrypted - * containers. - * - * @param encryptionAlgorithm encryption algorithm to use; format matches - * JCE - * @param encryptionSpec algorithm parameter specification - * @param encryptionKey key used for decryption - * @param macAlgorithm MAC algorithm to use; format matches JCE - * @param macSpec algorithm parameters specification, may be {@code null} - * @param macKey key used for authentication (i.e., for the MAC tag) - * @param macTag message authentication code (MAC) tag for the authenticated - * data - * @param authenticatedDataStart offset of start of authenticated data in - * stream - * @param encryptedDataStart offset of start of encrypted data in stream - * @param dataEnd offset of the end of both the authenticated and encrypted - * data - * @throws InvalidAlgorithmParameterException - */ - public ContainerEncryptionParams(String encryptionAlgorithm, - AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey, String macAlgorithm, - AlgorithmParameterSpec macSpec, SecretKey macKey, byte[] macTag, - long authenticatedDataStart, long encryptedDataStart, long dataEnd) - throws InvalidAlgorithmParameterException { - if (TextUtils.isEmpty(encryptionAlgorithm)) { - throw new NullPointerException("algorithm == null"); - } else if (encryptionSpec == null) { - throw new NullPointerException("encryptionSpec == null"); - } else if (encryptionKey == null) { - throw new NullPointerException("encryptionKey == null"); - } - - if (!TextUtils.isEmpty(macAlgorithm)) { - if (macKey == null) { - throw new NullPointerException("macKey == null"); - } - } - - if (!(encryptionSpec instanceof IvParameterSpec)) { - throw new InvalidAlgorithmParameterException( - "Unknown parameter spec class; must be IvParameters"); - } - - mEncryptionAlgorithm = encryptionAlgorithm; - mEncryptionSpec = (IvParameterSpec) encryptionSpec; - mEncryptionKey = encryptionKey; - - mMacAlgorithm = macAlgorithm; - mMacSpec = macSpec; - mMacKey = macKey; - mMacTag = macTag; - - mAuthenticatedDataStart = authenticatedDataStart; - mEncryptedDataStart = encryptedDataStart; - mDataEnd = dataEnd; - } - - public String getEncryptionAlgorithm() { - return mEncryptionAlgorithm; - } - - public AlgorithmParameterSpec getEncryptionSpec() { - return mEncryptionSpec; - } - - public SecretKey getEncryptionKey() { - return mEncryptionKey; - } - - public String getMacAlgorithm() { - return mMacAlgorithm; - } - - public AlgorithmParameterSpec getMacSpec() { - return mMacSpec; - } - - public SecretKey getMacKey() { - return mMacKey; - } - - public byte[] getMacTag() { - return mMacTag; - } - - public long getAuthenticatedDataStart() { - return mAuthenticatedDataStart; - } - - public long getEncryptedDataStart() { - return mEncryptedDataStart; - } - - public long getDataEnd() { - return mDataEnd; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof ContainerEncryptionParams)) { - return false; - } - - final ContainerEncryptionParams other = (ContainerEncryptionParams) o; - - // Primitive comparison - if ((mAuthenticatedDataStart != other.mAuthenticatedDataStart) - || (mEncryptedDataStart != other.mEncryptedDataStart) - || (mDataEnd != other.mDataEnd)) { - return false; - } - - // String comparison - if (!mEncryptionAlgorithm.equals(other.mEncryptionAlgorithm) - || !mMacAlgorithm.equals(other.mMacAlgorithm)) { - return false; - } - - // Object comparison - if (!isSecretKeyEqual(mEncryptionKey, other.mEncryptionKey) - || !isSecretKeyEqual(mMacKey, other.mMacKey)) { - return false; - } - - if (!Arrays.equals(mEncryptionSpec.getIV(), other.mEncryptionSpec.getIV()) - || !Arrays.equals(mMacTag, other.mMacTag) || (mMacSpec != other.mMacSpec)) { - return false; - } - - return true; - } - - private static final boolean isSecretKeyEqual(SecretKey key1, SecretKey key2) { - final String keyFormat = key1.getFormat(); - final String otherKeyFormat = key2.getFormat(); - - if (keyFormat == null) { - if (keyFormat != otherKeyFormat) { - return false; - } - - if (key1.getEncoded() != key2.getEncoded()) { - return false; - } - } else { - if (!keyFormat.equals(key2.getFormat())) { - return false; - } - - if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) { - return false; - } - } - - return true; - } - - @Override - public int hashCode() { - int hash = 3; - - hash += 5 * mEncryptionAlgorithm.hashCode(); - hash += 7 * Arrays.hashCode(mEncryptionSpec.getIV()); - hash += 11 * mEncryptionKey.hashCode(); - hash += 13 * mMacAlgorithm.hashCode(); - hash += 17 * mMacKey.hashCode(); - hash += 19 * Arrays.hashCode(mMacTag); - hash += 23 * mAuthenticatedDataStart; - hash += 29 * mEncryptedDataStart; - hash += 31 * mDataEnd; - - return hash; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(TO_STRING_PREFIX); - - sb.append("mEncryptionAlgorithm=\""); - sb.append(mEncryptionAlgorithm); - sb.append("\","); - sb.append("mEncryptionSpec="); - sb.append(mEncryptionSpec.toString()); - sb.append("mEncryptionKey="); - sb.append(mEncryptionKey.toString()); - - sb.append("mMacAlgorithm=\""); - sb.append(mMacAlgorithm); - sb.append("\","); - sb.append("mMacSpec="); - sb.append(mMacSpec.toString()); - sb.append("mMacKey="); - sb.append(mMacKey.toString()); - - sb.append(",mAuthenticatedDataStart="); - sb.append(mAuthenticatedDataStart); - sb.append(",mEncryptedDataStart="); - sb.append(mEncryptedDataStart); - sb.append(",mDataEnd="); - sb.append(mDataEnd); - sb.append('}'); - - return sb.toString(); - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mEncryptionAlgorithm); - dest.writeInt(ENC_PARAMS_IV_PARAMETERS); - dest.writeByteArray(mEncryptionSpec.getIV()); - dest.writeSerializable(mEncryptionKey); - - dest.writeString(mMacAlgorithm); - dest.writeInt(MAC_PARAMS_NONE); - dest.writeByteArray(new byte[0]); - dest.writeSerializable(mMacKey); - - dest.writeByteArray(mMacTag); - - dest.writeLong(mAuthenticatedDataStart); - dest.writeLong(mEncryptedDataStart); - dest.writeLong(mDataEnd); - } - - private ContainerEncryptionParams(Parcel source) throws InvalidAlgorithmParameterException { - mEncryptionAlgorithm = source.readString(); - final int encParamType = source.readInt(); - final byte[] encParamsEncoded = source.createByteArray(); - mEncryptionKey = (SecretKey) source.readSerializable(); - - mMacAlgorithm = source.readString(); - final int macParamType = source.readInt(); - source.createByteArray(); // byte[] macParamsEncoded - mMacKey = (SecretKey) source.readSerializable(); - - mMacTag = source.createByteArray(); - - mAuthenticatedDataStart = source.readLong(); - mEncryptedDataStart = source.readLong(); - mDataEnd = source.readLong(); - - switch (encParamType) { - case ENC_PARAMS_IV_PARAMETERS: - mEncryptionSpec = new IvParameterSpec(encParamsEncoded); - break; - default: - throw new InvalidAlgorithmParameterException("Unknown parameter type " - + encParamType); - } - - switch (macParamType) { - case MAC_PARAMS_NONE: - mMacSpec = null; - break; - default: - throw new InvalidAlgorithmParameterException("Unknown parameter type " - + macParamType); - } - - if (mEncryptionKey == null) { - throw new NullPointerException("encryptionKey == null"); - } - } - - public static final Parcelable.Creator<ContainerEncryptionParams> CREATOR = - new Parcelable.Creator<ContainerEncryptionParams>() { - public ContainerEncryptionParams createFromParcel(Parcel source) { - try { - return new ContainerEncryptionParams(source); - } catch (InvalidAlgorithmParameterException e) { - Slog.e(TAG, "Invalid algorithm parameters specified", e); - return null; - } - } - - public ContainerEncryptionParams[] newArray(int size) { - return new ContainerEncryptionParams[size]; - } - }; -}
\ No newline at end of file diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index d6b674c0edee..9959f2749609 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -46,7 +46,6 @@ import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; -import android.content.pm.VerificationParams; import android.content.pm.VerifierDeviceIdentity; import android.graphics.Bitmap; import android.net.Uri; @@ -214,19 +213,11 @@ interface IPackageManager { List<InstrumentationInfo> queryInstrumentation( String targetPackage, int flags); - void installPackage(in String originPath, - in IPackageInstallObserver2 observer, - int flags, - in String installerPackageName, - in VerificationParams verificationParams, - in String packageAbiOverride); - + /** @deprecated Use PackageInstaller instead */ void installPackageAsUser(in String originPath, in IPackageInstallObserver2 observer, int flags, in String installerPackageName, - in VerificationParams verificationParams, - in String packageAbiOverride, int userId); void finishPackageInstall(int token); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index b7f968c47079..588a89df411e 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -4597,60 +4597,20 @@ public abstract class PackageManager { */ @Deprecated public abstract void installPackage( - Uri packageURI, IPackageInstallObserver observer, @InstallFlags int flags, + Uri packageURI, + IPackageInstallObserver observer, + @InstallFlags int flags, String installerPackageName); - /** * @deprecated replaced by {@link PackageInstaller} * @hide */ @Deprecated - public abstract void installPackageWithVerification(Uri packageURI, - IPackageInstallObserver observer, @InstallFlags int flags, String installerPackageName, - Uri verificationURI, ContainerEncryptionParams encryptionParams); - - /** - * @deprecated replaced by {@link PackageInstaller} - * @hide - */ - @Deprecated - public abstract void installPackageWithVerificationAndEncryption(Uri packageURI, - IPackageInstallObserver observer, @InstallFlags int flags, String installerPackageName, - VerificationParams verificationParams, ContainerEncryptionParams encryptionParams); - - /** - * @deprecated replaced by {@link PackageInstaller} - * @hide - */ - @Deprecated - public abstract void installPackage(Uri packageURI, PackageInstallObserver observer, - @InstallFlags int flags, String installerPackageName); - - /** - * @deprecated replaced by {@link PackageInstaller} - * @hide - */ - @Deprecated - public abstract void installPackageAsUser(Uri packageURI, PackageInstallObserver observer, - @InstallFlags int flags, String installerPackageName, @UserIdInt int userId); - - /** - * @deprecated replaced by {@link PackageInstaller} - * @hide - */ - @Deprecated - public abstract void installPackageWithVerification(Uri packageURI, - PackageInstallObserver observer, @InstallFlags int flags, String installerPackageName, - Uri verificationURI, ContainerEncryptionParams encryptionParams); - - /** - * @deprecated replaced by {@link PackageInstaller} - * @hide - */ - @Deprecated - public abstract void installPackageWithVerificationAndEncryption(Uri packageURI, - PackageInstallObserver observer, @InstallFlags int flags, String installerPackageName, - VerificationParams verificationParams, ContainerEncryptionParams encryptionParams); + public abstract void installPackage( + Uri packageURI, + PackageInstallObserver observer, + @InstallFlags int flags, + String installerPackageName); /** * If there is already an application with the given package name installed diff --git a/core/java/android/content/pm/VerificationParams.aidl b/core/java/android/content/pm/VerificationParams.aidl deleted file mode 100644 index 5bb7f6962fe8..000000000000 --- a/core/java/android/content/pm/VerificationParams.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2012, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.content.pm; - -parcelable VerificationParams; diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index 5d64af577cba..d41bc070d6c1 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -1494,11 +1494,9 @@ public class Preference implements Comparable<Preference> { * @return True if the Preference is persistent. (This is not whether the * value was persisted, since we may not necessarily commit if there * will be a batch commit later.) - * @see #getPersistedString(Set) - * - * @hide Pending API approval + * @see #getPersistedStringSet(Set) */ - protected boolean persistStringSet(Set<String> values) { + public boolean persistStringSet(Set<String> values) { if (shouldPersist()) { // Shouldn't store null if (values.equals(getPersistedStringSet(null))) { @@ -1527,10 +1525,8 @@ public class Preference implements Comparable<Preference> { * @return The value from the SharedPreferences or the default return * value. * @see #persistStringSet(Set) - * - * @hide Pending API approval */ - protected Set<String> getPersistedStringSet(Set<String> defaultReturnValue) { + public Set<String> getPersistedStringSet(Set<String> defaultReturnValue) { if (!shouldPersist()) { return defaultReturnValue; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 921e18f18dff..f524be37bff5 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7048,6 +7048,14 @@ public final class Settings { "webview_data_reduction_proxy_key"; /** + * Whether or not the WebView fallback mechanism should be enabled. + * 0=disabled, 1=enabled. + * @hide + */ + public static final String WEBVIEW_FALLBACK_LOGIC_ENABLED = + "webview_fallback_logic_enabled"; + + /** * Name of the package used as WebView provider (if unset the provider is instead determined * by the system). * @hide diff --git a/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl b/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl index 52db22397b65..626b40827334 100644 --- a/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl +++ b/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl @@ -35,4 +35,6 @@ interface IPersistentDataBlockService { void setOemUnlockEnabled(boolean enabled); boolean getOemUnlockEnabled(); + int getFlashLockState(); } + diff --git a/core/java/android/service/persistentdata/PersistentDataBlockManager.java b/core/java/android/service/persistentdata/PersistentDataBlockManager.java index 0ffdf68c4b30..ddb6980046ed 100644 --- a/core/java/android/service/persistentdata/PersistentDataBlockManager.java +++ b/core/java/android/service/persistentdata/PersistentDataBlockManager.java @@ -17,9 +17,13 @@ package android.service.persistentdata; import android.annotation.SystemApi; +import android.annotation.IntDef; import android.os.RemoteException; import android.util.Slog; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * Interface for reading and writing data blocks to a persistent partition. * @@ -43,6 +47,27 @@ public class PersistentDataBlockManager { private static final String TAG = PersistentDataBlockManager.class.getSimpleName(); private IPersistentDataBlockService sService; + /** + * Indicates that the device's bootloader lock state is UNKNOWN. + */ + public static final int FLASH_LOCK_UNKNOWN = -1; + /** + * Indicates that the device's bootloader is UNLOCKED. + */ + public static final int FLASH_LOCK_UNLOCKED = 0; + /** + * Indicates that the device's bootloader is LOCKED. + */ + public static final int FLASH_LOCK_LOCKED = 1; + + @IntDef({ + FLASH_LOCK_UNKNOWN, + FLASH_LOCK_LOCKED, + FLASH_LOCK_UNLOCKED, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface FlashLockState {} + public PersistentDataBlockManager(IPersistentDataBlockService service) { sService = service; } @@ -140,6 +165,24 @@ public class PersistentDataBlockManager { } } + /** + * Retrieves available information about this device's flash lock state. + * + * @return FLASH_LOCK_STATE_LOCKED if device bootloader is locked, + * FLASH_LOCK_STATE_UNLOCKED if device bootloader is unlocked, + * or FLASH_LOCK_STATE unknown if this information cannot be ascertained + * on this device. + */ + @FlashLockState + public int getFlashLockState() { + try { + return sService.getFlashLockState(); + } catch (RemoteException e) { + onError("getting flash lock state"); + return FLASH_LOCK_UNKNOWN; + } + } + private void onError(String msg) { Slog.v(TAG, "Remote exception while " + msg); } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index a98551752181..de8133b33aa6 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -271,7 +271,8 @@ public abstract class WallpaperService extends Service { @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropRect, boolean forceLayout) { + Configuration newConfig, Rect backDropRect, boolean forceLayout, + boolean alwaysConsumeNavBar) { Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED, reportDraw ? 1 : 0, outsets); mCaller.sendMessage(msg); @@ -790,7 +791,7 @@ public abstract class WallpaperService extends Service { mFinalStableInsets.set(mDispatchedStableInsets); WindowInsets insets = new WindowInsets(mFinalSystemInsets, null, mFinalStableInsets, - getResources().getConfiguration().isScreenRound()); + getResources().getConfiguration().isScreenRound(), false); if (DEBUG) { Log.v(TAG, "dispatching insets=" + insets); } diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index 3688d50d9fe3..70d0513bfbc5 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -49,7 +49,8 @@ oneway interface IWindow { void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets, in Rect visibleInsets, in Rect stableInsets, in Rect outsets, boolean reportDraw, - in Configuration newConfig, in Rect backDropFrame, boolean forceLayout); + in Configuration newConfig, in Rect backDropFrame, boolean forceLayout, + boolean alwaysConsumeNavBar); void moved(int newX, int newY); void dispatchAppVisibility(boolean visible); void dispatchGetNewSurface(); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 152dd66ec7be..2c9d691214b0 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -743,7 +743,8 @@ public class SurfaceView extends View { @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropRect, boolean forceLayout) { + Configuration newConfig, Rect backDropRect, boolean forceLayout, + boolean alwaysConsumeNavBar) { SurfaceView surfaceView = mSurfaceView.get(); if (surfaceView != null) { if (DEBUG) Log.v( diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 70a0e014014a..26f3b39cf2f4 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -22517,6 +22517,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final Rect mOutsets = new Rect(); /** + * In multi-window we force show the navigation bar. Because we don't want that the surface + * size changes in this mode, we instead have a flag whether the navigation bar size should + * always be consumed, so the app is treated like there is no virtual navigation bar at all. + */ + boolean mAlwaysConsumeNavBar; + + /** * The internal insets given by this window. This value is * supplied by the client (through * {@link ViewTreeObserver.OnComputeInternalInsetsListener}) and will diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 2e10bec93874..af0fd51c3ff4 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -313,6 +313,7 @@ public final class ViewRootImpl implements ViewParent, final Rect mPendingContentInsets = new Rect(); final Rect mPendingOutsets = new Rect(); final Rect mPendingBackDropFrame = new Rect(); + boolean mPendingAlwaysConsumeNavBar; final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets = new ViewTreeObserver.InternalInsetsInfo(); @@ -623,6 +624,9 @@ public final class ViewRootImpl implements ViewParent, mPendingContentInsets.set(mAttachInfo.mContentInsets); mPendingStableInsets.set(mAttachInfo.mStableInsets); mPendingVisibleInsets.set(0, 0, 0, 0); + mAttachInfo.mAlwaysConsumeNavBar = + (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR) != 0; + mPendingAlwaysConsumeNavBar = mAttachInfo.mAlwaysConsumeNavBar; if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow); if (res < WindowManagerGlobal.ADD_OKAY) { mAttachInfo.mRootView = null; @@ -1345,7 +1349,8 @@ public final class ViewRootImpl implements ViewParent, } mLastWindowInsets = new WindowInsets(contentInsets, null /* windowDecorInsets */, stableInsets, - mContext.getResources().getConfiguration().isScreenRound()); + mContext.getResources().getConfiguration().isScreenRound(), + mAttachInfo.mAlwaysConsumeNavBar); } return mLastWindowInsets; } @@ -1512,6 +1517,9 @@ public final class ViewRootImpl implements ViewParent, if (!mPendingOutsets.equals(mAttachInfo.mOutsets)) { insetsChanged = true; } + if (mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar) { + insetsChanged = true; + } if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) { windowSizeMayChange = true; @@ -1696,6 +1704,8 @@ public final class ViewRootImpl implements ViewParent, final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets); final boolean surfaceSizeChanged = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0; + final boolean alwaysConsumeNavBarChanged = + mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar; if (contentInsetsChanged) { mAttachInfo.mContentInsets.set(mPendingContentInsets); if (DEBUG_LAYOUT) Log.v(mTag, "Content insets changing to: " @@ -1715,6 +1725,10 @@ public final class ViewRootImpl implements ViewParent, // Need to relayout with content insets. contentInsetsChanged = true; } + if (alwaysConsumeNavBarChanged) { + mAttachInfo.mAlwaysConsumeNavBar = mPendingAlwaysConsumeNavBar; + contentInsetsChanged = true; + } if (contentInsetsChanged || mLastSystemUiVisibility != mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested || mLastOverscanRequested != mAttachInfo.mOverscanRequested @@ -3391,6 +3405,7 @@ public final class ViewRootImpl implements ViewParent, mPendingOutsets.set((Rect) args.arg7); mPendingBackDropFrame.set((Rect) args.arg8); mForceNextWindowRelayout = args.argi1 != 0; + mPendingAlwaysConsumeNavBar = args.argi2 != 0; args.recycle(); @@ -5570,6 +5585,10 @@ public final class ViewRootImpl implements ViewParent, mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets, mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingConfiguration, mSurface); + + mPendingAlwaysConsumeNavBar = + (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0; + //Log.d(mTag, "<<<<<< BACK FROM relayout"); if (restore) { params.restore(); @@ -5841,7 +5860,8 @@ public final class ViewRootImpl implements ViewParent, public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropFrame, boolean forceLayout) { + Configuration newConfig, Rect backDropFrame, boolean forceLayout, + boolean alwaysConsumeNavBar) { if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString() + " contentInsets=" + contentInsets.toShortString() + " visibleInsets=" + visibleInsets.toShortString() @@ -5878,6 +5898,7 @@ public final class ViewRootImpl implements ViewParent, args.arg7 = sameProcessCall ? new Rect(outsets) : outsets; args.arg8 = sameProcessCall ? new Rect(backDropFrame) : backDropFrame; args.argi1 = forceLayout ? 1 : 0; + args.argi2 = alwaysConsumeNavBar ? 1 : 0; msg.obj = args; mHandler.sendMessage(msg); } @@ -6879,12 +6900,13 @@ public final class ViewRootImpl implements ViewParent, @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropFrame, boolean forceLayout) { + Configuration newConfig, Rect backDropFrame, boolean forceLayout, + boolean alwaysConsumeNavBar) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets, reportDraw, newConfig, backDropFrame, - forceLayout); + forceLayout, alwaysConsumeNavBar); } } diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index 997e7e8a16f0..929fdac82c28 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -37,6 +37,13 @@ public final class WindowInsets { private Rect mTempRect; private boolean mIsRound; + /** + * In multi-window we force show the navigation bar. Because we don't want that the surface size + * changes in this mode, we instead have a flag whether the navigation bar size should always + * be consumed, so the app is treated like there is no virtual navigation bar at all. + */ + private boolean mAlwaysConsumeNavBar; + private boolean mSystemWindowInsetsConsumed = false; private boolean mWindowDecorInsetsConsumed = false; private boolean mStableInsetsConsumed = false; @@ -52,12 +59,12 @@ public final class WindowInsets { public static final WindowInsets CONSUMED; static { - CONSUMED = new WindowInsets(null, null, null, false); + CONSUMED = new WindowInsets(null, null, null, false, false); } /** @hide */ public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, Rect stableInsets, - boolean isRound) { + boolean isRound, boolean alwaysConsumeNavBar) { mSystemWindowInsetsConsumed = systemWindowInsets == null; mSystemWindowInsets = mSystemWindowInsetsConsumed ? EMPTY_RECT : systemWindowInsets; @@ -68,6 +75,7 @@ public final class WindowInsets { mStableInsets = mStableInsetsConsumed ? EMPTY_RECT : stableInsets; mIsRound = isRound; + mAlwaysConsumeNavBar = alwaysConsumeNavBar; } /** @@ -87,7 +95,7 @@ public final class WindowInsets { /** @hide */ public WindowInsets(Rect systemWindowInsets) { - this(systemWindowInsets, null, null, false); + this(systemWindowInsets, null, null, false, false); } /** @@ -475,6 +483,13 @@ public final class WindowInsets { return result; } + /** + * @hide + */ + public boolean shouldAlwaysConsumeNavBar() { + return mAlwaysConsumeNavBar; + } + @Override public String toString() { return "WindowInsets{systemWindowInsets=" + mSystemWindowInsets diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 1530b474c534..a1cbc1d07575 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -90,6 +90,13 @@ public final class WindowManagerGlobal { public static final int RELAYOUT_RES_SURFACE_RESIZED = 0x20; /** + * In multi-window we force show the navigation bar. Because we don't want that the surface size + * changes in this mode, we instead have a flag whether the navigation bar size should always be + * consumed, so the app is treated like there is no virtual navigation bar at all. + */ + public static final int RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR = 0x40; + + /** * Flag for relayout: the client will be later giving * internal insets; as a result, the window will not impact other window * layouts until the insets are given. @@ -107,6 +114,11 @@ public final class WindowManagerGlobal { public static final int ADD_FLAG_APP_VISIBLE = 0x2; public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_RES_IN_TOUCH_MODE; + /** + * Like {@link #RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR}, but as a "hint" when adding the window. + */ + public static final int ADD_FLAG_ALWAYS_CONSUME_NAV_BAR = 0x4; + public static final int ADD_OKAY = 0; public static final int ADD_BAD_APP_TOKEN = -1; public static final int ADD_BAD_SUBWINDOW_TOKEN = -2; diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index e36077b5364f..2fbfd2d13b40 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -920,9 +920,10 @@ public interface WindowManagerPolicy { * @param outStableInsets The areas covered by stable system windows irrespective of their * current visibility. Expressed as positive insets. * @param outOutsets The areas that are not real display, but we would like to treat as such. - * + * @return Whether to always consume the navigation bar. + * See {@link #isNavBarForcedShownLw(WindowState)}. */ - public void getInsetHintLw(WindowManager.LayoutParams attrs, int rotation, + public boolean getInsetHintLw(WindowManager.LayoutParams attrs, int rotation, Rect outContentInsets, Rect outStableInsets, Rect outOutsets); /** @@ -1351,6 +1352,12 @@ public interface WindowManagerPolicy { public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight, Rect outInsets); + + /** + * @return true if the navigation bar is forced to stay visible + */ + public boolean isNavBarForcedShownLw(WindowState win); + /** * Calculates the insets for the areas that could never be removed in Honeycomb, i.e. system * bar or button bar. See {@link #getNonDecorDisplayWidth}. diff --git a/core/java/android/webkit/IWebViewUpdateService.aidl b/core/java/android/webkit/IWebViewUpdateService.aidl index 89d5d69de392..5697dfc0188c 100644 --- a/core/java/android/webkit/IWebViewUpdateService.aidl +++ b/core/java/android/webkit/IWebViewUpdateService.aidl @@ -38,10 +38,14 @@ interface IWebViewUpdateService { WebViewProviderResponse waitForAndGetProvider(); /** - * DevelopmentSettings uses this to notify WebViewUpdateService that a - * new provider has been selected by the user. + * DevelopmentSettings uses this to notify WebViewUpdateService that a new provider has been + * selected by the user. Returns the provider we end up switching to, this could be different to + * the one passed as argument to this method since the Dev Setting calling this method could be + * stale. I.e. the Dev setting could be letting the user choose uninstalled/disabled packages, + * it would then try to update the provider to such a package while in reality the update + * service would switch to another one. */ - void changeProviderAndSetting(String newProvider); + String changeProviderAndSetting(String newProvider); /** * DevelopmentSettings uses this to get the current available WebView @@ -53,4 +57,15 @@ interface IWebViewUpdateService { * Used by DevelopmentSetting to get the name of the WebView provider currently in use. */ String getCurrentWebViewPackageName(); + + /** + * Used by Settings to determine whether a certain package can be enabled/disabled by the user - + * the package should not be modifiable in this way if it is a fallback package. + */ + boolean isFallbackPackage(String packageName); + + /** + * Enable or disable the WebView package fallback mechanism. + */ + void enableFallbackLogic(boolean enable); } diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 647d4dcbc347..2eb258fb6683 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -288,11 +288,11 @@ import java.util.Map; * helps Google improve WebView. Data is collected on a per-app basis for each app which has * instantiated a WebView. An individual app can opt out of this feature by putting the following * tag in its manifest: - * </p> * <pre> - * <meta-data android:name="android.webkit.WebView.MetricsOptOut" - * android:value="true" /> + * <meta-data android:name="android.webkit.WebView.MetricsOptOut" + * android:value="true" /> * </pre> + * </p> * <p> * Data will only be uploaded for a given app if the user has consented AND the app has not opted * out. diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index b04b4c0e3b11..ad50ff60780e 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -21,6 +21,7 @@ import android.app.ActivityManagerInternal; import android.app.AppGlobals; import android.app.Application; import android.content.Context; +import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -134,6 +135,7 @@ public final class WebViewFactory { // Whether or not the provider must be explicitly chosen by the user to be used. private static String TAG_AVAILABILITY = "availableByDefault"; private static String TAG_SIGNATURE = "signature"; + private static String TAG_FALLBACK = "isFallback"; /** * Reads all signatures at the current depth (within the current provider) from the XML parser. @@ -159,6 +161,7 @@ public final class WebViewFactory { * @hide * */ public static WebViewProviderInfo[] getWebViewPackages() { + int numFallbackPackages = 0; XmlResourceParser parser = null; List<WebViewProviderInfo> webViewProviders = new ArrayList<WebViewProviderInfo>(); try { @@ -182,13 +185,21 @@ public final class WebViewFactory { throw new MissingWebViewPackageException( "WebView provider in framework resources missing description"); } - String availableByDefault = parser.getAttributeValue(null, TAG_AVAILABILITY); - if (availableByDefault == null) { - availableByDefault = "false"; - } - webViewProviders.add( + boolean availableByDefault = "true".equals( + parser.getAttributeValue(null, TAG_AVAILABILITY)); + boolean isFallback = "true".equals( + parser.getAttributeValue(null, TAG_FALLBACK)); + WebViewProviderInfo currentProvider = new WebViewProviderInfo(packageName, description, availableByDefault, - readSignatures(parser))); + isFallback, readSignatures(parser)); + if (currentProvider.isFallbackPackage()) { + numFallbackPackages++; + if (numFallbackPackages > 1) { + throw new AndroidRuntimeException( + "There can be at most one webview fallback package."); + } + } + webViewProviders.add(currentProvider); } else { Log.e(LOGTAG, "Found an element that is not a webview provider"); @@ -641,6 +652,18 @@ public final class WebViewFactory { return result; } + /** + * Returns whether the entire package from an ACTION_PACKAGE_CHANGED intent was changed (rather + * than just one of its components). + * @hide + */ + public static boolean entirePackageChanged(Intent intent) { + String[] componentList = + intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST); + return Arrays.asList(componentList).contains( + intent.getDataString().substring("package:".length())); + } + private static IWebViewUpdateService getUpdateService() { return IWebViewUpdateService.Stub.asInterface(ServiceManager.getService("webviewupdate")); } diff --git a/core/java/android/webkit/WebViewProviderInfo.java b/core/java/android/webkit/WebViewProviderInfo.java index 94e8b70ce38c..64c2caa58fd5 100644 --- a/core/java/android/webkit/WebViewProviderInfo.java +++ b/core/java/android/webkit/WebViewProviderInfo.java @@ -40,11 +40,12 @@ public class WebViewProviderInfo implements Parcelable { public WebViewPackageNotFoundException(Exception e) { super(e); } } - public WebViewProviderInfo(String packageName, String description, String availableByDefault, - String[] signatures) { + public WebViewProviderInfo(String packageName, String description, boolean availableByDefault, + boolean isFallback, String[] signatures) { this.packageName = packageName; this.description = description; - this.availableByDefault = availableByDefault.equals("true"); + this.availableByDefault = availableByDefault; + this.isFallback = isFallback; this.signatures = signatures; } @@ -114,6 +115,10 @@ public class WebViewProviderInfo implements Parcelable { return availableByDefault; } + public boolean isFallbackPackage() { + return isFallback; + } + private void updatePackageInfo() { try { PackageManager pm = AppGlobals.getInitialApplication().getPackageManager(); @@ -165,6 +170,7 @@ public class WebViewProviderInfo implements Parcelable { public String packageName; public String description; private boolean availableByDefault; + private boolean isFallback; private String[] signatures; diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 4ed175d80160..914ffdf8b1e9 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -1973,13 +1973,13 @@ public class RemoteViews implements Parcelable, Filter { public SetRemoteInputsAction(Parcel parcel) { viewId = parcel.readInt(); - remoteInputs = parcel.readParcelableArray(RemoteInput.class.getClassLoader()); + remoteInputs = parcel.createTypedArray(RemoteInput.CREATOR); } public void writeToParcel(Parcel dest, int flags) { dest.writeInt(TAG); dest.writeInt(viewId); - dest.writeParcelableArray(remoteInputs, flags); + dest.writeTypedArray(remoteInputs, flags); } @Override diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index 48328814abbd..6879df3a214a 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -1002,7 +1002,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind boolean consumingNavBar = (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0 - && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0; + && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0 + || (insets != null && insets.shouldAlwaysConsumeNavBar()); // If we didn't request fullscreen layout, but we still got it because of the // mForceWindowDrawsStatusBarBackground flag, also consume top inset. diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index bcc310f7a9fa..ab918c832c0c 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -38,7 +38,7 @@ public class BaseIWindow extends IWindow.Stub { @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig, - Rect backDropFrame, boolean forceLayout) { + Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar) { if (reportDraw) { try { mSession.finishDrawing(this); diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 80f8a64122e3..7d9e4a284cec 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -388,18 +388,43 @@ android_media_AudioSystem_dyn_policy_callback(int event, String8 regId, int val) } static void -android_media_AudioSystem_recording_callback(int event, int session, int source) +android_media_AudioSystem_recording_callback(int event, int session, int source, + const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig) { JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { return; } + if (clientConfig == NULL || deviceConfig == NULL) { + ALOGE("Unexpected null client/device configurations in recording callback"); + return; + } + // create an array for 2*3 integers to store the record configurations (client + device) + jintArray recParamArray = env->NewIntArray(6); + if (recParamArray == NULL) { + ALOGE("recording callback: Couldn't allocate int array for configuration data"); + return; + } + jint recParamData[6]; + recParamData[0] = (jint) audioFormatFromNative(clientConfig->format); + // FIXME this doesn't support index-based masks + recParamData[1] = (jint) inChannelMaskFromNative(clientConfig->channel_mask); + recParamData[2] = (jint) clientConfig->sample_rate; + recParamData[3] = (jint) audioFormatFromNative(deviceConfig->format); + // FIXME this doesn't support index-based masks + recParamData[4] = (jint) inChannelMaskFromNative(deviceConfig->channel_mask); + recParamData[5] = (jint) deviceConfig->sample_rate; + env->SetIntArrayRegion(recParamArray, 0, 6, recParamData); + + // callback into java jclass clazz = env->FindClass(kClassPathName); env->CallStaticVoidMethod(clazz, gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative, - event, session, source); + event, session, source, recParamArray); env->DeleteLocalRef(clazz); + + env->DeleteLocalRef(recParamArray); } static jint @@ -1819,7 +1844,7 @@ int register_android_media_AudioSystem(JNIEnv *env) "dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V"); gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative = GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName), - "recordingCallbackFromNative", "(III)V"); + "recordingCallbackFromNative", "(III[I)V"); jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix"); gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass); diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 2ab95412ef62..3a45da9ba3ab 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -8048,12 +8048,19 @@ i {@link android.media.tv.TvInputService#SERVICE_META_DATA} meta-data entry. Described here are the attributes that can be included in that tag. --> <declare-styleable name="TvInputService"> - <!-- Component name of an activity for setup of this service. - The setup includes scanning channels and registering EPG data. --> + <!-- Component name of an activity that allows the user to set up this service. --> <attr name="setupActivity" format="string" /> - <!-- Component name of an activity that allows the user to modify - the settings for this service. --> + <!-- Component name of an activity that allows the user to modify the settings for this + service. --> <attr name="settingsActivity" /> + <!-- Attribute whether the TV input service can record programs. This value can be changed + at runtime by calling + {@link android.media.tv.TvInputService#updateTvInputInfo(android.content.Context, android.media.tv.TvInputInfo)}. --> + <attr name="canRecord" format="boolean" /> + <!-- The number of tuners that the TV input service is associated with. This value can be + changed at runtime by calling + {@link android.media.tv.TvInputService#updateTvInputInfo(android.content.Context, android.media.tv.TvInputInfo)}. --> + <attr name="tunerCount" format="integer" /> </declare-styleable> <!-- Attributes that can be used with <code>rating-system-definition</code> tags inside of the diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index dbaa73772bbe..06e2248bbb5a 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2703,6 +2703,8 @@ <public type="attr" name="version" /> <public type="attr" name="backupInForeground" /> <public type="attr" name="countDown" /> + <public type="attr" name="canRecord" /> + <public type="attr" name="tunerCount" /> <public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" /> <public type="style" name="Widget.Material.SeekBar.Discrete" /> diff --git a/media/java/android/media/AudioRecordConfiguration.java b/media/java/android/media/AudioRecordConfiguration.java index 69df88f3cfe3..61d239c0e70b 100644 --- a/media/java/android/media/AudioRecordConfiguration.java +++ b/media/java/android/media/AudioRecordConfiguration.java @@ -41,11 +41,12 @@ public class AudioRecordConfiguration implements Parcelable { /** * @hide */ - public AudioRecordConfiguration(int session, int source) { + public AudioRecordConfiguration(int session, int source, + AudioFormat clientFormat, AudioFormat deviceFormat) { mSessionId = session; mClientSource = source; - mDeviceFormat = new AudioFormat.Builder().build(); - mClientFormat = new AudioFormat.Builder().build(); + mDeviceFormat = deviceFormat; + mClientFormat = clientFormat; mRecDevice = null; } @@ -129,13 +130,17 @@ public class AudioRecordConfiguration implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mSessionId); dest.writeInt(mClientSource); + mClientFormat.writeToParcel(dest, 0); + mDeviceFormat.writeToParcel(dest, 0); + //TODO marshall device info } private AudioRecordConfiguration(Parcel in) { mSessionId = in.readInt(); mClientSource = in.readInt(); - mDeviceFormat = new AudioFormat.Builder().build(); - mClientFormat = new AudioFormat.Builder().build(); + mClientFormat = AudioFormat.CREATOR.createFromParcel(in); + mDeviceFormat = AudioFormat.CREATOR.createFromParcel(in); + //TODO unmarshall device info mRecDevice = null; } diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index b3f73befc0a8..59782cb99a46 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -273,7 +273,17 @@ public class AudioSystem */ public interface AudioRecordingCallback { - void onRecordingConfigurationChanged(int event, int session, int source); + /** + * Callback for recording activity notifications events + * @param event + * @param session + * @param source + * @param recordingFormat an array of ints containing respectively the client and device + * recording configuration. Each set of parameters contains the following parameters + * in this order: format, channel mask, sample rate + */ + void onRecordingConfigurationChanged(int event, int session, int source, + int[] recordingFormat); } private static AudioRecordingCallback sRecordingCallback; @@ -285,13 +295,23 @@ public class AudioSystem } } - private static void recordingCallbackFromNative(int event, int session, int source) { + /** + * Callback from native for recording configuration updates. + * @param event + * @param session + * @param source + * @param recordingFormat see + * {@link AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int[])} for + * the description of the record format. + */ + private static void recordingCallbackFromNative(int event, int session, int source, + int[] recordingFormat) { AudioRecordingCallback cb = null; synchronized (AudioSystem.class) { cb = sRecordingCallback; } if (cb != null) { - cb.onRecordingConfigurationChanged(event, session, source); + cb.onRecordingConfigurationChanged(event, session, source, recordingFormat); } } diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java index f0a94268d533..b8a1374ff077 100644 --- a/media/java/android/media/tv/TvInputInfo.java +++ b/media/java/android/media/tv/TvInputInfo.java @@ -113,14 +113,14 @@ public final class TvInputInfo implements Parcelable { private final String mId; private final String mParentId; private final int mType; - private final int mTunerCount; - private final boolean mCanRecord; private final boolean mIsHardwareInput; private final Bundle mExtras; // Attributes from XML meta data. private String mSetupActivity; private String mSettingsActivity; + private boolean mCanRecord; + private int mTunerCount; private HdmiDeviceInfo mHdmiDeviceInfo; private int mLabelResId; @@ -250,21 +250,17 @@ public final class TvInputInfo implements Parcelable { * {@code false} otherwise. * @param isConnectedToHdmiSwitch Whether a CEC device for this TV input is connected to an HDMI * switch, i.e., the device isn't directly connected to a HDMI port. - * @param tunerCount The number of tuners this TV input has. - * @param canRecord Whether this TV input can record TV programs. */ private TvInputInfo(ResolveInfo service, String id, String parentId, int type, - boolean isHardwareInput, boolean isConnectedToHdmiSwitch, int tunerCount, - boolean canRecord, Bundle extras) { + boolean isHardwareInput, boolean isConnectedToHdmiSwitch, Bundle extras) { mService = service; mId = id; mParentId = parentId; mType = type; mIsHardwareInput = isHardwareInput; mIsConnectedToHdmiSwitch = isConnectedToHdmiSwitch; - mTunerCount = tunerCount; - mCanRecord = canRecord; mExtras = extras; + mTunerCount = type == TYPE_TUNER ? 1 : 0; } /** @@ -791,19 +787,17 @@ public final class TvInputInfo implements Parcelable { type = TYPE_HDMI; isHardwareInput = true; isConnectedToHdmiSwitch = (mHdmiDeviceInfo.getPhysicalAddress() & 0x0FFF) != 0; - mTunerCount = 0; } else if (mTvInputHardwareInfo != null) { id = generateInputId(componentName, mTvInputHardwareInfo); type = sHardwareTypeToTvInputType.get(mTvInputHardwareInfo.getType(), TYPE_TUNER); isHardwareInput = true; - mTunerCount = 0; } else { id = generateInputId(componentName); type = TYPE_TUNER; } TvInputInfo info = new TvInputInfo(mResolveInfo, id, mParentId, type, isHardwareInput, - isConnectedToHdmiSwitch, mTunerCount, mCanRecord, mExtras); + isConnectedToHdmiSwitch, mExtras); return parseServiceMetadata(type, info); } @@ -868,6 +862,12 @@ public final class TvInputInfo implements Parcelable { Log.d(TAG, "Settings activity loaded. [" + info.mSettingsActivity + "] for " + si.name); } + info.mCanRecord = sa.getBoolean( + com.android.internal.R.styleable.TvInputService_canRecord, false); + info.mTunerCount = sa.getInt( + com.android.internal.R.styleable.TvInputService_tunerCount, + info.mTunerCount); + sa.recycle(); } catch (NameNotFoundException e) { throw new XmlPullParserException("Unable to create context for: " + si.packageName); diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index 51aae9083fad..7089c0074c76 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -731,9 +731,7 @@ public final class TvInputManager { * * <p>Because the system automatically creates a <code>TvInputInfo</code> object for each TV * input based on the information collected from the <code>AndroidManifest.xml</code>, this - * method is only called back when such information has changed dynamically or when the TV - * input service implementation wants to pass additional information that is not specified - * by the manifest file, such as ability to record and tuner count. + * method is only called back when such information has changed dynamically. * * @param inputInfo The <code>TvInputInfo</code> object that contains new information. */ diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index da4a03832191..db851a31d363 100644 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -262,10 +262,8 @@ public abstract class TvInputService extends Service { * * <p>The system automatically creates a <code>TvInputInfo</code> object for each TV input, * based on the information collected from the <code>AndroidManifest.xml</code>, thus it is not - * necessary to call this method unless such information has changed dynamically. This may be - * also used to pass additional information that is not specified by the manifest file, such as - * ability to record and tuner count. Use {@link TvInputInfo.Builder} to build a new - * <code>TvInputInfo</code> object. + * necessary to call this method unless such information has changed dynamically. + * Use {@link TvInputInfo.Builder} to build a new <code>TvInputInfo</code> object. * * <p>Attempting to change information about a TV input that the calling package does not own * does nothing. diff --git a/packages/DocumentsUI/res/layout/item_dir_grid.xml b/packages/DocumentsUI/res/layout/item_dir_grid.xml index d866145dc4a6..a4f06d1cefe8 100644 --- a/packages/DocumentsUI/res/layout/item_dir_grid.xml +++ b/packages/DocumentsUI/res/layout/item_dir_grid.xml @@ -62,7 +62,7 @@ android:id="@android:id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:ellipsize="middle" + android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" android:textAppearance="@android:style/TextAppearance.Material.Subhead" diff --git a/packages/DocumentsUI/res/layout/item_doc_grid.xml b/packages/DocumentsUI/res/layout/item_doc_grid.xml index 1890f2fd1089..af1703fbe423 100644 --- a/packages/DocumentsUI/res/layout/item_doc_grid.xml +++ b/packages/DocumentsUI/res/layout/item_doc_grid.xml @@ -90,7 +90,7 @@ android:layout_alignParentTop="true" android:layout_toEndOf="@id/icon_mime_sm" android:singleLine="true" - android:ellipsize="middle" + android:ellipsize="end" android:textAlignment="viewStart" android:textAppearance="@android:style/TextAppearance.Material.Subhead" android:textColor="@*android:color/primary_text_default_material_light" /> diff --git a/packages/DocumentsUI/res/layout/item_doc_list.xml b/packages/DocumentsUI/res/layout/item_doc_list.xml index 8d9837719fd7..b169ec89320a 100644 --- a/packages/DocumentsUI/res/layout/item_doc_list.xml +++ b/packages/DocumentsUI/res/layout/item_doc_list.xml @@ -80,7 +80,7 @@ android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" - android:ellipsize="middle" + android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" android:textAppearance="@android:style/TextAppearance.Material.Subhead" diff --git a/packages/DocumentsUI/res/layout/item_subdir.xml b/packages/DocumentsUI/res/layout/item_subdir.xml index 821432d96799..b8251d1eb865 100644 --- a/packages/DocumentsUI/res/layout/item_subdir.xml +++ b/packages/DocumentsUI/res/layout/item_subdir.xml @@ -40,7 +40,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:singleLine="true" - android:ellipsize="middle" + android:ellipsize="end" android:textAlignment="viewStart" android:textAppearance="@android:style/TextAppearance.Material.Subhead" android:textColor="?android:attr/textColorPrimary" /> diff --git a/packages/DocumentsUI/res/layout/item_subdir_title.xml b/packages/DocumentsUI/res/layout/item_subdir_title.xml index 4c839d0ace20..de6c5234b47b 100644 --- a/packages/DocumentsUI/res/layout/item_subdir_title.xml +++ b/packages/DocumentsUI/res/layout/item_subdir_title.xml @@ -26,7 +26,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" - android:ellipsize="middle" + android:ellipsize="end" android:textAlignment="viewStart" android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title" /> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index 676bf5f56945..72fa9397e898 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -686,8 +686,8 @@ <string name="select_webview_provider_title">WebView implementation</string> <!-- Developer settings: select WebView provider dialog title [CHAR LIMIT=30] --> <string name="select_webview_provider_dialog_title">Set WebView implementation</string> - <!-- Developer settings: confirmation dialog text for the WebView provider selection dialog [CHAR LIMIT=NONE] --> - <string name="select_webview_provider_confirmation_text">The chosen WebView implementation is disabled, and must be enabled to be used, do you wish to enable it?</string> + <!-- Developer settings: text for the WebView provider selection toast shown if an invalid provider was chosen (i.e. the setting list was stale). [CHAR LIMIT=NONE] --> + <string name="select_webview_provider_toast_text">The chosen WebView implementation is invalid because the list of implementation choices grew stale. The list should now be updated.</string> <!-- Developer settings screen, convert userdata to file encryption option name --> <string name="convert_to_file_encryption">Convert to file encryption</string> diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml index b8f10dbec87c..3ee2475ec94a 100644 --- a/packages/SystemUI/res/layout/qs_panel.xml +++ b/packages/SystemUI/res/layout/qs_panel.xml @@ -18,7 +18,9 @@ android:id="@+id/quick_settings_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/qs_background_primary"> + android:background="@drawable/qs_background_primary" + android:clipToPadding="false" + android:clipChildren="false"> <com.android.systemui.qs.QSPanel android:id="@+id/quick_settings_panel" diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml index 8df2c28060fb..0a9baa0aac09 100644 --- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml +++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml @@ -108,7 +108,7 @@ android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentTop="true" - android:layout_marginTop="4dp" + android:layout_marginTop="8dp" android:layout_marginStart="16dp" android:gravity="start" android:orientation="vertical"> diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml index cce07bdaa45d..818df3b46fd7 100644 --- a/packages/SystemUI/res/layout/remote_input.xml +++ b/packages/SystemUI/res/layout/remote_input.xml @@ -42,6 +42,7 @@ android:background="@null" android:singleLine="true" android:ellipsize="start" + android:inputType="textShortMessage|textAutoCorrect|textCapSentences" android:imeOptions="actionSend" /> <FrameLayout diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 09d830f4f063..e1c19b85968a 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -174,8 +174,8 @@ <dimen name="qs_tile_margin">16dp</dimen> <dimen name="qs_quick_tile_size">48dp</dimen> <dimen name="qs_quick_tile_padding">12dp</dimen> - <dimen name="qs_date_anim_translation">36dp</dimen> - <dimen name="qs_date_alarm_anim_translation">26dp</dimen> + <dimen name="qs_date_anim_translation">32dp</dimen> + <dimen name="qs_date_alarm_anim_translation">22dp</dimen> <dimen name="qs_date_collapsed_text_size">14sp</dimen> <dimen name="qs_date_text_size">16sp</dimen> <dimen name="qs_header_gear_translation">150dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 0bd7c4e18a67..26c3f3ab3546 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1270,7 +1270,7 @@ <!-- SysUI Tuner: Disclaimer about using dark theme with night mode [CHAR LIMIT=NONE] --> <string name="night_mode_disclaimer">The dark theme is applied to core areas of Android OS that are normally displayed in a light theme, - such as Settings and notifications.</string> + such as Settings.</string> <!-- Button to apply settings [CHAR LIMIT=30] --> <string name="color_apply">Apply</string> diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml index 023a3f047755..ea9fbfb6bdb3 100644 --- a/packages/SystemUI/res/xml/tuner_prefs.xml +++ b/packages/SystemUI/res/xml/tuner_prefs.xml @@ -120,10 +120,12 @@ </PreferenceScreen> + <!-- <Preference android:key="nav_bar" android:title="@string/nav_bar" android:fragment="com.android.systemui.tuner.NavBarTuner" /> + --> <PreferenceScreen android:key="overview" diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java index 4cfa042cb23b..dc645914e183 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java @@ -39,6 +39,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha public static final float EXPANDED_TILE_DELAY = .7f; private final ArrayList<View> mAllViews = new ArrayList<>(); + private final ArrayList<View> mTopFiveQs = new ArrayList<>(); private final QuickQSPanel mQuickQsPanel; private final QSPanel mQsPanel; private final QSContainer mQsContainer; @@ -86,7 +87,10 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha firstPageDelayedBuilder.setStartDelay(EXPANDED_TILE_DELAY); firstPageBuilder.setListener(this); translationYBuilder.setInterpolator(TRANSLATION_Y_INTERPOLATOR); + // Fade in the tiles/labels as we reach the final position. + firstPageDelayedBuilder.addFloat(mQsPanel.getTileLayout(), "alpha", 0, 1); mAllViews.clear(); + mTopFiveQs.clear(); for (QSTile<?> tile : tiles) { QSTileBaseView tileView = mQsPanel.getTileView(tile); final TextView label = ((QSTileView) tileView).getLabel(); @@ -104,21 +108,17 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff); // Counteract the parent translation on the tile. So we have a static base to - // animate off from. + // animate the label position off from. firstPageBuilder.addFloat(tileView, "translationY", mQsPanel.getHeight(), 0); - // Move the real tile's icon and label from the quick tile position to its final + // Move the real tile's label from the quick tile position to its final // location. - firstPageBuilder.addFloat(tileIcon, "translationX", -xDiff, 0); - translationYBuilder.addFloat(tileIcon, "translationY", -yDiff, 0); firstPageBuilder.addFloat(label, "translationX", -xDiff, 0); translationYBuilder.addFloat(label, "translationY", -yDiff, 0); - // Fade in the label as we reach the final position. - firstPageDelayedBuilder.addFloat(label, "alpha", 0, 1); + mTopFiveQs.add(tileIcon); + mAllViews.add(tileIcon); mAllViews.add(quickTileView); - } else { - firstPageDelayedBuilder.addFloat(tileView, "alpha", 0, 1); } mAllViews.add(tileView); mAllViews.add(label); @@ -159,17 +159,26 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha @Override public void onAnimationAtStart() { - } @Override public void onAnimationAtEnd() { mQuickQsPanel.setVisibility(View.INVISIBLE); + final int N = mTopFiveQs.size(); + for (int i = 0; i < N; i++) { + mTopFiveQs.get(i).setVisibility(View.VISIBLE); + } } @Override public void onAnimationStarted() { mQuickQsPanel.setVisibility(View.VISIBLE); + if (mOnFirstPage) { + final int N = mTopFiveQs.size(); + for (int i = 0; i < N; i++) { + mTopFiveQs.get(i).setVisibility(View.INVISIBLE); + } + } } private void clearAnimationState() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java index b33d31df1cbd..94d8524188ee 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java @@ -14,8 +14,6 @@ package com.android.systemui.qs; -import android.animation.Keyframe; -import android.util.Log; import android.util.MathUtils; import android.util.Property; import android.view.View; @@ -34,7 +32,6 @@ import java.util.List; public class TouchAnimator { private final Object[] mTargets; - private final Property[] mProperties; private final KeyframeSet[] mKeyframeSets; private final float mStartDelay; private final float mEndDelay; @@ -43,10 +40,9 @@ public class TouchAnimator { private final Listener mListener; private float mLastT; - private TouchAnimator(Object[] targets, Property[] properties, KeyframeSet[] keyframeSets, + private TouchAnimator(Object[] targets, KeyframeSet[] keyframeSets, float startDelay, float endDelay, Interpolator interpolator, Listener listener) { mTargets = targets; - mProperties = properties; mKeyframeSets = keyframeSets; mStartDelay = startDelay; mEndDelay = endDelay; @@ -73,8 +69,7 @@ public class TouchAnimator { mLastT = t; } for (int i = 0; i < mTargets.length; i++) { - Object value = mKeyframeSets[i].getValue(t); - mProperties[i].set(mTargets[i], value); + mKeyframeSets[i].setValue(t, mTargets[i]); } } @@ -111,7 +106,6 @@ public class TouchAnimator { public static class Builder { private List<Object> mTargets = new ArrayList<>(); - private List<Property> mProperties = new ArrayList<>(); private List<KeyframeSet> mValues = new ArrayList<>(); private float mStartDelay; @@ -120,18 +114,17 @@ public class TouchAnimator { private Listener mListener; public Builder addFloat(Object target, String property, float... values) { - add(target, property, KeyframeSet.ofFloat(values)); + add(target, KeyframeSet.ofFloat(getProperty(target, property), values)); return this; } public Builder addInt(Object target, String property, int... values) { - add(target, property, KeyframeSet.ofInt(values)); + add(target, KeyframeSet.ofInt(getProperty(target, property), values)); return this; } - private void add(Object target, String property, KeyframeSet keyframeSet) { + private void add(Object target, KeyframeSet keyframeSet) { mTargets.add(target); - mProperties.add(getProperty(target, property)); mValues.add(keyframeSet); } @@ -183,7 +176,6 @@ public class TouchAnimator { public TouchAnimator build() { return new TouchAnimator(mTargets.toArray(new Object[mTargets.size()]), - mProperties.toArray(new Property[mProperties.size()]), mValues.toArray(new KeyframeSet[mValues.size()]), mStartDelay, mEndDelay, mInterpolator, mListener); } @@ -199,54 +191,57 @@ public class TouchAnimator { mFrameWidth = 1 / (float) (size - 1); } - Object getValue(float fraction) { + void setValue(float fraction, Object target) { int i; for (i = 1; i < mSize - 1 && fraction > mFrameWidth; i++); float amount = fraction / mFrameWidth; - return interpolate(i, amount); + interpolate(i, amount, target); } - protected abstract Object interpolate(int index, float amount); + protected abstract void interpolate(int index, float amount, Object target); - public static KeyframeSet ofInt(int... values) { - return new IntKeyframeSet(values); + public static KeyframeSet ofInt(Property property, int... values) { + return new IntKeyframeSet((Property<?, Integer>) property, values); } - public static KeyframeSet ofFloat(float... values) { - return new FloatKeyframeSet(values); + public static KeyframeSet ofFloat(Property property, float... values) { + return new FloatKeyframeSet((Property<?, Float>) property, values); } } - private static class FloatKeyframeSet extends KeyframeSet { + private static class FloatKeyframeSet<T> extends KeyframeSet { private final float[] mValues; + private final Property<T, Float> mProperty; - public FloatKeyframeSet(float[] values) { + public FloatKeyframeSet(Property<T, Float> property, float[] values) { super(values.length); + mProperty = property; mValues = values; } @Override - protected Object interpolate(int index, float amount) { + protected void interpolate(int index, float amount, Object target) { float firstFloat = mValues[index - 1]; float secondFloat = mValues[index]; - return firstFloat + (secondFloat - firstFloat) * amount; + mProperty.set((T) target, firstFloat + (secondFloat - firstFloat) * amount); } } - private static class IntKeyframeSet extends KeyframeSet { - + private static class IntKeyframeSet<T> extends KeyframeSet { private final int[] mValues; + private final Property<T, Integer> mProperty; - public IntKeyframeSet(int[] values) { + public IntKeyframeSet(Property<T, Integer> property, int[] values) { super(values.length); + mProperty = property; mValues = values; } @Override - protected Object interpolate(int index, float amount) { + protected void interpolate(int index, float amount, Object target) { int firstFloat = mValues[index - 1]; int secondFloat = mValues[index]; - return (int) (firstFloat + (secondFloat - firstFloat) * amount); + mProperty.set((T) target, (int) (firstFloat + (secondFloat - firstFloat) * amount)); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java index 8c7c71f11159..04095e76add4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java @@ -45,6 +45,7 @@ public class ExpandableIndicator extends ImageView { final AnimatedVectorDrawable avd = (AnimatedVectorDrawable) getContext() .getDrawable(res).getConstantState().newDrawable(); setImageDrawable(avd); + avd.forceAnimationOnUI(); avd.start(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java index 4f3c61e1119d..5b4a3f0039c9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java @@ -28,10 +28,13 @@ import android.os.Handler; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import android.util.Log; import libcore.io.IoUtils; +import java.util.Objects; + /** * Manages the lockscreen wallpaper. */ @@ -42,11 +45,15 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen private final Context mContext; private final PhoneStatusBar mBar; private final IWallpaperManager mService; + private final WallpaperManager mWallpaperManager; private final Handler mH; private boolean mCached; private Bitmap mCache; - private int mUserId; + private int mCurrentUserId; + // The user selected in the UI, or null if no user is selected or UI doesn't support selecting + // users. + private UserHandle mSelectedUser; public LockscreenWallpaper(Context ctx, PhoneStatusBar bar, Handler h) { mContext = ctx; @@ -54,7 +61,8 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen mH = h; mService = IWallpaperManager.Stub.asInterface( ServiceManager.getService(Context.WALLPAPER_SERVICE)); - mUserId = ActivityManager.getCurrentUser(); + mWallpaperManager = (WallpaperManager) ctx.getSystemService(Context.WALLPAPER_SERVICE); + mCurrentUserId = ActivityManager.getCurrentUser(); try { mService.setLockWallpaperCallback(this); @@ -73,8 +81,12 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen mCache = null; return null; } + // Prefer the selected user (when specified) over the current user for the FLAG_SET_LOCK + // wallpaper. + final int lockWallpaperUserId = + mSelectedUser != null ? mSelectedUser.getIdentifier() : mCurrentUserId; ParcelFileDescriptor fd = mService.getWallpaper(null, WallpaperManager.FLAG_SET_LOCK, - new Bundle(), mUserId); + new Bundle(), lockWallpaperUserId); if (fd != null) { try { BitmapFactory.Options options = new BitmapFactory.Options(); @@ -90,8 +102,17 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen } } else { mCached = true; - mCache = null; - return null; + if (mSelectedUser != null && mSelectedUser.getIdentifier() != mCurrentUserId) { + // When selected user is different from the current user, show the selected + // user's static wallpaper. + mWallpaperManager.forgetLoadedWallpaper(); + mCache = mWallpaperManager.getBitmapAsUser(mSelectedUser.getIdentifier()); + } else { + // When there is no selected user, or it's same as the current user, show the + // system (possibly dynamic) wallpaper for the selected user. + mCache = null; + } + return mCache; } } catch (RemoteException e) { Log.e(TAG, "System dead?" + e); @@ -99,13 +120,23 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen } } - public void setUser(int user) { - if (user != mUserId) { + public void setCurrentUser(int user) { + if (user != mCurrentUserId) { mCached = false; - mUserId = user; + mCurrentUserId = user; } } + public void setSelectedUser(UserHandle selectedUser) { + if (Objects.equals(selectedUser, mSelectedUser)) { + return; + } + mSelectedUser = selectedUser; + + mH.removeCallbacks(this); + mH.post(this); + } + @Override public void onWallpaperChanged() { // Called on Binder thread. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index e344df2bc2f2..d25e99baf0c9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -27,7 +27,6 @@ import android.app.IWallpaperManagerCallback; import android.app.Notification; import android.app.PendingIntent; import android.app.StatusBarManager; -import android.app.WallpaperManager; import android.content.BroadcastReceiver; import android.content.ComponentCallbacks2; import android.content.ComponentName; @@ -69,7 +68,6 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; -import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.os.Vibrator; @@ -296,7 +294,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, AccessibilityController mAccessibilityController; FingerprintUnlockController mFingerprintUnlockController; LightStatusBarController mLightStatusBarController; - private LockscreenWallpaper mLockscreenWallpaper; + protected LockscreenWallpaper mLockscreenWallpaper; int mNaturalBarHeight = -1; @@ -3171,7 +3169,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, resetUserSetupObserver(); setControllerUsers(); clearCurrentMediaNotification(); - mLockscreenWallpaper.setUser(newUserId); + mLockscreenWallpaper.setCurrentUser(newUserId); updateMediaMetaData(true, false); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java index ab8067ddebbe..cf5531fd3eb8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java @@ -21,7 +21,6 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; -import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.RippleDrawable; import android.util.AttributeSet; @@ -129,14 +128,6 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements ((RippleDrawable) getBackground()).setForceSoftware(true); ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true); - addOnLayoutChangeListener(new View.OnLayoutChangeListener() { - @Override - public void onLayoutChange(View v, int left, int top, int right, - int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { - setClipBounds(new Rect(getPaddingLeft(), 0, getWidth() - getPaddingRight(), - getHeight())); - } - }); updateResources(); } diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 6d0d9e9090f6..8cfeb748ccee 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -1671,16 +1671,23 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } @Override - public void dump(FileDescriptor fd, PrintWriter writer, String args[]) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); - if (mBluetoothBinder == null) { - writer.println("Bluetooth Service not connected"); - } else { - try { - mBluetoothBinder.dump(fd, args); - } catch (RemoteException re) { - writer.println("RemoteException while calling Bluetooth Service"); + public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); + String errorMsg = null; + if (mBluetoothBinder == null) { + errorMsg = "Bluetooth Service not connected"; + } else { + try { + mBluetoothBinder.dump(fd, args); + } catch (RemoteException re) { + errorMsg = "RemoteException while calling Bluetooth Service"; + } + } + if (errorMsg != null) { + // Silently return if we are extracting metrics in Protobuf format + if ((args.length > 0) && args[0].startsWith("--proto")) + return; + writer.println(errorMsg); } - } } } diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java index a291cc72ea60..2085f3277648 100644 --- a/services/core/java/com/android/server/PersistentDataBlockService.java +++ b/services/core/java/com/android/server/PersistentDataBlockService.java @@ -27,6 +27,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.service.persistentdata.IPersistentDataBlockService; +import android.service.persistentdata.PersistentDataBlockManager; import android.util.Slog; import com.android.internal.R; @@ -72,6 +73,9 @@ public class PersistentDataBlockService extends SystemService { private static final int MAX_DATA_BLOCK_SIZE = 1024 * 100; public static final int DIGEST_SIZE_BYTES = 32; private static final String OEM_UNLOCK_PROP = "sys.oem_unlock_allowed"; + private static final String FLASH_LOCK_PROP = "ro.boot.flash.locked"; + private static final String FLASH_LOCK_LOCKED = "1"; + private static final String FLASH_LOCK_UNLOCKED = "0"; private final Context mContext; private final String mDataBlockFile; @@ -454,6 +458,20 @@ public class PersistentDataBlockService extends SystemService { } @Override + public int getFlashLockState() { + enforceOemUnlockPermission(); + String locked = SystemProperties.get(FLASH_LOCK_PROP); + switch (locked) { + case FLASH_LOCK_LOCKED: + return PersistentDataBlockManager.FLASH_LOCK_LOCKED; + case FLASH_LOCK_UNLOCKED: + return PersistentDataBlockManager.FLASH_LOCK_UNLOCKED; + default: + return PersistentDataBlockManager.FLASH_LOCK_UNKNOWN; + } + } + + @Override public int getDataBlockSize() { enforcePersistentDataBlockAccess(); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index ec0e07532104..e3a0b5c48f29 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -12291,10 +12291,11 @@ public final class ActivityManagerService extends ActivityManagerNative + " from " + proc.initialIdlePss + ")", true); } } - } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { + } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME + && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) { proc.notCachedSinceIdle = true; proc.initialIdlePss = 0; - proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, + proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true, mTestPssMode, isSleeping(), now); } } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 2394842d25b5..0f0a6c5afce9 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2226,6 +2226,11 @@ public final class ActivityStackSupervisor implements DisplayListener { return; } + if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) { + throw new IllegalArgumentException("moveTaskToStack:" + + "Attempt to move task " + taskId + " to unsupported freeform stack"); + } + final ActivityRecord topActivity = task.getTopActivity(); final int sourceStackId = task.stack != null ? task.stack.mStackId : INVALID_STACK_ID; final boolean mightReplaceWindow = @@ -2260,10 +2265,13 @@ public final class ActivityStackSupervisor implements DisplayListener { // Make sure the task has the appropriate bounds/size for the stack it is in. if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) { kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow); - } else if (stackId == FREEFORM_WORKSPACE_STACK_ID - && task.mBounds == null && task.mLastNonFullscreenBounds != null) { - kept = resizeTaskLocked(task, task.mLastNonFullscreenBounds, - RESIZE_MODE_SYSTEM, !mightReplaceWindow); + } else if (stackId == FREEFORM_WORKSPACE_STACK_ID) { + Rect bounds = task.getLaunchBounds(); + if (bounds == null) { + stack.layoutTaskInStack(task, null); + bounds = task.mBounds; + } + kept = resizeTaskLocked(task, bounds, RESIZE_MODE_FORCED, !mightReplaceWindow); } else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) { kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow); } diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java index a6325a4814b4..4b0a14241d6b 100644 --- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java +++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java @@ -16,6 +16,7 @@ package com.android.server.audio; +import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecordConfiguration; import android.media.AudioSystem; @@ -48,11 +49,12 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin /** * Implementation of android.media.AudioSystem.AudioRecordingCallback */ - public void onRecordingConfigurationChanged(int event, int session, int source) { + public void onRecordingConfigurationChanged(int event, int session, int source, + int[] recordingFormat) { if (MediaRecorder.isSystemOnlyAudioSource(source)) { return; } - if (updateSnapshot(event, session, source)) { + if (updateSnapshot(event, session, source, recordingFormat)) { final Iterator<RecMonitorClient> clientIterator = mClients.iterator(); synchronized(mClients) { while (clientIterator.hasNext()) { @@ -110,15 +112,30 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin * @param event * @param session * @param source + * @param recordingFormat see + * {@link AudioSystem.AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int[])} + * for the definition of the contents of the array * @return true if the list of active recording sessions has been modified, false otherwise. */ - private boolean updateSnapshot(int event, int session, int source) { + private boolean updateSnapshot(int event, int session, int source, int[] recordingFormat) { synchronized(mRecordConfigs) { switch (event) { case AudioManager.RECORD_CONFIG_EVENT_STOP: // return failure if an unknown recording session stopped return (mRecordConfigs.remove(new Integer(session)) != null); case AudioManager.RECORD_CONFIG_EVENT_START: + final AudioFormat clientFormat = new AudioFormat.Builder() + .setEncoding(recordingFormat[0]) + // FIXME this doesn't support index-based masks + .setChannelMask(recordingFormat[1]) + .setSampleRate(recordingFormat[2]) + .build(); + final AudioFormat deviceFormat = new AudioFormat.Builder() + .setEncoding(recordingFormat[3]) + // FIXME this doesn't support index-based masks + .setChannelMask(recordingFormat[4]) + .setSampleRate(recordingFormat[5]) + .build(); if (mRecordConfigs.containsKey(new Integer(session))) { // start of session that's already tracked, not worth an update // TO DO in the future when tracking record format: there might be a record @@ -126,7 +143,8 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin return false; } else { mRecordConfigs.put(new Integer(session), - new AudioRecordConfiguration(session, source)); + new AudioRecordConfiguration(session, source, + clientFormat, deviceFormat)); return true; } default: diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index f7db1f7586f7..95a98751c7d0 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -1319,7 +1319,7 @@ public class SyncManager { } getJobScheduler().scheduleAsPackage(b.build(), syncOperation.owningPackage, - syncOperation.target.userId); + syncOperation.target.userId, "sync"); } /** diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java index 957b0871715c..804be4ea1ae7 100644 --- a/services/core/java/com/android/server/content/SyncOperation.java +++ b/services/core/java/com/android/server/content/SyncOperation.java @@ -17,6 +17,7 @@ package com.android.server.content; import android.accounts.Account; +import android.app.job.JobInfo; import android.content.pm.PackageManager; import android.content.ContentResolver; import android.os.Bundle; @@ -320,11 +321,11 @@ public class SyncOperation { int findPriority() { if (isInitialization()) { - return 2; + return JobInfo.PRIORITY_SYNC_INITIALIZATION; } else if (isExpedited()) { - return 1; + return JobInfo.PRIORITY_SYNC_EXPEDITED; } - return 0; + return JobInfo.PRIORITY_DEFAULT; } private String toKey() { diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index 42ecc06605ff..f1d7b36a98b6 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -52,6 +52,7 @@ import android.os.UserHandle; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseBooleanArray; import com.android.internal.app.IBatteryStats; import com.android.server.DeviceIdleController; import com.android.server.LocalServices; @@ -85,6 +86,8 @@ public final class JobSchedulerService extends com.android.server.SystemService /** The number of concurrent jobs we run at one time. */ private static final int MAX_JOB_CONTEXTS_COUNT = ActivityManager.isLowRamDeviceStatic() ? 3 : 6; + /** Enforce a per-app limit on scheduled jobs? */ + private static final boolean ENFORCE_MAX_JOBS = false; /** The maximum number of jobs that we allow an unprivileged app to schedule */ private static final int MAX_JOBS_PER_APP = 100; @@ -159,11 +162,16 @@ public final class JobSchedulerService extends com.android.server.SystemService boolean mDeviceIdleMode; /** - * What we last reported to DeviceIdleController about wheter we are active. + * What we last reported to DeviceIdleController about whether we are active. */ boolean mReportedActive; /** + * Which uids are currently in the foreground. + */ + final SparseBooleanArray mForegroundUids = new SparseBooleanArray(); + + /** * Cleans up outstanding jobs when a package is removed. Even if it's being replaced later we * still clean up. On reinstall the package will have a new uid. */ @@ -199,9 +207,11 @@ public final class JobSchedulerService extends com.android.server.SystemService final private IUidObserver mUidObserver = new IUidObserver.Stub() { @Override public void onUidStateChanged(int uid, int procState) throws RemoteException { + updateUidState(uid, procState); } @Override public void onUidGone(int uid) throws RemoteException { + updateUidState(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); } @Override public void onUidActive(int uid) throws RemoteException { @@ -236,11 +246,12 @@ public final class JobSchedulerService extends com.android.server.SystemService * @return Result of this operation. See <code>JobScheduler#RESULT_*</code> return codes. */ public int schedule(JobInfo job, int uId) { - return scheduleAsPackage(job, uId, null, -1); + return scheduleAsPackage(job, uId, null, -1, null); } - public int scheduleAsPackage(JobInfo job, int uId, String packageName, int userId) { - JobStatus jobStatus = JobStatus.createFromJobInfo(job, uId, packageName, userId); + public int scheduleAsPackage(JobInfo job, int uId, String packageName, int userId, + String tag) { + JobStatus jobStatus = JobStatus.createFromJobInfo(job, uId, packageName, userId, tag); try { if (ActivityManagerNative.getDefault().getAppStartMode(uId, job.getService().getPackageName()) == ActivityManager.APP_START_MODE_DISABLED) { @@ -254,7 +265,7 @@ public final class JobSchedulerService extends com.android.server.SystemService JobStatus toCancel; synchronized (mLock) { // Jobs on behalf of others don't apply to the per-app job cap - if (packageName == null) { + if (ENFORCE_MAX_JOBS && packageName == null) { if (mJobs.countJobsForUid(uId) > MAX_JOBS_PER_APP) { Slog.w(TAG, "Too many jobs for uid " + uId); throw new IllegalStateException("Apps may not schedule more than " @@ -353,6 +364,25 @@ public final class JobSchedulerService extends com.android.server.SystemService } } + void updateUidState(int uid, int procState) { + synchronized (mLock) { + boolean foreground = procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; + boolean changed = false; + if (foreground) { + if (!mForegroundUids.get(uid)) { + changed = true; + mForegroundUids.put(uid, true); + } + } else { + int index = mForegroundUids.indexOfKey(uid); + if (index >= 0) { + mForegroundUids.removeAt(index); + changed = true; + } + } + } + } + void updateIdleMode(boolean enabled) { boolean changed = false; boolean rocking; @@ -462,7 +492,8 @@ public final class JobSchedulerService extends com.android.server.SystemService mPowerManager = (PowerManager)getContext().getSystemService(Context.POWER_SERVICE); try { ActivityManagerNative.getDefault().registerUidObserver(mUidObserver, - ActivityManager.UID_OBSERVER_IDLE); + ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE + | ActivityManager.UID_OBSERVER_IDLE); } catch (RemoteException e) { // ignored; both services live in system_server } @@ -948,6 +979,17 @@ public final class JobSchedulerService extends com.android.server.SystemService } } + private int evaluateJobPriorityLocked(JobStatus job) { + int priority = job.getPriority(); + if (priority >= JobInfo.PRIORITY_FOREGROUND_APP) { + return priority; + } + if (mForegroundUids.get(job.getSourceUid())) { + return JobInfo.PRIORITY_FOREGROUND_APP; + } + return priority; + } + /** * Takes jobs from pending queue and runs them on available contexts. * If no contexts are available, preempts lower priority jobs to @@ -984,6 +1026,8 @@ public final class JobSchedulerService extends com.android.server.SystemService continue; } + nextPending.lastEvaluatedPriority = evaluateJobPriorityLocked(nextPending); + // Find a context for nextPending. The context should be available OR // it should have lowest priority among all running jobs // (sharing the same Uid as nextPending) @@ -1005,11 +1049,11 @@ public final class JobSchedulerService extends com.android.server.SystemService if (job.getUid() != nextPending.getUid()) { continue; } - if (job.getPriority() >= nextPending.getPriority()) { + if (evaluateJobPriorityLocked(job) >= nextPending.lastEvaluatedPriority) { continue; } - if (minPriority > nextPending.getPriority()) { - minPriority = nextPending.getPriority(); + if (minPriority > nextPending.lastEvaluatedPriority) { + minPriority = nextPending.lastEvaluatedPriority; minPriorityContextId = i; } } @@ -1033,18 +1077,18 @@ public final class JobSchedulerService extends com.android.server.SystemService mActiveServices.get(i).preemptExecutingJob(); preservePreferredUid = true; } else { + final JobStatus pendingJob = contextIdToJobMap[i]; if (DEBUG) { Slog.d(TAG, "About to run job on context " - + String.valueOf(i) + ", job: " + contextIdToJobMap[i]); + + String.valueOf(i) + ", job: " + pendingJob); } for (int ic=0; ic<mControllers.size(); ic++) { - StateController controller = mControllers.get(ic); - controller.prepareForExecutionLocked(contextIdToJobMap[i]); + mControllers.get(ic).prepareForExecutionLocked(pendingJob); } - if (!mActiveServices.get(i).executeRunnableJob(contextIdToJobMap[i])) { - Slog.d(TAG, "Error executing " + contextIdToJobMap[i]); + if (!mActiveServices.get(i).executeRunnableJob(pendingJob)) { + Slog.d(TAG, "Error executing " + pendingJob); } - mPendingJobs.remove(contextIdToJobMap[i]); + mPendingJobs.remove(pendingJob); } } if (!preservePreferredUid) { @@ -1143,7 +1187,7 @@ public final class JobSchedulerService extends com.android.server.SystemService } @Override - public int scheduleAsPackage(JobInfo job, String packageName, int userId) + public int scheduleAsPackage(JobInfo job, String packageName, int userId, String tag) throws RemoteException { final int callerUid = Binder.getCallingUid(); if (DEBUG) { @@ -1165,7 +1209,7 @@ public final class JobSchedulerService extends com.android.server.SystemService long ident = Binder.clearCallingIdentity(); try { return JobSchedulerService.this.scheduleAsPackage(job, callerUid, - packageName, userId); + packageName, userId, tag); } finally { Binder.restoreCallingIdentity(ident); } @@ -1287,7 +1331,22 @@ public final class JobSchedulerService extends com.android.server.SystemService mControllers.get(i).dumpControllerStateLocked(pw); } pw.println(); - pw.println(printPendingQueue()); + pw.println("Foreground uids:"); + for (int i=0; i<mForegroundUids.size(); i++) { + pw.print(" "); pw.println(UserHandle.formatUid(mForegroundUids.keyAt(i))); + } + pw.println(); + pw.println("Pending queue:"); + for (int i=0; i<mPendingJobs.size(); i++) { + JobStatus job = mPendingJobs.get(i); + pw.print(" Pending #"); pw.print(i); pw.print(": "); + pw.println(job.toShortString()); + int priority = evaluateJobPriorityLocked(job); + if (priority != JobInfo.PRIORITY_DEFAULT) { + pw.print(" Evaluated priority: "); pw.println(priority); + } + pw.print(" Tag: "); pw.println(job.getTag()); + } pw.println(); pw.println("Active jobs:"); for (int i=0; i<mActiveServices.size(); i++) { @@ -1303,6 +1362,10 @@ public final class JobSchedulerService extends com.android.server.SystemService pw.print(" fromnow="); pw.println(timeout-now); jsc.getRunningJob().dump(pw, " "); + int priority = evaluateJobPriorityLocked(jsc.getRunningJob()); + if (priority != JobInfo.PRIORITY_DEFAULT) { + pw.print(" Evaluated priority: "); pw.println(priority); + } } } pw.println(); diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java index 48549ce5a113..7c5e336d4841 100644 --- a/services/core/java/com/android/server/job/JobServiceContext.java +++ b/services/core/java/com/android/server/job/JobServiceContext.java @@ -204,7 +204,7 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne return false; } try { - mBatteryStats.noteJobStart(job.getName(), job.getSourceUid()); + mBatteryStats.noteJobStart(job.getBatteryName(), job.getSourceUid()); } catch (RemoteException e) { // Whatever. } @@ -580,7 +580,8 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne } completedJob = mRunningJob; try { - mBatteryStats.noteJobFinish(mRunningJob.getName(), mRunningJob.getSourceUid()); + mBatteryStats.noteJobFinish(mRunningJob.getBatteryName(), + mRunningJob.getSourceUid()); } catch (RemoteException e) { // Whatever. } diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java index f8753d68c678..4268dab01a92 100644 --- a/services/core/java/com/android/server/job/JobStore.java +++ b/services/core/java/com/android/server/job/JobStore.java @@ -323,6 +323,9 @@ public class JobStore { if (jobStatus.getSourcePackageName() != null) { out.attribute(null, "sourcePackageName", jobStatus.getSourcePackageName()); } + if (jobStatus.getSourceTag() != null) { + out.attribute(null, "sourceTag", jobStatus.getSourceTag()); + } out.attribute(null, "sourceUserId", String.valueOf(jobStatus.getSourceUserId())); out.attribute(null, "uid", Integer.toString(jobStatus.getUid())); out.attribute(null, "priority", String.valueOf(jobStatus.getPriority())); @@ -542,6 +545,8 @@ public class JobStore { final String sourcePackageName = parser.getAttributeValue(null, "sourcePackageName"); + final String sourceTag = parser.getAttributeValue(null, "sourceTag"); + int eventType; // Read out constraints tag. do { @@ -656,7 +661,7 @@ public class JobStore { parser.nextTag(); // Consume </extras> JobStatus js = new JobStatus( - jobBuilder.build(), uid, sourcePackageName, sourceUserId, + jobBuilder.build(), uid, sourcePackageName, sourceUserId, sourceTag, elapsedRuntimes.first, elapsedRuntimes.second); return js; } diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java index f83506909bd6..e6fbc39b6dc6 100644 --- a/services/core/java/com/android/server/job/controllers/JobStatus.java +++ b/services/core/java/com/android/server/job/controllers/JobStatus.java @@ -58,12 +58,14 @@ public final class JobStatus { final JobInfo job; /** Uid of the package requesting this job. */ final int callingUid; - final String name; - final String tag; + final String batteryName; final String sourcePackageName; final int sourceUserId; final int sourceUid; + final String sourceTag; + + final String tag; /** * Earliest point in the future at which this job will be eligible to run. A value of 0 @@ -87,6 +89,8 @@ public final class JobStatus { public ArraySet<Uri> changedUris; public ArraySet<String> changedAuthorities; + public int lastEvaluatedPriority; + /** * For use only by ContentObserverController: state it is maintaining about content URIs * being observed. @@ -99,12 +103,10 @@ public final class JobStatus { } private JobStatus(JobInfo job, int callingUid, String sourcePackageName, - int sourceUserId, int numFailures, long earliestRunTimeElapsedMillis, + int sourceUserId, String tag, int numFailures, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { this.job = job; this.callingUid = callingUid; - this.name = job.getService().flattenToShortString(); - this.tag = "*job*/" + this.name; int tempSourceUid = -1; if (sourceUserId != -1 && sourcePackageName != null) { @@ -119,11 +121,24 @@ public final class JobStatus { this.sourceUid = callingUid; this.sourceUserId = UserHandle.getUserId(callingUid); this.sourcePackageName = job.getService().getPackageName(); + this.sourceTag = null; } else { this.sourceUid = tempSourceUid; this.sourceUserId = sourceUserId; this.sourcePackageName = sourcePackageName; + this.sourceTag = tag; + } + + if (this.sourceTag != null) { + StringBuilder sb = new StringBuilder(); + sb.append(job.getService().getPackageName()); + sb.append('/'); + sb.append(this.sourceTag); + this.batteryName = sb.toString(); + } else { + this.batteryName = job.getService().flattenToShortString(); } + this.tag = "*job*/" + this.batteryName; this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis; this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis; @@ -158,8 +173,8 @@ public final class JobStatus { public JobStatus(JobStatus jobStatus) { this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(), - jobStatus.getNumFailures(), jobStatus.getEarliestRunTime(), - jobStatus.getLatestRunTimeElapsed()); + jobStatus.getSourceTag(), jobStatus.getNumFailures(), + jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed()); } /** @@ -169,18 +184,18 @@ public final class JobStatus { * wallclock runtime rather than resetting it on every boot. * We consider a freshly loaded job to no longer be in back-off. */ - public JobStatus(JobInfo job, int callingUid, String sourcePackageName, - int sourceUserId, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { - this(job, callingUid, sourcePackageName, sourceUserId, 0, earliestRunTimeElapsedMillis, - latestRunTimeElapsedMillis); + public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId, + String sourceTag, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { + this(job, callingUid, sourcePackageName, sourceUserId, sourceTag, 0, + earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis); } /** Create a new job to be rescheduled with the provided parameters. */ public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis, long newLatestRuntimeElapsedMillis, int backoffAttempt) { this(rescheduling.job, rescheduling.getUid(), - rescheduling.getSourcePackageName(), - rescheduling.getSourceUserId(), backoffAttempt, newEarliestRuntimeElapsedMillis, + rescheduling.getSourcePackageName(), rescheduling.getSourceUserId(), + rescheduling.getSourceTag(), backoffAttempt, newEarliestRuntimeElapsedMillis, newLatestRuntimeElapsedMillis); } @@ -192,7 +207,7 @@ public final class JobStatus { * @param sourceUserId User id for whom this job is scheduled. -1 indicates this is same as the */ public static JobStatus createFromJobInfo(JobInfo job, int callingUid, String sourcePackageName, - int sourceUserId) { + int sourceUserId, String tag) { final long elapsedNow = SystemClock.elapsedRealtime(); final long earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis; if (job.isPeriodic()) { @@ -204,7 +219,7 @@ public final class JobStatus { latestRunTimeElapsedMillis = job.hasLateConstraint() ? elapsedNow + job.getMaxExecutionDelayMillis() : NO_LATEST_RUNTIME; } - return new JobStatus(job, callingUid, sourcePackageName, sourceUserId, 0, + return new JobStatus(job, callingUid, sourcePackageName, sourceUserId, tag, 0, earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis); } @@ -240,12 +255,16 @@ public final class JobStatus { return UserHandle.getUserId(callingUid); } + public String getSourceTag() { + return sourceTag; + } + public int getUid() { return callingUid; } - public String getName() { - return name; + public String getBatteryName() { + return batteryName; } public String getTag() { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 41077d021798..b218f0f01d9c 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -153,7 +153,6 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.Signature; import android.content.pm.UserInfo; -import android.content.pm.VerificationParams; import android.content.pm.VerifierDeviceIdentity; import android.content.pm.VerifierInfo; import android.content.res.Resources; @@ -173,6 +172,7 @@ import android.os.Looper; import android.os.Message; import android.os.Parcel; import android.os.ParcelFileDescriptor; +import android.os.Parcelable; import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; @@ -5001,8 +5001,9 @@ public class PackageManagerService extends IPackageManager.Stub { // cross-profile app linking works only towards the parent. final UserInfo parent = getProfileParent(sourceUserId); synchronized(mPackages) { + int flags = updateFlagsForResolve(0, parent.id, intent); CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( - intent, resolvedType, 0, sourceUserId, parent.id); + intent, resolvedType, flags, sourceUserId, parent.id); return xpDomainInfo != null; } } @@ -10402,17 +10403,8 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override - public void installPackage(String originPath, IPackageInstallObserver2 observer, - int installFlags, String installerPackageName, VerificationParams verificationParams, - String packageAbiOverride) { - installPackageAsUser(originPath, observer, installFlags, installerPackageName, - verificationParams, packageAbiOverride, UserHandle.getCallingUserId()); - } - - @Override public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, - int installFlags, String installerPackageName, VerificationParams verificationParams, - String packageAbiOverride, int userId) { + int installFlags, String installerPackageName, int userId) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); final int callingUid = Binder.getCallingUid(); @@ -10455,14 +10447,15 @@ public class PackageManagerService extends IPackageManager.Stub { + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); } - verificationParams.setInstallerUid(callingUid); - final File originFile = new File(originPath); final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); final Message msg = mHandler.obtainMessage(INIT_COPY); - final InstallParams params = new InstallParams(origin, null, observer, installFlags, - installerPackageName, null, verificationParams, user, packageAbiOverride, null); + final VerificationInfo verificationInfo = new VerificationInfo( + null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); + final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, + installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, + null /*packageAbiOverride*/, null /*grantedPermissions*/); params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); msg.obj = params; @@ -10482,10 +10475,9 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.d(TAG, "Ephemeral install of " + packageName); } } - final VerificationParams verifParams = new VerificationParams( - null, sessionParams.originatingUri, sessionParams.referrerUri, - sessionParams.originatingUid); - verifParams.setInstallerUid(installerUid); + final VerificationInfo verificationInfo = new VerificationInfo( + sessionParams.originatingUri, sessionParams.referrerUri, + sessionParams.originatingUid, installerUid); final OriginInfo origin; if (stagedDir != null) { @@ -10497,7 +10489,7 @@ public class PackageManagerService extends IPackageManager.Stub { final Message msg = mHandler.obtainMessage(INIT_COPY); final InstallParams params = new InstallParams(origin, null, observer, sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, - verifParams, user, sessionParams.abiOverride, + verificationInfo, user, sessionParams.abiOverride, sessionParams.grantedRuntimePermissions); params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); msg.obj = params; @@ -11525,6 +11517,30 @@ public class PackageManagerService extends IPackageManager.Stub { } } + static class VerificationInfo { + /** A constant used to indicate that a uid value is not present. */ + public static final int NO_UID = -1; + + /** URI referencing where the package was downloaded from. */ + final Uri originatingUri; + + /** HTTP referrer URI associated with the originatingURI. */ + final Uri referrer; + + /** UID of the application that the install request originated from. */ + final int originatingUid; + + /** UID of application requesting the install */ + final int installerUid; + + VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { + this.originatingUri = originatingUri; + this.referrer = referrer; + this.originatingUid = originatingUid; + this.installerUid = installerUid; + } + } + class InstallParams extends HandlerParams { final OriginInfo origin; final MoveInfo move; @@ -11532,15 +11548,15 @@ public class PackageManagerService extends IPackageManager.Stub { int installFlags; final String installerPackageName; final String volumeUuid; - final VerificationParams verificationParams; private InstallArgs mArgs; private int mRet; final String packageAbiOverride; final String[] grantedRuntimePermissions; + final VerificationInfo verificationInfo; InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, - VerificationParams verificationParams, UserHandle user, String packageAbiOverride, + VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, String[] grantedPermissions) { super(user); this.origin = origin; @@ -11549,7 +11565,7 @@ public class PackageManagerService extends IPackageManager.Stub { this.installFlags = installFlags; this.installerPackageName = installerPackageName; this.volumeUuid = volumeUuid; - this.verificationParams = verificationParams; + this.verificationInfo = verificationInfo; this.packageAbiOverride = packageAbiOverride; this.grantedRuntimePermissions = grantedPermissions; } @@ -11792,26 +11808,22 @@ public class PackageManagerService extends IPackageManager.Stub { verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, pkgLite.versionCode); - if (verificationParams != null) { - if (verificationParams.getVerificationURI() != null) { - verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, - verificationParams.getVerificationURI()); - } - if (verificationParams.getOriginatingURI() != null) { + if (verificationInfo != null) { + if (verificationInfo.originatingUri != null) { verification.putExtra(Intent.EXTRA_ORIGINATING_URI, - verificationParams.getOriginatingURI()); + verificationInfo.originatingUri); } - if (verificationParams.getReferrer() != null) { + if (verificationInfo.referrer != null) { verification.putExtra(Intent.EXTRA_REFERRER, - verificationParams.getReferrer()); + verificationInfo.referrer); } - if (verificationParams.getOriginatingUid() >= 0) { + if (verificationInfo.originatingUid >= 0) { verification.putExtra(Intent.EXTRA_ORIGINATING_UID, - verificationParams.getOriginatingUid()); + verificationInfo.originatingUid); } - if (verificationParams.getInstallerUid() >= 0) { + if (verificationInfo.installerUid >= 0) { verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, - verificationParams.getInstallerUid()); + verificationInfo.installerUid); } } @@ -18357,7 +18369,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); final Message msg = mHandler.obtainMessage(INIT_COPY); final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, - installerPackageName, volumeUuid, null, user, packageAbiOverride, null); + installerPackageName, volumeUuid, null /*verificationInfo*/, user, + packageAbiOverride, null); params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); msg.obj = params; diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 26a19418460f..e1a029964279 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -576,6 +576,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mConsumeSearchKeyUp; boolean mAssistKeyLongPressed; boolean mPendingMetaAction; + boolean mForceShowSystemBars; // support for activating the lock screen while the screen is on boolean mAllowLockscreenWhenOn; @@ -3608,7 +3609,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - public void getInsetHintLw(WindowManager.LayoutParams attrs, int displayRotation, + public boolean getInsetHintLw(WindowManager.LayoutParams attrs, int displayRotation, Rect outContentInsets, Rect outStableInsets, Rect outOutsets) { final int fl = PolicyControl.getWindowFlags(null, attrs); final int sysuiVis = PolicyControl.getSystemUiVisibility(null, attrs); @@ -3663,10 +3664,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { outStableInsets.set(mStableLeft, mStableTop, availRight - mStableRight, availBottom - mStableBottom); - return; + return mForceShowSystemBars; } outContentInsets.setEmpty(); outStableInsets.setEmpty(); + return mForceShowSystemBars; } private boolean shouldUseOutsets(WindowManager.LayoutParams attrs, int fl) { @@ -6103,6 +6105,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override + public boolean isNavBarForcedShownLw(WindowState windowState) { + return mForceShowSystemBars + && !windowState.getFrameLw().equals(windowState.getDisplayFrameLw()); + } + + @Override public boolean isDockSideAllowed(int dockSide) { // We do not allow all dock sides at which the navigation bar touches the docked stack. @@ -6994,8 +7002,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { // We need to force system bars when the docked stack is visible, when the freeform stack // is visible but also when we are resizing for the transitions when docked stack // visibility changes. - final boolean forceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing; - final boolean forceOpaqueSystemBars = forceShowSystemBars && !mForceStatusBarFromKeyguard; + mForceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing; + final boolean forceOpaqueSystemBars = mForceShowSystemBars && !mForceStatusBarFromKeyguard; // apply translucent bar vis flags WindowState transWin = isStatusBarKeyguard() && !mHideLockScreen @@ -7043,11 +7051,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0; final boolean transientStatusBarAllowed = mStatusBar != null - && (statusBarHasFocus || (!forceShowSystemBars + && (statusBarHasFocus || (!mForceShowSystemBars && (hideStatusBarWM || (hideStatusBarSysui && immersiveSticky)))); final boolean transientNavBarAllowed = mNavigationBar != null - && !forceShowSystemBars && hideNavBarSysui && immersiveSticky; + && !mForceShowSystemBars && hideNavBarSysui && immersiveSticky; final long now = SystemClock.uptimeMillis(); final boolean pendingPanic = mPendingPanicGestureUptime != 0 @@ -7064,7 +7072,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { && !transientStatusBarAllowed && hideStatusBarSysui; final boolean denyTransientNav = mNavigationBarController.isTransientShowRequested() && !transientNavBarAllowed; - if (denyTransientStatus || denyTransientNav || forceShowSystemBars) { + if (denyTransientStatus || denyTransientNav || mForceShowSystemBars) { // clear the clearable flags instead clearClearableFlagsLw(); vis &= ~View.SYSTEM_UI_CLEARABLE_FLAGS; diff --git a/services/core/java/com/android/server/twilight/TwilightService.java b/services/core/java/com/android/server/twilight/TwilightService.java index ac1ab64a1e81..6158c929a296 100644 --- a/services/core/java/com/android/server/twilight/TwilightService.java +++ b/services/core/java/com/android/server/twilight/TwilightService.java @@ -115,14 +115,14 @@ public final class TwilightService extends SystemService { getContext().registerReceiver(mReceiver, filter); publishLocalService(TwilightManager.class, mService); - getContext().getContentResolver().registerContentObserver( - Secure.getUriFor(Secure.TWILIGHT_MODE), false, mContentObserver, mCurrentUser); - mContentObserver.onChange(true); } @Override public void onBootPhase(int phase) { if (phase == PHASE_BOOT_COMPLETED) { + getContext().getContentResolver().registerContentObserver( + Secure.getUriFor(Secure.TWILIGHT_MODE), false, mContentObserver, mCurrentUser); + mContentObserver.onChange(true); mBootCompleted = true; sendBroadcast(); } diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java index 5d0c22edeaa9..bc5d73fed4c8 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java @@ -23,13 +23,18 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageDeleteObserver; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; +import android.content.pm.UserInfo; import android.os.Binder; +import android.os.PatternMatcher; import android.os.Process; import android.os.RemoteException; +import android.os.ResultReceiver; import android.os.UserHandle; +import android.os.UserManager; import android.provider.Settings; import android.provider.Settings.Global; import android.util.AndroidRuntimeException; @@ -41,6 +46,7 @@ import android.webkit.WebViewFactory; import com.android.server.SystemService; +import java.io.FileDescriptor; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -102,6 +108,27 @@ public class WebViewUpdateService extends SystemService { return; } + // Ensure that we only heed PACKAGE_CHANGED intents if they change an entire + // package, not just a component + if (intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED)) { + if (!WebViewFactory.entirePackageChanged(intent)) { + return; + } + } + + if (intent.getAction().equals(Intent.ACTION_USER_ADDED)) { + int userId = + intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); + handleNewUser(userId); + return; + } + + updateFallbackState(context, intent); + + // TODO(gsennton) for now don't update WebView on PACKAGE_CHANGED as this will + // change the current behaviour even more, instead do this in a follow-up. + if (intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED)) return; + for (WebViewProviderInfo provider : WebViewFactory.getWebViewPackages()) { String webviewPackage = "package:" + provider.packageName; @@ -154,12 +181,167 @@ public class WebViewUpdateService extends SystemService { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_PACKAGE_ADDED); filter.addAction(Intent.ACTION_PACKAGE_REMOVED); + filter.addAction(Intent.ACTION_PACKAGE_CHANGED); filter.addDataScheme("package"); + // Make sure we only receive intents for WebView packages from our config file. + for (WebViewProviderInfo provider : WebViewFactory.getWebViewPackages()) { + filter.addDataSchemeSpecificPart(provider.packageName, PatternMatcher.PATTERN_LITERAL); + } getContext().registerReceiver(mWebViewUpdatedReceiver, filter); + IntentFilter userAddedFilter = new IntentFilter(); + userAddedFilter.addAction(Intent.ACTION_USER_ADDED); + getContext().registerReceiver(mWebViewUpdatedReceiver, userAddedFilter); + publishBinderService("webviewupdate", new BinderService()); } + private static boolean existsValidNonFallbackProvider(WebViewProviderInfo[] providers) { + for (WebViewProviderInfo provider : providers) { + if (provider.isAvailableByDefault() && provider.isEnabled() + && provider.isValidProvider() && !provider.isFallbackPackage()) { + return true; + } + } + return false; + } + + private static void enablePackageForUser(String packageName, boolean enable, int userId) { + try { + AppGlobals.getPackageManager().setApplicationEnabledSetting( + packageName, + enable ? PackageManager.COMPONENT_ENABLED_STATE_DEFAULT : + PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, 0, + userId, null); + } catch (RemoteException e) { + Slog.w(TAG, "Tried to disable " + packageName + " for user " + userId + ": " + e); + } + } + + /** + * Called when a new user has been added to update the state of its fallback package. + */ + void handleNewUser(int userId) { + if (!isFallbackLogicEnabled()) return; + + WebViewProviderInfo[] webviewProviders = WebViewFactory.getWebViewPackages(); + WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders); + if (fallbackProvider == null) return; + boolean existsValidNonFallbackProvider = + existsValidNonFallbackProvider(webviewProviders); + + enablePackageForUser(fallbackProvider.packageName, !existsValidNonFallbackProvider, + userId); + } + + /** + * Handle the enabled-state of our fallback package, i.e. if there exists some non-fallback + * package that is valid (and available by default) then disable the fallback package, + * otherwise, enable the fallback package. + */ + void updateFallbackState(final Context context, final Intent intent) { + if (!isFallbackLogicEnabled()) return; + + WebViewProviderInfo[] webviewProviders = WebViewFactory.getWebViewPackages(); + + if (intent != null && (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED) + || intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED))) { + // A package was changed / updated / downgraded, early out if it is not one of the + // webview packages that are available by default. + String changedPackage = null; + for (WebViewProviderInfo provider : webviewProviders) { + String webviewPackage = "package:" + provider.packageName; + if (webviewPackage.equals(intent.getDataString())) { + if (provider.isAvailableByDefault()) { + changedPackage = provider.packageName; + } + break; + } + } + if (changedPackage == null) return; + } + + // If there exists a valid and enabled non-fallback package - disable the fallback + // package, otherwise, enable it. + WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders); + if (fallbackProvider == null) return; + boolean existsValidNonFallbackProvider = existsValidNonFallbackProvider(webviewProviders); + + if (existsValidNonFallbackProvider + // During an OTA the primary user's WebView state might differ from other users', so + // ignore the state of that user during boot. + && (fallbackProvider.isEnabled() || intent == null)) { + // Uninstall and disable fallback package for all users. + context.getPackageManager().deletePackage(fallbackProvider.packageName, + new IPackageDeleteObserver.Stub() { + public void packageDeleted(String packageName, int returnCode) { + // Ignore returnCode since the deletion could fail, e.g. we might be trying + // to delete a non-updated system-package (and we should still disable the + // package) + UserManager userManager = + (UserManager)context.getSystemService(Context.USER_SERVICE); + // Disable the fallback package for all users. + for(UserInfo userInfo : userManager.getUsers()) { + enablePackageForUser(packageName, false, userInfo.id); + } + } + }, PackageManager.DELETE_SYSTEM_APP | PackageManager.DELETE_ALL_USERS); + } else if (!existsValidNonFallbackProvider + // During an OTA the primary user's WebView state might differ from other users', so + // ignore the state of that user during boot. + && (!fallbackProvider.isEnabled() || intent==null)) { + // Enable the fallback package for all users. + UserManager userManager = + (UserManager)context.getSystemService(Context.USER_SERVICE); + for(UserInfo userInfo : userManager.getUsers()) { + enablePackageForUser(fallbackProvider.packageName, true, userInfo.id); + } + } + } + + private static boolean isFallbackLogicEnabled() { + // Note that this is enabled by default (i.e. if the setting hasn't been set). + return Settings.Global.getInt(AppGlobals.getInitialApplication().getContentResolver(), + Settings.Global.WEBVIEW_FALLBACK_LOGIC_ENABLED, 1) == 1; + } + + private static void enableFallbackLogic(boolean enable) { + Settings.Global.putInt(AppGlobals.getInitialApplication().getContentResolver(), + Settings.Global.WEBVIEW_FALLBACK_LOGIC_ENABLED, enable ? 1 : 0); + } + + /** + * Returns the only fallback provider, or null if there is none. + */ + private static WebViewProviderInfo getFallbackProvider(WebViewProviderInfo[] webviewPackages) { + for (WebViewProviderInfo provider : webviewPackages) { + if (provider.isFallbackPackage()) { + return provider; + } + } + return null; + } + + private static boolean containsAvailableNonFallbackProvider( + WebViewProviderInfo[] webviewPackages) { + for (WebViewProviderInfo provider : webviewPackages) { + if (provider.isAvailableByDefault() && provider.isEnabled() + && provider.isValidProvider() && !provider.isFallbackPackage()) { + return true; + } + } + return false; + } + + private static boolean isFallbackPackage(String packageName) { + if (packageName == null || !isFallbackLogicEnabled()) return false; + + WebViewProviderInfo[] webviewPackages = WebViewFactory.getWebViewPackages(); + WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewPackages); + return (fallbackProvider != null + && packageName.equals(fallbackProvider.packageName)); + } + /** * Perform any WebView loading preparations that must happen at boot from the system server, * after the package manager has started or after an update to the webview is installed. @@ -167,6 +349,7 @@ public class WebViewUpdateService extends SystemService { * Currently, this means spawning the child processes which will create the relro files. */ public void prepareWebViewInSystemServer() { + updateFallbackState(getContext(), null); try { synchronized(this) { updateValidWebViewPackages(); @@ -182,8 +365,10 @@ public class WebViewUpdateService extends SystemService { /** * Change WebView provider and provider setting and kill packages using the old provider. + * Return the new provider (in case we are in the middle of creating relro files this new + * provider will not be in use directly, but will when the relros are done). */ - private void changeProviderAndSetting(String newProviderName) { + private String changeProviderAndSetting(String newProviderName) { PackageInfo oldPackage = null; PackageInfo newPackage = null; synchronized(this) { @@ -195,14 +380,14 @@ public class WebViewUpdateService extends SystemService { if (oldPackage != null && newPackage.packageName.equals(oldPackage.packageName)) { // If we don't perform the user change, revert the settings change. updateUserSetting(newPackage.packageName); - return; + return newPackage.packageName; } } catch (WebViewFactory.MissingWebViewPackageException e) { Slog.e(TAG, "Tried to change WebView provider but failed to fetch WebView package " + e); // If we don't perform the user change but don't have an installed WebView package, // we will have changed the setting and it will be used when a package is available. - return; + return newProviderName; } onWebViewProviderChanged(newPackage); } @@ -214,7 +399,7 @@ public class WebViewUpdateService extends SystemService { } } catch (RemoteException e) { } - return; + return newPackage.packageName; } /** @@ -349,6 +534,14 @@ public class WebViewUpdateService extends SystemService { private class BinderService extends IWebViewUpdateService.Stub { + @Override + public void onShellCommand(FileDescriptor in, FileDescriptor out, + FileDescriptor err, String[] args, ResultReceiver resultReceiver) { + (new WebViewUpdateServiceShellCommand(this)).exec( + this, in, out, err, args, resultReceiver); + } + + /** * The shared relro process calls this to notify us that it's done trying to create a relro * file. This method gets called even if the relro creation has failed or the process @@ -428,7 +621,7 @@ public class WebViewUpdateService extends SystemService { * This is called from DeveloperSettings when the user changes WebView provider. */ @Override // Binder call - public void changeProviderAndSetting(String newProvider) { + public String changeProviderAndSetting(String newProvider) { if (getContext().checkCallingPermission( android.Manifest.permission.WRITE_SECURE_SETTINGS) != PackageManager.PERMISSION_GRANTED) { @@ -440,7 +633,7 @@ public class WebViewUpdateService extends SystemService { throw new SecurityException(msg); } - WebViewUpdateService.this.changeProviderAndSetting(newProvider); + return WebViewUpdateService.this.changeProviderAndSetting(newProvider); } @Override // Binder call @@ -458,5 +651,26 @@ public class WebViewUpdateService extends SystemService { return WebViewUpdateService.this.mCurrentWebViewPackage.packageName; } } + + @Override // Binder call + public boolean isFallbackPackage(String packageName) { + return WebViewUpdateService.isFallbackPackage(packageName); + } + + @Override // Binder call + public void enableFallbackLogic(boolean enable) { + if (getContext().checkCallingPermission( + android.Manifest.permission.WRITE_SECURE_SETTINGS) + != PackageManager.PERMISSION_GRANTED) { + String msg = "Permission Denial: enableFallbackLogic() from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid() + + " requires " + android.Manifest.permission.WRITE_SECURE_SETTINGS; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } + + WebViewUpdateService.enableFallbackLogic(enable); + } } } diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java new file mode 100644 index 000000000000..a9461e82a596 --- /dev/null +++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.webkit; + +import android.os.RemoteException; +import android.os.ShellCommand; +import android.webkit.IWebViewUpdateService; + +import java.io.PrintWriter; + +class WebViewUpdateServiceShellCommand extends ShellCommand { + final IWebViewUpdateService mInterface; + + WebViewUpdateServiceShellCommand(IWebViewUpdateService service) { + mInterface = service; + } + + @Override + public int onCommand(String cmd) { + if (cmd == null) { + return handleDefaultCommands(cmd); + } + + final PrintWriter pw = getOutPrintWriter(); + try { + // TODO(gsennton) add command for changing WebView provider + switch(cmd) { + case "enable-redundant-packages": + return enableFallbackLogic(false); + case "disable-redundant-packages": + return enableFallbackLogic(true); + default: + return handleDefaultCommands(cmd); + } + } catch (RemoteException e) { + pw.println("Remote exception: " + e); + } + return -1; + } + + private int enableFallbackLogic(boolean enable) throws RemoteException { + final PrintWriter pw = getOutPrintWriter(); + mInterface.enableFallbackLogic(enable); + pw.println("Success"); + return 0; + } + + @Override + public void onHelp() { + PrintWriter pw = getOutPrintWriter(); + pw.println("WebView updater commands:"); + pw.println(" help"); + pw.println(" Print this help text."); + pw.println(""); + pw.println(" enable-redundant-packages"); + pw.println(" Allow a fallback package to be installed and enabled even when a"); + pw.println(" more-preferred package is available. This command is useful when testing"); + pw.println(" fallback packages."); + pw.println(" disable-redundant-packages"); + pw.println(" Disallow installing and enabling fallback packages when a more-preferred"); + pw.println(" package is available."); + pw.println(); + } +} diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 8fb5e91f19a3..b8963e4ca050 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1998,8 +1998,10 @@ public class WindowManagerService extends IWindowManager.Stub prepareWindowReplacementTransition(atoken); if (displayContent.isDefaultDisplay) { - mPolicy.getInsetHintLw(win.mAttrs, mRotation, outContentInsets, outStableInsets, - outOutsets); + if (mPolicy.getInsetHintLw(win.mAttrs, mRotation, outContentInsets, outStableInsets, + outOutsets)) { + res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR; + } } else { outContentInsets.setEmpty(); outStableInsets.setEmpty(); @@ -2760,6 +2762,9 @@ public class WindowManagerService extends IWindowManager.Stub winAnimator.mReportSurfaceResized = false; result |= WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED; } + if (mPolicy.isNavBarForcedShownLw(win)) { + result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR; + } if (!win.isGoneForLayoutLw()) { win.mResizedWhileGone = false; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 9dcb404407ed..44ed7e2314b5 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2155,7 +2155,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { Configuration newConfig) throws RemoteException { mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets, reportDraw, newConfig, getBackdropFrame(frame), - isDragResizeChanged() /* forceRelayout */); + isDragResizeChanged() /* forceRelayout */, mPolicy.isNavBarForcedShownLw(this)); mDragResizingChangeReported = true; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 050f6ba9721e..6db147df66f9 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -4090,16 +4090,24 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, String alias) { + public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, String alias, + boolean requestAccess) { enforceCanManageInstalledKeys(who); - final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId()); + final int callingUid = mInjector.binderGetCallingUid(); final long id = mInjector.binderClearCallingIdentity(); try { - final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle); + final KeyChainConnection keyChainConnection = + KeyChain.bindAsUser(mContext, UserHandle.getUserHandleForUid(callingUid)); try { IKeyChainService keyChain = keyChainConnection.getService(); - return keyChain.installKeyPair(privKey, cert, alias); + if (!keyChain.installKeyPair(privKey, cert, alias)) { + return false; + } + if (requestAccess) { + keyChain.setGrant(callingUid, alias, true); + } + return true; } catch (RemoteException e) { Log.e(LOG_TAG, "Installing certificate", e); } finally { diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java index e64481ea6e24..edbff83736ad 100644 --- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java @@ -59,7 +59,7 @@ public class JobStoreTest extends AndroidTestCase { .setMinimumLatency(runFromMillis) .setPersisted(true) .build(); - final JobStatus ts = JobStatus.createFromJobInfo(task, SOME_UID, null, -1); + final JobStatus ts = JobStatus.createFromJobInfo(task, SOME_UID, null, -1, null); mTaskStoreUnderTest.add(ts); Thread.sleep(IO_WAIT); // Manually load tasks from xml file. @@ -92,8 +92,8 @@ public class JobStoreTest extends AndroidTestCase { .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) .setPersisted(true) .build(); - final JobStatus taskStatus1 = JobStatus.createFromJobInfo(task1, SOME_UID, null, -1); - final JobStatus taskStatus2 = JobStatus.createFromJobInfo(task2, SOME_UID, null, -1); + final JobStatus taskStatus1 = JobStatus.createFromJobInfo(task1, SOME_UID, null, -1, null); + final JobStatus taskStatus2 = JobStatus.createFromJobInfo(task2, SOME_UID, null, -1, null); mTaskStoreUnderTest.add(taskStatus1); mTaskStoreUnderTest.add(taskStatus2); Thread.sleep(IO_WAIT); @@ -141,7 +141,7 @@ public class JobStoreTest extends AndroidTestCase { extras.putInt("into", 3); b.setExtras(extras); final JobInfo task = b.build(); - JobStatus taskStatus = JobStatus.createFromJobInfo(task, SOME_UID, null, -1); + JobStatus taskStatus = JobStatus.createFromJobInfo(task, SOME_UID, null, -1, null); mTaskStoreUnderTest.add(taskStatus); Thread.sleep(IO_WAIT); @@ -159,7 +159,7 @@ public class JobStoreTest extends AndroidTestCase { .setRequiresCharging(true) .setPersisted(true); JobStatus taskStatus = JobStatus.createFromJobInfo(b.build(), SOME_UID, - "com.google.android.gms", 0); + "com.google.android.gms", 0, null); mTaskStoreUnderTest.add(taskStatus); Thread.sleep(IO_WAIT); @@ -180,7 +180,7 @@ public class JobStoreTest extends AndroidTestCase { .setPeriodic(5*60*60*1000, 1*60*60*1000) .setRequiresCharging(true) .setPersisted(true); - JobStatus taskStatus = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1); + JobStatus taskStatus = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null); mTaskStoreUnderTest.add(taskStatus); Thread.sleep(IO_WAIT); @@ -206,7 +206,7 @@ public class JobStoreTest extends AndroidTestCase { final long invalidEarlyRuntimeElapsedMillis = invalidLateRuntimeElapsedMillis - TWO_HOURS; // Early is (late - period). final JobStatus js = new JobStatus(b.build(), SOME_UID, "somePackage", - 0 /* sourceUserId */, + 0 /* sourceUserId */, "someTag", invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis); mTaskStoreUnderTest.add(js); @@ -232,7 +232,7 @@ public class JobStoreTest extends AndroidTestCase { .setOverrideDeadline(5000) .setPriority(42) .setPersisted(true); - final JobStatus js = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1); + final JobStatus js = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null); mTaskStoreUnderTest.add(js); Thread.sleep(IO_WAIT); final JobSet jobStatusSet = new JobSet(); @@ -248,12 +248,12 @@ public class JobStoreTest extends AndroidTestCase { JobInfo.Builder b = new Builder(42, mComponent) .setOverrideDeadline(10000) .setPersisted(false); - JobStatus jsNonPersisted = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1); + JobStatus jsNonPersisted = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null); mTaskStoreUnderTest.add(jsNonPersisted); b = new Builder(43, mComponent) .setOverrideDeadline(10000) .setPersisted(true); - JobStatus jsPersisted = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1); + JobStatus jsPersisted = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null); mTaskStoreUnderTest.add(jsPersisted); Thread.sleep(IO_WAIT); final JobSet jobStatusSet = new JobSet(); diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 8e891bfcbabc..8b250f4c18d8 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -151,6 +151,8 @@ public class UsageStatsService extends SystemService implements private ArrayList<UsageStatsManagerInternal.AppIdleStateChangeListener> mPackageAccessListeners = new ArrayList<>(); + private List<String> mCarrierPrivilegedApps; + public UsageStatsService(Context context) { super(context); } @@ -170,10 +172,18 @@ public class UsageStatsService extends SystemService implements + mUsageStatsDir.getAbsolutePath()); } - IntentFilter userActions = new IntentFilter(Intent.ACTION_USER_REMOVED); - userActions.addAction(Intent.ACTION_USER_STARTED); - getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, userActions, - null, null); + IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED); + filter.addAction(Intent.ACTION_USER_STARTED); + getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, filter, + null, mHandler); + + IntentFilter packageFilter = new IntentFilter(); + packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); + packageFilter.addDataScheme("package"); + + getContext().registerReceiverAsUser(new PackageReceiver(), UserHandle.ALL, packageFilter, + null, mHandler); mAppIdleEnabled = getContext().getResources().getBoolean( com.android.internal.R.bool.config_enableAutoPowerModes); @@ -232,15 +242,15 @@ public class UsageStatsService extends SystemService implements } private class UserActionsReceiver extends BroadcastReceiver { - @Override public void onReceive(Context context, Intent intent) { final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); - if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { + final String action = intent.getAction(); + if (Intent.ACTION_USER_REMOVED.equals(action)) { if (userId >= 0) { mHandler.obtainMessage(MSG_REMOVE_USER, userId, 0).sendToTarget(); } - } else if (Intent.ACTION_USER_STARTED.equals(intent.getAction())) { + } else if (Intent.ACTION_USER_STARTED.equals(action)) { if (userId >=0) { postCheckIdleStates(userId); } @@ -248,6 +258,17 @@ public class UsageStatsService extends SystemService implements } } + private class PackageReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (Intent.ACTION_PACKAGE_ADDED.equals(action) + || Intent.ACTION_PACKAGE_CHANGED.equals(action)) { + clearCarrierPrivilegedApps(); + } + } + } + private class DeviceStateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -890,9 +911,30 @@ public class UsageStatsService extends SystemService implements } private boolean isCarrierApp(String packageName) { - TelephonyManager telephonyManager = getContext().getSystemService(TelephonyManager.class); - return telephonyManager.checkCarrierPrivilegesForPackageAnyPhone(packageName) - == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; + synchronized (mLock) { + if (mCarrierPrivilegedApps == null) { + fetchCarrierPrivilegedAppsLocked(); + } + } + return mCarrierPrivilegedApps.contains(packageName); + } + + void clearCarrierPrivilegedApps() { + if (DEBUG) { + Slog.i(TAG, "Clearing carrier privileged apps list"); + } + synchronized (mLock) { + mCarrierPrivilegedApps = null; // Need to be refetched. + } + } + + private void fetchCarrierPrivilegedAppsLocked() { + TelephonyManager telephonyManager = + getContext().getSystemService(TelephonyManager.class); + mCarrierPrivilegedApps = telephonyManager.getPackagesWithCarrierPrivileges(); + if (DEBUG) { + Slog.d(TAG, "apps with carrier privilege " + mCarrierPrivilegedApps); + } } private boolean isActiveNetworkScorer(String packageName) { @@ -963,6 +1005,9 @@ public class UsageStatsService extends SystemService implements } pw.println(); + pw.println("Carrier privileged apps: " + mCarrierPrivilegedApps); + + pw.println(); pw.println("Settings:"); pw.print(" mAppIdleDurationMillis="); @@ -1257,6 +1302,17 @@ public class UsageStatsService extends SystemService implements } @Override + public void onCarrierPrivilegedAppsChanged() { + if (DEBUG) { + Slog.i(TAG, "Carrier privileged apps changed"); + } + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.BIND_CARRIER_SERVICES, + "onCarrierPrivilegedAppsChanged can only be called by privileged apps."); + UsageStatsService.this.clearCarrierPrivilegedApps(); + } + + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index fcb42a48048f..e90be91e3248 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -47,6 +47,7 @@ import com.android.internal.telephony.TelephonyProperties; import java.io.FileInputStream; import java.io.IOException; +import java.util.Collections; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -2931,10 +2932,27 @@ public class TelephonyManager { * @return an IccOpenLogicalChannelResponse object. */ public IccOpenLogicalChannelResponse iccOpenLogicalChannel(String AID) { + return iccOpenLogicalChannel(getDefaultSubscription(), AID); + } + + /** + * Opens a logical channel to the ICC card. + * + * Input parameters equivalent to TS 27.007 AT+CCHO command. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param subId The subscription to use. + * @param AID Application id. See ETSI 102.221 and 101.220. + * @return an IccOpenLogicalChannelResponse object. + */ + public IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID) { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.iccOpenLogicalChannel(AID); + return telephony.iccOpenLogicalChannel(subId, AID); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -2955,10 +2973,28 @@ public class TelephonyManager { * @return true if the channel was closed successfully. */ public boolean iccCloseLogicalChannel(int channel) { + return iccCloseLogicalChannel(getDefaultSubscription(), channel); + } + + /** + * Closes a previously opened logical channel to the ICC card. + * + * Input parameters equivalent to TS 27.007 AT+CCHC command. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param subId The subscription to use. + * @param channel is the channel id to be closed as retruned by a successful + * iccOpenLogicalChannel. + * @return true if the channel was closed successfully. + */ + public boolean iccCloseLogicalChannel(int subId, int channel) { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.iccCloseLogicalChannel(channel); + return telephony.iccCloseLogicalChannel(subId, channel); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -2988,10 +3024,38 @@ public class TelephonyManager { */ public String iccTransmitApduLogicalChannel(int channel, int cla, int instruction, int p1, int p2, int p3, String data) { + return iccTransmitApduLogicalChannel(getDefaultSubscription(), channel, cla, + instruction, p1, p2, p3, data); + } + + /** + * Transmit an APDU to the ICC card over a logical channel. + * + * Input parameters equivalent to TS 27.007 AT+CGLA command. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param subId The subscription to use. + * @param channel is the channel id to be closed as returned by a successful + * iccOpenLogicalChannel. + * @param cla Class of the APDU command. + * @param instruction Instruction of the APDU command. + * @param p1 P1 value of the APDU command. + * @param p2 P2 value of the APDU command. + * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU + * is sent to the SIM. + * @param data Data to be sent with the APDU. + * @return The APDU response from the ICC card with the status appended at + * the end. + */ + public String iccTransmitApduLogicalChannel(int subId, int channel, int cla, + int instruction, int p1, int p2, int p3, String data) { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.iccTransmitApduLogicalChannel(channel, cla, + return telephony.iccTransmitApduLogicalChannel(subId, channel, cla, instruction, p1, p2, p3, data); } catch (RemoteException ex) { } catch (NullPointerException ex) { @@ -3020,10 +3084,36 @@ public class TelephonyManager { */ public String iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2, int p3, String data) { + return iccTransmitApduBasicChannel(getDefaultSubscription(), cla, + instruction, p1, p2, p3, data); + } + + /** + * Transmit an APDU to the ICC card over the basic channel. + * + * Input parameters equivalent to TS 27.007 AT+CSIM command. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param subId The subscription to use. + * @param cla Class of the APDU command. + * @param instruction Instruction of the APDU command. + * @param p1 P1 value of the APDU command. + * @param p2 P2 value of the APDU command. + * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU + * is sent to the SIM. + * @param data Data to be sent with the APDU. + * @return The APDU response from the ICC card with the status appended at + * the end. + */ + public String iccTransmitApduBasicChannel(int subId, int cla, + int instruction, int p1, int p2, int p3, String data) { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.iccTransmitApduBasicChannel(cla, + return telephony.iccTransmitApduBasicChannel(subId, cla, instruction, p1, p2, p3, data); } catch (RemoteException ex) { } catch (NullPointerException ex) { @@ -3048,10 +3138,31 @@ public class TelephonyManager { */ public byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, String filePath) { + return iccExchangeSimIO(getDefaultSubscription(), fileID, command, p1, p2, p3, filePath); + } + + /** + * Returns the response APDU for a command APDU sent through SIM_IO. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param subId The subscription to use. + * @param fileID + * @param command + * @param p1 P1 value of the APDU command. + * @param p2 P2 value of the APDU command. + * @param p3 P3 value of the APDU command. + * @param filePath + * @return The APDU response. + */ + public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, + int p3, String filePath) { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.iccExchangeSimIO(fileID, command, p1, p2, p3, filePath); + return telephony.iccExchangeSimIO(subId, fileID, command, p1, p2, p3, filePath); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -3073,10 +3184,29 @@ public class TelephonyManager { * returns an empty string. */ public String sendEnvelopeWithStatus(String content) { + return sendEnvelopeWithStatus(getDefaultSubscription(), content); + } + + /** + * Send ENVELOPE to the SIM and return the response. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param subId The subscription to use. + * @param content String containing SAT/USAT response in hexadecimal + * format starting with command tag. See TS 102 223 for + * details. + * @return The APDU response from the ICC card in hexadecimal format + * with the last 4 bytes being the status word. If the command fails, + * returns an empty string. + */ + public String sendEnvelopeWithStatus(int subId, String content) { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.sendEnvelopeWithStatus(content); + return telephony.sendEnvelopeWithStatus(subId, content); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -3637,8 +3767,20 @@ public class TelephonyManager { * @return true on success; false on any failure. */ public boolean setPreferredNetworkTypeToGlobal() { - return setPreferredNetworkType(getDefaultSubscription(), - RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA); + return setPreferredNetworkTypeToGlobal(getDefaultSubscription()); + } + + /** + * Set the preferred network type to global mode which includes LTE, CDMA, EvDo and GSM/WCDMA. + * + * <p> + * Requires that the calling app has carrier privileges. + * @see #hasCarrierPrivileges + * + * @return true on success; false on any failure. + */ + public boolean setPreferredNetworkTypeToGlobal(int subId) { + return setPreferredNetworkType(subId, RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA); } /** @@ -3685,10 +3827,26 @@ public class TelephonyManager { * @return true if the app has carrier privileges. */ public boolean hasCarrierPrivileges() { + return hasCarrierPrivileges(getDefaultSubscription()); + } + + /** + * Has the calling application been granted carrier privileges by the carrier. + * + * If any of the packages in the calling UID has carrier privileges, the + * call will return true. This access is granted by the owner of the UICC + * card and does not depend on the registered carrier. + * + * @param subId The subscription to use. + * @return true if the app has carrier privileges. + */ + public boolean hasCarrierPrivileges(int subId) { try { ITelephony telephony = getITelephony(); - if (telephony != null) - return telephony.getCarrierPrivilegeStatus() == CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; + if (telephony != null) { + return telephony.getCarrierPrivilegeStatus(subId) == + CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; + } } catch (RemoteException ex) { Rlog.e(TAG, "hasCarrierPrivileges RemoteException", ex); } catch (NullPointerException ex) { @@ -3712,10 +3870,29 @@ public class TelephonyManager { * @return true if the operation was executed correctly. */ public boolean setOperatorBrandOverride(String brand) { + return setOperatorBrandOverride(getDefaultSubscription(), brand); + } + + /** + * Override the branding for the current ICCID. + * + * Once set, whenever the SIM is present in the device, the service + * provider name (SPN) and the operator name will both be replaced by the + * brand value input. To unset the value, the same function should be + * called with a null brand value. + * + * <p>Requires that the calling app has carrier privileges. + * @see #hasCarrierPrivileges + * + * @param subId The subscription to use. + * @param brand The brand name to display/set. + * @return true if the operation was executed correctly. + */ + public boolean setOperatorBrandOverride(int subId, String brand) { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.setOperatorBrandOverride(brand); + return telephony.setOperatorBrandOverride(subId, brand); } catch (RemoteException ex) { Rlog.e(TAG, "setOperatorBrandOverride RemoteException", ex); } catch (NullPointerException ex) { @@ -3746,10 +3923,37 @@ public class TelephonyManager { public boolean setRoamingOverride(List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList) { + return setRoamingOverride(getDefaultSubscription(), gsmRoamingList, gsmNonRoamingList, + cdmaRoamingList, cdmaNonRoamingList); + } + + /** + * Override the roaming preference for the current ICCID. + * + * Using this call, the carrier app (see #hasCarrierPrivileges) can override + * the platform's notion of a network operator being considered roaming or not. + * The change only affects the ICCID that was active when this call was made. + * + * If null is passed as any of the input, the corresponding value is deleted. + * + * <p>Requires that the caller have carrier privilege. See #hasCarrierPrivileges. + * + * @param subId for which the roaming overrides apply. + * @param gsmRoamingList - List of MCCMNCs to be considered roaming for 3GPP RATs. + * @param gsmNonRoamingList - List of MCCMNCs to be considered not roaming for 3GPP RATs. + * @param cdmaRoamingList - List of SIDs to be considered roaming for 3GPP2 RATs. + * @param cdmaNonRoamingList - List of SIDs to be considered not roaming for 3GPP2 RATs. + * @return true if the operation was executed correctly. + * + * @hide + */ + public boolean setRoamingOverride(int subId, List<String> gsmRoamingList, + List<String> gsmNonRoamingList, List<String> cdmaRoamingList, + List<String> cdmaNonRoamingList) { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, + return telephony.setRoamingOverride(subId, gsmRoamingList, gsmNonRoamingList, cdmaRoamingList, cdmaNonRoamingList); } catch (RemoteException ex) { Rlog.e(TAG, "setRoamingOverride RemoteException", ex); @@ -3857,6 +4061,21 @@ public class TelephonyManager { } /** @hide */ + public List<String> getPackagesWithCarrierPrivileges() { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getPackagesWithCarrierPrivileges(); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "getPackagesWithCarrierPrivileges RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "getPackagesWithCarrierPrivileges NPE", ex); + } + return Collections.EMPTY_LIST; + } + + /** @hide */ @SystemApi public void dial(String number) { try { diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java index c909c6dc518e..4aa5b98ff364 100644 --- a/telephony/java/com/android/ims/ImsReasonInfo.java +++ b/telephony/java/com/android/ims/ImsReasonInfo.java @@ -249,12 +249,33 @@ public class ImsReasonInfo implements Parcelable { public static final int CODE_SUPP_SVC_REINVITE_COLLISION = 1203; /** + * DPD Procedure received no response or send failed + */ + public static final int CODE_IWLAN_DPD_FAILURE = 1300; + + /** + * Establishment of the ePDG Tunnel Failed + */ + public static final int CODE_EPDG_TUNNEL_ESTABLISH_FAILURE = 1400; + + /** + * Re-keying of the ePDG Tunnel Failed; may not always result in teardown + */ + public static final int CODE_EPDG_TUNNEL_REKEY_FAILURE = 1401; + + /** + * Connection to the packet gateway is lost + */ + public static final int CODE_EPDG_TUNNEL_LOST_CONNECTION = 1402; + + /** * Network string error messages. * mExtraMessage may have these values. */ public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service"; + // For main reason code public int mCode; // For the extra code value; it depends on the code value. diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 62f294c3a197..2727319ad0a6 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -538,27 +538,30 @@ interface ITelephony { * * Input parameters equivalent to TS 27.007 AT+CCHO command. * + * @param subId The subscription to use. * @param AID Application id. See ETSI 102.221 and 101.220. * @return an IccOpenLogicalChannelResponse object. */ - IccOpenLogicalChannelResponse iccOpenLogicalChannel(String AID); + IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID); /** * Closes a previously opened logical channel to the ICC card. * * Input parameters equivalent to TS 27.007 AT+CCHC command. * + * @param subId The subscription to use. * @param channel is the channel id to be closed as retruned by a * successful iccOpenLogicalChannel. * @return true if the channel was closed successfully. */ - boolean iccCloseLogicalChannel(int channel); + boolean iccCloseLogicalChannel(int subId, int channel); /** * Transmit an APDU to the ICC card over a logical channel. * * Input parameters equivalent to TS 27.007 AT+CGLA command. * + * @param subId The subscription to use. * @param channel is the channel id to be closed as retruned by a * successful iccOpenLogicalChannel. * @param cla Class of the APDU command. @@ -571,7 +574,7 @@ interface ITelephony { * @return The APDU response from the ICC card with the status appended at * the end. */ - String iccTransmitApduLogicalChannel(int channel, int cla, int instruction, + String iccTransmitApduLogicalChannel(int subId, int channel, int cla, int instruction, int p1, int p2, int p3, String data); /** @@ -579,6 +582,7 @@ interface ITelephony { * * Input parameters equivalent to TS 27.007 AT+CSIM command. * + * @param subId The subscription to use. * @param cla Class of the APDU command. * @param instruction Instruction of the APDU command. * @param p1 P1 value of the APDU command. @@ -589,12 +593,13 @@ interface ITelephony { * @return The APDU response from the ICC card with the status appended at * the end. */ - String iccTransmitApduBasicChannel(int cla, int instruction, + String iccTransmitApduBasicChannel(int subId, int cla, int instruction, int p1, int p2, int p3, String data); /** * Returns the response APDU for a command APDU sent through SIM_IO. * + * @param subId The subscription to use. * @param fileID * @param command * @param p1 P1 value of the APDU command. @@ -603,12 +608,13 @@ interface ITelephony { * @param filePath * @return The APDU response. */ - byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, + byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, String filePath); /** * Send ENVELOPE to the SIM and returns the response. * + * @param subId The subscription to use. * @param contents String containing SAT/USAT response in hexadecimal * format starting with command tag. See TS 102 223 for * details. @@ -616,7 +622,7 @@ interface ITelephony { * being the status word. If the command fails, returns an empty * string. */ - String sendEnvelopeWithStatus(String content); + String sendEnvelopeWithStatus(int subId, String content); /** * Read one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}. @@ -768,9 +774,10 @@ interface ITelephony { * * TODO: Add a link to documentation. * + * @param subId The subscription to use. * @return carrier privilege status defined in TelephonyManager. */ - int getCarrierPrivilegeStatus(); + int getCarrierPrivilegeStatus(int subId); /** * Similar to above, but check for the package whose name is pkgName. @@ -842,10 +849,11 @@ interface ITelephony { * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} * or has to be carrier app - see #hasCarrierPrivileges. * + * @param subId The subscription to use. * @param brand The brand name to display/set. * @return true if the operation was executed correctly. */ - boolean setOperatorBrandOverride(String brand); + boolean setOperatorBrandOverride(int subId, String brand); /** * Override the roaming indicator for the current ICCID. @@ -858,13 +866,14 @@ interface ITelephony { * * <p>Requires that the caller have carrier privilege. See #hasCarrierPrivileges. * + * @param subId for which the roaming overrides apply. * @param gsmRoamingList - List of MCCMNCs to be considered roaming for 3GPP RATs. * @param gsmNonRoamingList - List of MCCMNCs to be considered not roaming for 3GPP RATs. * @param cdmaRoamingList - List of SIDs to be considered roaming for 3GPP2 RATs. * @param cdmaNonRoamingList - List of SIDs to be considered not roaming for 3GPP2 RATs. * @return true if the operation was executed correctly. */ - boolean setRoamingOverride(in List<String> gsmRoamingList, + boolean setRoamingOverride(int subId, in List<String> gsmRoamingList, in List<String> gsmNonRoamingList, in List<String> cdmaRoamingList, in List<String> cdmaNonRoamingList); @@ -1028,4 +1037,9 @@ interface ITelephony { * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise. */ boolean isVoicemailVibrationEnabled(in PhoneAccountHandle accountHandle); + + /** + * Returns a list of packages that have carrier privileges. + */ + List<String> getPackagesWithCarrierPrivileges(); } diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index da4346002110..c34d4a919242 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -25,7 +25,6 @@ import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; -import android.content.pm.ContainerEncryptionParams; import android.content.pm.EphemeralApplicationInfo; import android.content.pm.FeatureInfo; import android.content.pm.IPackageDataObserver; @@ -44,7 +43,6 @@ import android.content.pm.PermissionInfo; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; -import android.content.pm.VerificationParams; import android.content.pm.VerifierDeviceIdentity; import android.content.res.Resources; import android.content.res.XmlResourceParser; @@ -602,14 +600,6 @@ public class MockPackageManager extends PackageManager { throw new UnsupportedOperationException(); } - /** @hide */ - @Override - public void installPackageAsUser(Uri packageURI, PackageInstallObserver observer, - int flags, String installerPackageName, int userId) { - throw new UnsupportedOperationException(); - } - - @Override public void setInstallerPackageName(String targetPackage, String installerPackageName) { @@ -873,26 +863,6 @@ public class MockPackageManager extends PackageManager { * @hide */ @Override - public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, - int flags, String installerPackageName, Uri verificationURI, - ContainerEncryptionParams encryptionParams) { - throw new UnsupportedOperationException(); - } - - /** - * @hide - */ - @Override - public void installPackageWithVerificationAndEncryption(Uri packageURI, - IPackageInstallObserver observer, int flags, String installerPackageName, - VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { - throw new UnsupportedOperationException(); - } - - /** - * @hide - */ - @Override public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, UserHandle user) { return false; @@ -1024,27 +994,6 @@ public class MockPackageManager extends PackageManager { * @hide */ @Override - public void installPackageWithVerification(Uri packageURI, - PackageInstallObserver observer, int flags, String installerPackageName, - Uri verificationURI, - ContainerEncryptionParams encryptionParams) { - throw new UnsupportedOperationException(); - } - - /** - * @hide - */ - @Override - public void installPackageWithVerificationAndEncryption(Uri packageURI, - PackageInstallObserver observer, int flags, String installerPackageName, - VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { - throw new UnsupportedOperationException(); - } - - /** - * @hide - */ - @Override public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId, int flags) { throw new UnsupportedOperationException(); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java index fcfbad2743ed..85e26103fbf5 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java @@ -24,7 +24,6 @@ import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; -import android.content.pm.ContainerEncryptionParams; import android.content.pm.EphemeralApplicationInfo; import android.content.pm.FeatureInfo; import android.content.pm.IPackageDataObserver; @@ -43,7 +42,6 @@ import android.content.pm.PermissionInfo; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; -import android.content.pm.VerificationParams; import android.content.pm.VerifierDeviceIdentity; import android.content.res.Resources; import android.content.res.XmlResourceParser; @@ -555,40 +553,11 @@ public class BridgePackageManager extends PackageManager { } @Override - public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, - int flags, String installerPackageName, Uri verificationURI, - ContainerEncryptionParams encryptionParams) { - } - - @Override - public void installPackageWithVerificationAndEncryption(Uri packageURI, - IPackageInstallObserver observer, int flags, String installerPackageName, - VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { - } - - @Override public void installPackage(Uri packageURI, PackageInstallObserver observer, int flags, String installerPackageName) { } @Override - public void installPackageAsUser(Uri packageURI, PackageInstallObserver observer,int flags, - String installerPackageName, int userId) { - } - - @Override - public void installPackageWithVerification(Uri packageURI, PackageInstallObserver observer, - int flags, String installerPackageName, Uri verificationURI, - ContainerEncryptionParams encryptionParams) { - } - - @Override - public void installPackageWithVerificationAndEncryption(Uri packageURI, - PackageInstallObserver observer, int flags, String installerPackageName, - VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { - } - - @Override public int installExistingPackage(String packageName) throws NameNotFoundException { return 0; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java index 2000fbc0fa47..533a10a6b13a 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java @@ -50,7 +50,8 @@ public final class BridgeWindow implements IWindow { @Override public void resized(Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, Rect rect6, - boolean b, Configuration configuration, Rect rect7, boolean b2) throws RemoteException { + boolean b, Configuration configuration, Rect rect7, boolean b2, boolean b3) + throws RemoteException { // pass for now. } |