Add option to toggle all changes
This change adds the ability of enabling and disabling all allowed changes for a given package and target sdk through adb. Bug: 149980515 Test: adb shell am enable-all 28 foo.bar && \ adb shell dumpsys platform_compat Test: adb shell am disable-all 28 foo.bar && \ adb shell dumpsys platform_compat Test: atest CompatConfigTest Merged-In: Ia84d8e1162ea0b3f4c6afe87e63db56256236940 Change-Id: I4696e13882b1b2c930731e6e7787924e20da1a46
This commit is contained in:
@@ -163,6 +163,30 @@ interface IPlatformCompat
|
||||
*/
|
||||
boolean clearOverride(long changeId, String packageName);
|
||||
|
||||
/**
|
||||
* Enable 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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
int disableTargetSdkChanges(in String packageName, int targetSdkVersion);
|
||||
|
||||
/**
|
||||
* Revert overrides to compatibility changes. Kills the app to allow the changes to take effect.
|
||||
*
|
||||
|
||||
@@ -2931,25 +2931,35 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
final PlatformCompat platformCompat = (PlatformCompat)
|
||||
ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
|
||||
String toggleValue = getNextArgRequired();
|
||||
if (toggleValue.equals("reset-all")) {
|
||||
final String packageName = getNextArgRequired();
|
||||
pw.println("Reset all changes for " + packageName + " to default value.");
|
||||
platformCompat.clearOverrides(packageName);
|
||||
return 0;
|
||||
}
|
||||
long changeId;
|
||||
String changeIdString = getNextArgRequired();
|
||||
try {
|
||||
changeId = Long.parseLong(changeIdString);
|
||||
} catch (NumberFormatException e) {
|
||||
changeId = platformCompat.lookupChangeId(changeIdString);
|
||||
}
|
||||
if (changeId == -1) {
|
||||
pw.println("Unknown or invalid change: '" + changeIdString + "'.");
|
||||
return -1;
|
||||
boolean toggleAll = false;
|
||||
int targetSdkVersion = -1;
|
||||
long changeId = -1;
|
||||
|
||||
if (toggleValue.endsWith("-all")) {
|
||||
toggleValue = toggleValue.substring(0, toggleValue.lastIndexOf("-all"));
|
||||
toggleAll = true;
|
||||
if (!toggleValue.equals("reset")) {
|
||||
try {
|
||||
targetSdkVersion = Integer.parseInt(getNextArgRequired());
|
||||
} catch (NumberFormatException e) {
|
||||
pw.println("Invalid targetSdkVersion!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String changeIdString = getNextArgRequired();
|
||||
try {
|
||||
changeId = Long.parseLong(changeIdString);
|
||||
} catch (NumberFormatException e) {
|
||||
changeId = platformCompat.lookupChangeId(changeIdString);
|
||||
}
|
||||
if (changeId == -1) {
|
||||
pw.println("Unknown or invalid change: '" + changeIdString + "'.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
String packageName = getNextArgRequired();
|
||||
if (!platformCompat.isKnownChangeId(changeId)) {
|
||||
if (!toggleAll && !platformCompat.isKnownChangeId(changeId)) {
|
||||
pw.println("Warning! Change " + changeId + " is not known yet. Enabling/disabling it"
|
||||
+ " could have no effect.");
|
||||
}
|
||||
@@ -2958,22 +2968,49 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
try {
|
||||
switch (toggleValue) {
|
||||
case "enable":
|
||||
enabled.add(changeId);
|
||||
CompatibilityChangeConfig overrides =
|
||||
new CompatibilityChangeConfig(
|
||||
new Compatibility.ChangeConfig(enabled, disabled));
|
||||
platformCompat.setOverrides(overrides, packageName);
|
||||
pw.println("Enabled change " + changeId + " for " + packageName + ".");
|
||||
if (toggleAll) {
|
||||
int numChanges = platformCompat.enableTargetSdkChanges(packageName,
|
||||
targetSdkVersion);
|
||||
if (numChanges == 0) {
|
||||
pw.println("No changes were enabled.");
|
||||
return -1;
|
||||
}
|
||||
pw.println("Enabled " + numChanges + " changes gated by targetSdkVersion "
|
||||
+ targetSdkVersion + " for " + packageName + ".");
|
||||
} else {
|
||||
enabled.add(changeId);
|
||||
CompatibilityChangeConfig overrides =
|
||||
new CompatibilityChangeConfig(
|
||||
new Compatibility.ChangeConfig(enabled, disabled));
|
||||
platformCompat.setOverrides(overrides, packageName);
|
||||
pw.println("Enabled change " + changeId + " for " + packageName + ".");
|
||||
}
|
||||
return 0;
|
||||
case "disable":
|
||||
disabled.add(changeId);
|
||||
overrides =
|
||||
new CompatibilityChangeConfig(
|
||||
new Compatibility.ChangeConfig(enabled, disabled));
|
||||
platformCompat.setOverrides(overrides, packageName);
|
||||
pw.println("Disabled change " + changeId + " for " + packageName + ".");
|
||||
if (toggleAll) {
|
||||
int numChanges = platformCompat.disableTargetSdkChanges(packageName,
|
||||
targetSdkVersion);
|
||||
if (numChanges == 0) {
|
||||
pw.println("No changes were disabled.");
|
||||
return -1;
|
||||
}
|
||||
pw.println("Disabled " + numChanges + " changes gated by targetSdkVersion "
|
||||
+ targetSdkVersion + " for " + packageName + ".");
|
||||
} else {
|
||||
disabled.add(changeId);
|
||||
CompatibilityChangeConfig overrides =
|
||||
new CompatibilityChangeConfig(
|
||||
new Compatibility.ChangeConfig(enabled, disabled));
|
||||
platformCompat.setOverrides(overrides, packageName);
|
||||
pw.println("Disabled change " + changeId + " for " + packageName + ".");
|
||||
}
|
||||
return 0;
|
||||
case "reset":
|
||||
if (toggleAll) {
|
||||
platformCompat.clearOverrides(packageName);
|
||||
pw.println("Reset all changes for " + packageName + " to default value.");
|
||||
return 0;
|
||||
}
|
||||
if (platformCompat.clearOverride(changeId, packageName)) {
|
||||
pw.println("Reset change " + changeId + " for " + packageName
|
||||
+ " to default value.");
|
||||
@@ -3304,6 +3341,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
pw.println(" enable|disable|reset <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>");
|
||||
pw.println(" Toggles a change either by id or by name for <PACKAGE_NAME>.");
|
||||
pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect).");
|
||||
pw.println(" enable-all|disable-all <targetSdkVersion> <PACKAGE_NAME");
|
||||
pw.println(" Toggles all changes that are gated by <targetSdkVersion>.");
|
||||
pw.println(" reset-all <PACKAGE_NAME>");
|
||||
pw.println(" Removes all existing overrides for all changes for ");
|
||||
pw.println(" <PACKAGE_NAME> (back to default behaviour).");
|
||||
|
||||
@@ -288,6 +288,63 @@ final class CompatConfig {
|
||||
}
|
||||
}
|
||||
|
||||
private long[] getAllowedChangesAfterTargetSdkForPackage(String packageName,
|
||||
int targetSdkVersion)
|
||||
throws RemoteException {
|
||||
LongArray allowed = new LongArray();
|
||||
synchronized (mChanges) {
|
||||
for (int i = 0; i < mChanges.size(); ++i) {
|
||||
try {
|
||||
CompatChange change = mChanges.valueAt(i);
|
||||
if (change.getEnableAfterTargetSdk() != targetSdkVersion) {
|
||||
continue;
|
||||
}
|
||||
OverrideAllowedState allowedState =
|
||||
mOverrideValidator.getOverrideAllowedState(change.getId(),
|
||||
packageName);
|
||||
if (allowedState.state == OverrideAllowedState.ALLOWED) {
|
||||
allowed.add(change.getId());
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// Should never occur, since validator is in the same process.
|
||||
throw new RuntimeException("Unable to call override validator!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return allowed.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables all changes with enabledAfterTargetSdk == {@param targetSdkVersion} for
|
||||
* {@param packageName}.
|
||||
*
|
||||
* @return The number of changes that were toggled.
|
||||
*/
|
||||
int enableTargetSdkChangesForPackage(String packageName, int targetSdkVersion)
|
||||
throws RemoteException {
|
||||
long[] changes = getAllowedChangesAfterTargetSdkForPackage(packageName, targetSdkVersion);
|
||||
for (long changeId : changes) {
|
||||
addOverride(changeId, packageName, true);
|
||||
}
|
||||
return changes.length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Disables all changes with enabledAfterTargetSdk == {@param targetSdkVersion} for
|
||||
* {@param packageName}.
|
||||
*
|
||||
* @return The number of changes that were toggled.
|
||||
*/
|
||||
int disableTargetSdkChangesForPackage(String packageName, int targetSdkVersion)
|
||||
throws RemoteException {
|
||||
long[] changes = getAllowedChangesAfterTargetSdkForPackage(packageName, targetSdkVersion);
|
||||
for (long changeId : changes) {
|
||||
addOverride(changeId, packageName, false);
|
||||
}
|
||||
return changes.length;
|
||||
}
|
||||
|
||||
boolean registerListener(long changeId, CompatChange.ChangeListener listener) {
|
||||
boolean alreadyKnown = true;
|
||||
synchronized (mChanges) {
|
||||
|
||||
@@ -165,6 +165,26 @@ public class PlatformCompat extends IPlatformCompat.Stub {
|
||||
mCompatConfig.addOverrides(overrides, packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableTargetSdkChanges(String packageName, int targetSdkVersion)
|
||||
throws RemoteException, SecurityException {
|
||||
checkCompatChangeOverridePermission();
|
||||
int numChanges = mCompatConfig.enableTargetSdkChangesForPackage(packageName,
|
||||
targetSdkVersion);
|
||||
killPackage(packageName);
|
||||
return numChanges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int disableTargetSdkChanges(String packageName, int targetSdkVersion)
|
||||
throws RemoteException, SecurityException {
|
||||
checkCompatChangeOverridePermission();
|
||||
int numChanges = mCompatConfig.disableTargetSdkChangesForPackage(packageName,
|
||||
targetSdkVersion);
|
||||
killPackage(packageName);
|
||||
return numChanges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearOverrides(String packageName) throws RemoteException, SecurityException {
|
||||
checkCompatChangeOverridePermission();
|
||||
|
||||
@@ -255,6 +255,49 @@ public class CompatConfigTest {
|
||||
assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnableTargetSdkChangesForPackage() throws Exception {
|
||||
CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
|
||||
.addEnabledChangeWithId(1L)
|
||||
.addDisabledChangeWithId(2L)
|
||||
.addTargetSdkChangeWithId(3, 3L)
|
||||
.addTargetSdkChangeWithId(4, 4L)
|
||||
.build();
|
||||
ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
|
||||
.withPackageName("foo.bar")
|
||||
.withTargetSdk(2)
|
||||
.build();
|
||||
|
||||
assertThat(compatConfig.isChangeEnabled(3, applicationInfo)).isFalse();
|
||||
assertThat(compatConfig.isChangeEnabled(4, applicationInfo)).isFalse();
|
||||
|
||||
assertThat(compatConfig.enableTargetSdkChangesForPackage("foo.bar", 3)).isEqualTo(1);
|
||||
assertThat(compatConfig.isChangeEnabled(3, applicationInfo)).isTrue();
|
||||
assertThat(compatConfig.isChangeEnabled(4, applicationInfo)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableTargetSdkChangesForPackage() throws Exception {
|
||||
CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
|
||||
.addEnabledChangeWithId(1L)
|
||||
.addDisabledChangeWithId(2L)
|
||||
.addTargetSdkChangeWithId(3, 3L)
|
||||
.addTargetSdkChangeWithId(4, 4L)
|
||||
.build();
|
||||
ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
|
||||
.withPackageName("foo.bar")
|
||||
.withTargetSdk(2)
|
||||
.build();
|
||||
|
||||
assertThat(compatConfig.enableTargetSdkChangesForPackage("foo.bar", 3)).isEqualTo(1);
|
||||
assertThat(compatConfig.isChangeEnabled(3, applicationInfo)).isTrue();
|
||||
assertThat(compatConfig.isChangeEnabled(4, applicationInfo)).isFalse();
|
||||
|
||||
assertThat(compatConfig.disableTargetSdkChangesForPackage("foo.bar", 3)).isEqualTo(1);
|
||||
assertThat(compatConfig.isChangeEnabled(3, applicationInfo)).isFalse();
|
||||
assertThat(compatConfig.isChangeEnabled(4, applicationInfo)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupChangeId() throws Exception {
|
||||
CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
|
||||
|
||||
Reference in New Issue
Block a user