diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl index cc266d60465eb..f54c96b88f703 100644 --- a/core/java/com/android/internal/compat/IPlatformCompat.aidl +++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl @@ -22,17 +22,16 @@ import java.util.Map; parcelable CompatibilityChangeConfig; parcelable CompatibilityChangeInfo; - /** * Platform private API for talking with the PlatformCompat service. * - *
Should be used for gating and logging from non-app processes. - * For app processes please use android.compat.Compatibility API. + *
Should be used for gating and logging from non-app processes. + * + *
Note: for app processes please use {@code android.compat.Compatibility} API. * * {@hide} */ -interface IPlatformCompat -{ +interface IPlatformCompat { /** * Reports that a compatibility change is affecting an app process now. @@ -40,8 +39,9 @@ interface IPlatformCompat *
Note: for changes that are gated using {@link #isChangeEnabled(long, ApplicationInfo)}, * you do not need to call this API directly. The change will be reported for you. * - * @param changeId The ID of the compatibility change taking effect. - * @param appInfo Representing the affected app. + * @param changeId the ID of the compatibility change taking effect + * @param appInfo representing the affected app + * @throws SecurityException if logging is not allowed */ void reportChange(long changeId, in ApplicationInfo appInfo); @@ -51,11 +51,12 @@ interface IPlatformCompat *
Note: for changes that are gated using {@link #isChangeEnabled(long, String)}, * you do not need to call this API directly. The change will be reported for you. * - * @param changeId The ID of the compatibility change taking effect. - * @param userId The ID of the user that the operation is done for. - * @param packageName The package name of the app in question. + * @param changeId the ID of the compatibility change taking effect + * @param userId the ID of the user that the operation is done for + * @param packageName the package name of the app in question + * @throws SecurityException if logging is not allowed */ - void reportChangeByPackageName(long changeId, in String packageName, int userId); + void reportChangeByPackageName(long changeId, in String packageName, int userId); /** * Reports that a compatibility change is affecting an app process now. @@ -63,13 +64,14 @@ interface IPlatformCompat *
Note: for changes that are gated using {@link #isChangeEnabled(long, int)}, * you do not need to call this API directly. The change will be reported for you. * - * @param changeId The ID of the compatibility change taking effect. - * @param uid The UID of the app in question. + * @param changeId the ID of the compatibility change taking effect + * @param uid the UID of the app in question + * @throws SecurityException if logging is not allowed */ void reportChangeByUid(long changeId, int uid); /** - * Query if a given compatibility change is enabled for an app process. This method should + * Queries if a given compatibility change is enabled for an app process. This method should * be called when implementing functionality on behalf of the affected app. * *
If this method returns {@code true}, the calling code should implement the compatibility @@ -79,14 +81,15 @@ interface IPlatformCompat *
It will also report the change as {@link #reportChange(long, ApplicationInfo)} would, so * there is no need to call that method directly. * - * @param changeId The ID of the compatibility change in question. - * @param appInfo Representing the app in question. - * @return {@code true} if the change is enabled for the current app. + * @param changeId the ID of the compatibility change in question + * @param appInfo representing the app in question + * @return {@code true} if the change is enabled for the current app + * @throws SecurityException if logging or reading compat confis is not allowed */ boolean isChangeEnabled(long changeId, in ApplicationInfo appInfo); /** - * Query if a given compatibility change is enabled for an app process. This method should + * Queries if a given compatibility change is enabled for an app process. This method should * be called when implementing functionality on behalf of the affected app. * *
Same as {@link #isChangeEnabled(long, ApplicationInfo)}, except it receives a package name @@ -102,15 +105,16 @@ interface IPlatformCompat *
It will also report the change as {@link #reportChange(long, String)} would, so there is * no need to call that method directly. * - * @param changeId The ID of the compatibility change in question. - * @param packageName The package name of the app in question. - * @param userId The ID of the user that the operation is done for. - * @return {@code true} if the change is enabled for the current app. + * @param changeId the ID of the compatibility change in question + * @param packageName the package name of the app in question + * @param userId the ID of the user that the operation is done for + * @return {@code true} if the change is enabled for the current app + * @throws SecurityException if logging or reading compat confis is not allowed */ boolean isChangeEnabledByPackageName(long changeId, in String packageName, int userId); /** - * Query if a given compatibility change is enabled for an app process. This method should + * Queries if a given compatibility change is enabled for an app process. This method should * be called when implementing functionality on behalf of the affected app. * *
Same as {@link #isChangeEnabled(long, ApplicationInfo)}, except it receives a uid @@ -127,110 +131,121 @@ interface IPlatformCompat *
It will also report the change as {@link #reportChange(long, int)} would, so there is * no need to call that method directly. * - * @param changeId The ID of the compatibility change in question. - * @param uid The UID of the app in question. - * @return {@code true} if the change is enabled for the current app. + * @param changeId the ID of the compatibility change in question + * @param uid the UID of the app in question + * @return {@code true} if the change is enabled for the current app + * @throws SecurityException if logging or reading compat confis is not allowed */ boolean isChangeEnabledByUid(long changeId, int uid); /** - * Add overrides to compatibility changes. Kills the app to allow the changes to take effect. + * Adds overrides to compatibility changes. * - * @param overrides Parcelable containing the compat change overrides to be applied. - * @param packageName The package name of the app whose changes will be overridden. + *
Kills the app to allow the changes to take effect. * + * @param overrides parcelable containing the compat change overrides to be applied + * @param packageName the package name of the app whose changes will be overridden + * @throws SecurityException if overriding changes is not permitted */ void setOverrides(in CompatibilityChangeConfig overrides, in String packageName); /** - * Add overrides to compatibility changes. Doesn't kill the app, to be only used in tests. + * Adds overrides to compatibility changes. * - * @param overrides Parcelable containing the compat change overrides to be applied. - * @param packageName The package name of the app whose changes will be overridden. + *
Does not kill the app, to be only used in tests. * + * @param overrides parcelable containing the compat change overrides to be applied + * @param packageName the package name of the app whose changes will be overridden + * @throws SecurityException if overriding changes is not permitted. */ void setOverridesForTest(in CompatibilityChangeConfig overrides, in String packageName); /** - * Removes an override previously added via {@link #setOverrides(CompatibilityChangeConfig, - * String)}. This restores the default behaviour for the given change and app, once any app - * processes have been restarted. - * Kills the app to allow the changes to take effect. + * Restores the default behaviour for the given change and app. * - * @param changeId The ID of the change that was overridden. - * @param packageName The app package name that was overridden. - * @return {@code true} if an override existed; + *
Kills the app to allow the changes to take effect. + * + * @param changeId the ID of the change that was overridden + * @param packageName the app package name that was overridden + * @return {@code true} if an override existed + * @throws SecurityException if overriding changes is not permitted */ boolean clearOverride(long changeId, String packageName); /** - * Enable all compatibility changes which have enabledSinceTargetSdk == - * {@param targetSdkVersion} for an app, subject to the policy. Kills the app to allow the - * changes to take effect. + * Enables all compatibility changes that have enabledSinceTargetSdk == + * {@param targetSdkVersion} for an app, subject to the policy. * - * @param packageName The package name of the app whose compatibility changes will be enabled. + *
Kills the app to allow the changes to take effect. + * + * @param packageName The package name of the app whose compatibility changes will be + * enabled. * @param targetSdkVersion The targetSdkVersion for filtering the changes to be enabled. - * * @return The number of changes that were enabled. + * @throws SecurityException if overriding changes is not permitted. */ int enableTargetSdkChanges(in String packageName, int targetSdkVersion); /** - * Disable all compatibility changes which have enabledAfterTargetSdk == - * {@param targetSdkVersion} for an app, subject to the policy. Kills the app to allow the - * changes to take effect. + * Disables all compatibility changes that have enabledAfterTargetSdk == + * {@param targetSdkVersion} for an app, subject to the policy. * - * @param packageName The package name of the app whose compatibility changes will be disabled. - * @param targetSdkVersion The targetSdkVersion for filtering the changes to be disabled. + *
Kills the app to allow the changes to take effect. * - * @return The number of changes that were disabled. + * @param packageName the package name of the app whose compatibility changes will be + * disabled + * @param targetSdkVersion the targetSdkVersion for filtering the changes to be disabled + * @return the number of changes that were disabled + * @throws SecurityException if overriding changes is not permitted. */ int disableTargetSdkChanges(in String packageName, int targetSdkVersion); /** - * Revert overrides to compatibility changes. Kills the app to allow the changes to take effect. + * Restores the default behaviour for the given app. * - * @param packageName The package name of the app whose overrides will be cleared. + *
Kills the app to allow the changes to take effect. * + * @param packageName the package name of the app whose overrides will be cleared + * @throws SecurityException if overriding changes is not permitted */ void clearOverrides(in String packageName); /** - * Revert overrides to compatibility changes. Doesn't kill the app, to be only used in tests. + * Restores the default behaviour for the given app. * - * @param packageName The package name of the app whose overrides will be cleared. + *
Does not kill the app; to be only used in tests. * + * @param packageName the package name of the app whose overrides will be cleared + * @throws SecurityException if overriding changes is not permitted */ void clearOverridesForTest(in String packageName); - /** * Get configs for an application. * - * @param appInfo The application whose config will be returned. - * - * @return A {@link CompatibilityChangeConfig}, representing whether a change is enabled for - * the given app or not. + * @param appInfo the application whose config will be returned + * @return a {@link CompatibilityChangeConfig}, representing whether a change is enabled for + * the given app or not */ CompatibilityChangeConfig getAppConfig(in ApplicationInfo appInfo); /** * List all compatibility changes. * - * @return An array of {@link CompatChangeInfo} known to the service. + * @return an array of {@link CompatibilityChangeInfo} known to the service */ CompatibilityChangeInfo[] listAllChanges(); /** - * List the compatibility changes that should be present in the UI. - * Filters out certain changes like e.g. logging only. - * - * @return An array of {@link CompatChangeInfo}. - */ + * List the compatibility changes that should be present in the UI. + * Filters out certain changes like e.g. logging only. + * + * @return an array of {@link CompatibilityChangeInfo} + */ CompatibilityChangeInfo[] listUIChanges(); /** - * Get an instance that can determine whether a changeid can be overridden for a package name. + * Gets an instance that can determine whether a changeid can be overridden for a package name. */ IOverrideValidator getOverrideValidator(); } diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index 9376e8dc16eae..69686a2e46781 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -21,7 +21,6 @@ import android.compat.Compatibility.ChangeConfig; import android.content.Context; import android.content.pm.ApplicationInfo; import android.os.Environment; -import android.os.RemoteException; import android.text.TextUtils; import android.util.LongArray; import android.util.LongSparseArray; @@ -53,7 +52,7 @@ import java.util.Set; import javax.xml.datatype.DatatypeConfigurationException; /** - * This class maintains state relating to platform compatibility changes. + * CompatConfig maintains state related to the platform compatibility changes. * *
It stores the default configuration for each change, and any per-package overrides that have
* been configured.
@@ -65,18 +64,38 @@ final class CompatConfig {
@GuardedBy("mChanges")
private final LongSparseArray This is intended to be used by code that reads change config from the filesystem. This
+ * should be done at system startup time.
+ *
+ * Any change with the same ID will be overwritten.
+ *
+ * @param change the change to add
*/
void addChange(CompatChange change) {
synchronized (mChanges) {
@@ -86,13 +105,15 @@ final class CompatConfig {
}
/**
- * Retrieves the set of disabled changes for a given app. Any change ID not in the returned
- * array is by default enabled for the app.
+ * Retrieves the set of disabled changes for a given app.
*
- * @param app The app in question
- * @return A sorted long array of change IDs. We use a primitive array to minimize memory
- * footprint: Every app process will store this array statically so we aim to reduce
- * overhead as much as possible.
+ * Any change ID not in the returned array is by default enabled for the app.
+ *
+ * We use a primitive array to minimize memory footprint: every app process will store this
+ * array statically so we aim to reduce overhead as much as possible.
+ *
+ * @param app the app in question
+ * @return a sorted long array of change IDs
*/
long[] getDisabledChanges(ApplicationInfo app) {
LongArray disabled = new LongArray();
@@ -110,10 +131,10 @@ final class CompatConfig {
}
/**
- * Look up a change ID by name.
+ * Looks up a change ID by name.
*
- * @param name Name of the change to look up
- * @return The change ID, or {@code -1} if no change with that name exists.
+ * @param name name of the change to look up
+ * @return the change ID, or {@code -1} if no change with that name exists
*/
long lookupChangeId(String name) {
synchronized (mChanges) {
@@ -127,10 +148,10 @@ final class CompatConfig {
}
/**
- * Find if a given change is enabled for a given application.
+ * Checks if a given change is enabled for a given application.
*
- * @param changeId The ID of the change in question
- * @param app App to check for
+ * @param changeId the ID of the change in question
+ * @param app app to check for
* @return {@code true} if the change is enabled for this app. Also returns {@code true} if the
* change ID is not known, as unknown changes are enabled by default.
*/
@@ -146,10 +167,10 @@ final class CompatConfig {
}
/**
- * Find if a given change will be enabled for a given package name, prior to installation.
+ * Checks if a given change will be enabled for a given package name after the installation.
*
- * @param changeId The ID of the change in question
- * @param packageName Package name to check for
+ * @param changeId the ID of the change in question
+ * @param packageName package name to check for
* @return {@code true} if the change would be enabled for this package name. Also returns
* {@code true} if the change ID is not known, as unknown changes are enabled by default.
*/
@@ -165,22 +186,22 @@ final class CompatConfig {
}
/**
- * Overrides the enabled state for a given change and app. This method is intended to be used
- * *only* for debugging purposes, ultimately invoked either by an adb command, or from some
- * developer settings UI.
+ * Overrides the enabled state for a given change and app.
*
- * Note, package overrides are not persistent and will be lost on system or runtime restart.
+ * This method is intended to be used *only* for debugging purposes, ultimately invoked
+ * either by an adb command, or from some developer settings UI.
*
- * @param changeId The ID of the change to be overridden. Note, this call will succeed even
- * if
- * this change is not known; it will only have any effect if any code in the
- * platform is gated on the ID given.
- * @param packageName The app package name to override the change for.
- * @param enabled If the change should be enabled or disabled.
- * @return {@code true} if the change existed before adding the override.
+ * Note: package overrides are not persistent and will be lost on system or runtime restart.
+ *
+ * @param changeId the ID of the change to be overridden. Note, this call will succeed even
+ * if this change is not known; it will only have any effect if any code in
+ * the platform is gated on the ID given.
+ * @param packageName the app package name to override the change for
+ * @param enabled if the change should be enabled or disabled
+ * @return {@code true} if the change existed before adding the override
+ * @throws IllegalStateException if overriding is not allowed
*/
- boolean addOverride(long changeId, String packageName, boolean enabled)
- throws SecurityException {
+ boolean addOverride(long changeId, String packageName, boolean enabled) {
boolean alreadyKnown = true;
OverrideAllowedState allowedState =
mOverrideValidator.getOverrideAllowedState(changeId, packageName);
@@ -201,18 +222,14 @@ final class CompatConfig {
break;
default:
throw new IllegalStateException("Should only be able to override changes that "
- + "are allowed or can be deferred.");
+ + "are allowed or can be deferred.");
}
invalidateCache();
}
return alreadyKnown;
}
- /**
- * Check whether the change is known to the compat config.
- *
- * @return {@code true} if the change is known.
- */
+ /** Checks whether the change is known to the compat config. */
boolean isKnownChangeId(long changeId) {
synchronized (mChanges) {
CompatChange c = mChanges.get(changeId);
@@ -221,16 +238,13 @@ final class CompatConfig {
}
/**
- * Returns the maximum sdk version for which this change can be opted in (or -1 if it is not
- * target sdk gated).
+ * Returns the maximum SDK version for which this change can be opted in (or -1 if it is not
+ * target SDK gated).
*/
int maxTargetSdkForChangeIdOptIn(long changeId) {
synchronized (mChanges) {
CompatChange c = mChanges.get(changeId);
- if (c == null) {
- return -1;
- }
- if (c.getEnableSinceTargetSdk() != -1) {
+ if (c != null && c.getEnableSinceTargetSdk() != -1) {
return c.getEnableSinceTargetSdk() - 1;
}
return -1;
@@ -243,10 +257,7 @@ final class CompatConfig {
boolean isLoggingOnly(long changeId) {
synchronized (mChanges) {
CompatChange c = mChanges.get(changeId);
- if (c == null) {
- return false;
- }
- return c.getLoggingOnly();
+ return c != null && c.getLoggingOnly();
}
}
@@ -256,24 +267,21 @@ final class CompatConfig {
boolean isDisabled(long changeId) {
synchronized (mChanges) {
CompatChange c = mChanges.get(changeId);
- if (c == null) {
- return false;
- }
- return c.getDisabled();
+ return c != null && c.getDisabled();
}
}
/**
- * Removes an override previously added via {@link #addOverride(long, String, boolean)}. This
- * restores the default behaviour for the given change and app, once any app processes have been
- * restarted.
+ * Removes an override previously added via {@link #addOverride(long, String, boolean)}.
*
- * @param changeId The ID of the change that was overridden.
- * @param packageName The app package name that was overridden.
+ * This restores the default behaviour for the given change and app, once any app processes
+ * have been restarted.
+ *
+ * @param changeId the ID of the change that was overridden
+ * @param packageName the app package name that was overridden
* @return {@code true} if an override existed;
*/
- boolean removeOverride(long changeId, String packageName)
- throws SecurityException {
+ boolean removeOverride(long changeId, String packageName) {
boolean overrideExists = false;
synchronized (mChanges) {
CompatChange c = mChanges.get(changeId);
@@ -299,13 +307,12 @@ final class CompatConfig {
/**
* Overrides the enabled state for a given change and app.
*
- * Note, package overrides are not persistent and will be lost on system or runtime restart.
+ * Note: package overrides are not persistent and will be lost on system or runtime restart.
*
- * @param overrides list of overrides to default changes config.
- * @param packageName app for which the overrides will be applied.
+ * @param overrides list of overrides to default changes config
+ * @param packageName app for which the overrides will be applied
*/
- void addOverrides(CompatibilityChangeConfig overrides, String packageName)
- throws RemoteException, SecurityException {
+ void addOverrides(CompatibilityChangeConfig overrides, String packageName) {
synchronized (mChanges) {
for (Long changeId : overrides.enabledChanges()) {
addOverride(changeId, packageName, true);
@@ -324,9 +331,9 @@ final class CompatConfig {
*
* This restores the default behaviour for the given app.
*
- * @param packageName The package for which the overrides should be purged.
+ * @param packageName the package for which the overrides should be purged
*/
- void removePackageOverrides(String packageName) throws SecurityException {
+ void removePackageOverrides(String packageName) {
synchronized (mChanges) {
for (int i = 0; i < mChanges.size(); ++i) {
CompatChange change = mChanges.valueAt(i);
@@ -337,8 +344,7 @@ final class CompatConfig {
}
private long[] getAllowedChangesSinceTargetSdkForPackage(String packageName,
- int targetSdkVersion)
- throws RemoteException {
+ int targetSdkVersion) {
LongArray allowed = new LongArray();
synchronized (mChanges) {
for (int i = 0; i < mChanges.size(); ++i) {
@@ -348,7 +354,7 @@ final class CompatConfig {
}
OverrideAllowedState allowedState =
mOverrideValidator.getOverrideAllowedState(change.getId(),
- packageName);
+ packageName);
if (allowedState.state == OverrideAllowedState.ALLOWED) {
allowed.add(change.getId());
}
@@ -361,10 +367,9 @@ final class CompatConfig {
* Enables all changes with enabledSinceTargetSdk == {@param targetSdkVersion} for
* {@param packageName}.
*
- * @return The number of changes that were toggled.
+ * @return the number of changes that were toggled
*/
- int enableTargetSdkChangesForPackage(String packageName, int targetSdkVersion)
- throws RemoteException {
+ int enableTargetSdkChangesForPackage(String packageName, int targetSdkVersion) {
long[] changes = getAllowedChangesSinceTargetSdkForPackage(packageName, targetSdkVersion);
for (long changeId : changes) {
addOverride(changeId, packageName, true);
@@ -372,15 +377,13 @@ final class CompatConfig {
return changes.length;
}
-
/**
* Disables all changes with enabledSinceTargetSdk == {@param targetSdkVersion} for
* {@param packageName}.
*
- * @return The number of changes that were toggled.
+ * @return the number of changes that were toggled
*/
- int disableTargetSdkChangesForPackage(String packageName, int targetSdkVersion)
- throws RemoteException {
+ int disableTargetSdkChangesForPackage(String packageName, int targetSdkVersion) {
long[] changes = getAllowedChangesSinceTargetSdkForPackage(packageName, targetSdkVersion);
for (long changeId : changes) {
addOverride(changeId, packageName, false);
@@ -425,7 +428,7 @@ final class CompatConfig {
/**
* Dumps the current list of compatibility config information.
*
- * @param pw The {@link PrintWriter} instance to which the information will be dumped.
+ * @param pw {@link PrintWriter} instance to which the information will be dumped
*/
void dumpConfig(PrintWriter pw) {
synchronized (mChanges) {
@@ -441,13 +444,10 @@ final class CompatConfig {
}
/**
- * Get the config for a given app.
+ * Returns config for a given app.
*
- * @param applicationInfo the {@link ApplicationInfo} for which the info should be dumped.
- * @return A {@link CompatibilityChangeConfig} which contains the compat config info for the
- * given app.
+ * @param applicationInfo the {@link ApplicationInfo} for which the info should be dumped
*/
-
CompatibilityChangeConfig getAppConfig(ApplicationInfo applicationInfo) {
Set {@code listener.onCompatChange(String)} method is guaranteed to be called with
- * packageName before the app is killed upon an override change. The state of a change is not
- * guaranteed to change when {@code listener.onCompatChange(String)} is called.
- *
- * @param changeId to get updates for
- * @param listener the listener that will be called upon a potential change for package.
- * @throws IllegalStateException if a listener was already registered for changeId
- * @returns {@code true} if a change with changeId was already known, or (@code false}
- * otherwise.
+ * Does not perform costly permission check.
+ * TODO(b/167551701): Remove this method and add 'loggability' as a changeid property.
*/
- public boolean registerListener(long changeId, CompatChange.ChangeListener listener) {
- return mCompatConfig.registerListener(changeId, listener);
+ public boolean isChangeEnabledInternalNoLogging(long changeId, ApplicationInfo appInfo) {
+ return mCompatConfig.isChangeEnabled(changeId, appInfo);
+ }
+
+ /**
+ * Internal version of {@link #isChangeEnabled(long, ApplicationInfo)}.
+ *
+ * Does not perform costly permission check.
+ */
+ public boolean isChangeEnabledInternal(long changeId, ApplicationInfo appInfo) {
+ boolean enabled = isChangeEnabledInternalNoLogging(changeId, appInfo);
+ if (appInfo != null) {
+ reportChangeInternal(changeId, appInfo.uid,
+ enabled ? ChangeReporter.STATE_ENABLED : ChangeReporter.STATE_DISABLED);
+ }
+ return enabled;
}
@Override
- public void setOverrides(CompatibilityChangeConfig overrides, String packageName)
- throws RemoteException, SecurityException {
+ public void setOverrides(CompatibilityChangeConfig overrides, String packageName) {
checkCompatChangeOverridePermission();
mCompatConfig.addOverrides(overrides, packageName);
killPackage(packageName);
}
@Override
- public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName)
- throws RemoteException, SecurityException {
+ public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName) {
checkCompatChangeOverridePermission();
mCompatConfig.addOverrides(overrides, packageName);
}
@Override
- public int enableTargetSdkChanges(String packageName, int targetSdkVersion)
- throws RemoteException, SecurityException {
+ public int enableTargetSdkChanges(String packageName, int targetSdkVersion) {
checkCompatChangeOverridePermission();
- int numChanges = mCompatConfig.enableTargetSdkChangesForPackage(packageName,
- targetSdkVersion);
+ int numChanges =
+ mCompatConfig.enableTargetSdkChangesForPackage(packageName, targetSdkVersion);
killPackage(packageName);
return numChanges;
}
@Override
- public int disableTargetSdkChanges(String packageName, int targetSdkVersion)
- throws RemoteException, SecurityException {
+ public int disableTargetSdkChanges(String packageName, int targetSdkVersion) {
checkCompatChangeOverridePermission();
- int numChanges = mCompatConfig.disableTargetSdkChangesForPackage(packageName,
- targetSdkVersion);
+ int numChanges =
+ mCompatConfig.disableTargetSdkChangesForPackage(packageName, targetSdkVersion);
killPackage(packageName);
return numChanges;
}
@Override
- public void clearOverrides(String packageName) throws RemoteException, SecurityException {
+ public void clearOverrides(String packageName) {
checkCompatChangeOverridePermission();
mCompatConfig.removePackageOverrides(packageName);
killPackage(packageName);
}
@Override
- public void clearOverridesForTest(String packageName)
- throws RemoteException, SecurityException {
+ public void clearOverridesForTest(String packageName) {
checkCompatChangeOverridePermission();
mCompatConfig.removePackageOverrides(packageName);
}
@Override
- public boolean clearOverride(long changeId, String packageName)
- throws RemoteException, SecurityException {
+ public boolean clearOverride(long changeId, String packageName) {
checkCompatChangeOverridePermission();
boolean existed = mCompatConfig.removeOverride(changeId, packageName);
killPackage(packageName);
@@ -247,18 +224,13 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public CompatibilityChangeInfo[] listUIChanges() {
- return Arrays.stream(listAllChanges()).filter(
- x -> isShownInUI(x)).toArray(CompatibilityChangeInfo[]::new);
+ return Arrays.stream(listAllChanges()).filter(this::isShownInUI).toArray(
+ CompatibilityChangeInfo[]::new);
}
- /**
- * Check whether the change is known to the compat config.
- *
- * @return {@code true} if the change is known.
- */
+ /** Checks whether the change is known to the compat config. */
public boolean isKnownChangeId(long changeId) {
return mCompatConfig.isKnownChangeId(changeId);
-
}
/**
@@ -286,7 +258,9 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) {
+ return;
+ }
checkCompatChangeReadAndLogPermission();
mCompatConfig.dumpConfig(pw);
}
@@ -298,7 +272,8 @@ public class PlatformCompat extends IPlatformCompat.Stub {
/**
* Clears information stored about events reported on behalf of an app.
- * To be called once upon app start or end. A second call would be a no-op.
+ *
+ * To be called once upon app start or end. A second call would be a no-op.
*
* @param appInfo the app to reset
*/
@@ -311,13 +286,9 @@ public class PlatformCompat extends IPlatformCompat.Stub {
packageName, 0, userId, userId);
}
- private void reportChange(long changeId, int uid, int state) {
- mChangeReporter.reportChange(uid, changeId, state);
- }
-
private void killPackage(String packageName) {
int uid = LocalServices.getService(PackageManagerInternal.class).getPackageUid(packageName,
- 0, UserHandle.myUserId());
+ 0, UserHandle.myUserId());
if (uid < 0) {
Slog.w(TAG, "Didn't find package " + packageName + " on device.");
@@ -325,21 +296,18 @@ public class PlatformCompat extends IPlatformCompat.Stub {
}
Slog.d(TAG, "Killing package " + packageName + " (UID " + uid + ").");
- killUid(UserHandle.getAppId(uid),
- UserHandle.USER_ALL, "PlatformCompat overrides");
+ killUid(UserHandle.getAppId(uid));
}
- private void killUid(int appId, int userId, String reason) {
+ private void killUid(int appId) {
final long identity = Binder.clearCallingIdentity();
try {
IActivityManager am = ActivityManager.getService();
if (am != null) {
- try {
- am.killUid(appId, userId, reason);
- } catch (RemoteException e) {
- /* ignore - same process */
- }
+ am.killUid(appId, UserHandle.USER_ALL, "PlatformCompat overrides");
}
+ } catch (RemoteException e) {
+ /* ignore - same process */
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -350,13 +318,12 @@ public class PlatformCompat extends IPlatformCompat.Stub {
if (Binder.getCallingUid() == SYSTEM_UID) {
return;
}
- if (mContext.checkCallingOrSelfPermission(LOG_COMPAT_CHANGE)
- != PERMISSION_GRANTED) {
+ if (mContext.checkCallingOrSelfPermission(LOG_COMPAT_CHANGE) != PERMISSION_GRANTED) {
throw new SecurityException("Cannot log compat change usage");
}
}
- private void checkCompatChangeReadPermission() throws SecurityException {
+ private void checkCompatChangeReadPermission() {
// Don't check for permissions within the system process
if (Binder.getCallingUid() == SYSTEM_UID) {
return;
@@ -367,7 +334,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
}
}
- private void checkCompatChangeOverridePermission() throws SecurityException {
+ private void checkCompatChangeOverridePermission() {
// Don't check for permissions within the system process
if (Binder.getCallingUid() == SYSTEM_UID) {
return;
@@ -378,7 +345,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
}
}
- private void checkCompatChangeReadAndLogPermission() throws SecurityException {
+ private void checkCompatChangeReadAndLogPermission() {
checkCompatChangeReadPermission();
checkCompatChangeLogPermission();
}
@@ -391,16 +358,34 @@ public class PlatformCompat extends IPlatformCompat.Stub {
return false;
}
if (change.getEnableSinceTargetSdk() > 0) {
- if (change.getEnableSinceTargetSdk() < sMinTargetSdk) {
- return false;
- }
+ return change.getEnableSinceTargetSdk() >= Build.VERSION_CODES.Q;
}
return true;
}
+ /**
+ * Registers a listener for change state overrides.
+ *
+ * Only one listener per change is allowed.
+ *
+ * {@code listener.onCompatChange(String)} method is guaranteed to be called with
+ * packageName before the app is killed upon an override change. The state of a change is not
+ * guaranteed to change when {@code listener.onCompatChange(String)} is called.
+ *
+ * @param changeId to get updates for
+ * @param listener the listener that will be called upon a potential change for package
+ * @return {@code true} if a change with changeId was already known, or (@code false}
+ * otherwise
+ * @throws IllegalStateException if a listener was already registered for changeId
+ */
+ public boolean registerListener(long changeId, CompatChange.ChangeListener listener) {
+ return mCompatConfig.registerListener(changeId, listener);
+ }
+
/**
* Registers a broadcast receiver that listens for package install, replace or remove.
- * @param context the context where the receiver should be registered.
+ *
+ * @param context the context where the receiver should be registered
*/
public void registerPackageReceiver(Context context) {
final BroadcastReceiver receiver = new BroadcastReceiver() {
@@ -429,8 +414,8 @@ public class PlatformCompat extends IPlatformCompat.Stub {
}
/**
- * Register the observer for
- * {@link android.provider.Settings.Global#FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT}
+ * Registers the observer for
+ * {@link android.provider.Settings.Global#FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT}.
*/
public void registerContentObserver() {
mCompatConfig.registerContentObserver();