Merge "Add option to toggle all changes" am: 77d832b12d am: 88eb11eab5 am: e2093c1695
Change-Id: I10ca066b5180e3642258d742230e403f157f1149
This commit is contained in:
@@ -163,6 +163,30 @@ interface IPlatformCompat
|
|||||||
*/
|
*/
|
||||||
boolean clearOverride(long changeId, String packageName);
|
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.
|
* 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)
|
final PlatformCompat platformCompat = (PlatformCompat)
|
||||||
ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
|
ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
|
||||||
String toggleValue = getNextArgRequired();
|
String toggleValue = getNextArgRequired();
|
||||||
if (toggleValue.equals("reset-all")) {
|
boolean toggleAll = false;
|
||||||
final String packageName = getNextArgRequired();
|
int targetSdkVersion = -1;
|
||||||
pw.println("Reset all changes for " + packageName + " to default value.");
|
long changeId = -1;
|
||||||
platformCompat.clearOverrides(packageName);
|
|
||||||
return 0;
|
if (toggleValue.endsWith("-all")) {
|
||||||
}
|
toggleValue = toggleValue.substring(0, toggleValue.lastIndexOf("-all"));
|
||||||
long changeId;
|
toggleAll = true;
|
||||||
String changeIdString = getNextArgRequired();
|
if (!toggleValue.equals("reset")) {
|
||||||
try {
|
try {
|
||||||
changeId = Long.parseLong(changeIdString);
|
targetSdkVersion = Integer.parseInt(getNextArgRequired());
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
changeId = platformCompat.lookupChangeId(changeIdString);
|
pw.println("Invalid targetSdkVersion!");
|
||||||
}
|
return -1;
|
||||||
if (changeId == -1) {
|
}
|
||||||
pw.println("Unknown or invalid change: '" + changeIdString + "'.");
|
}
|
||||||
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();
|
String packageName = getNextArgRequired();
|
||||||
if (!platformCompat.isKnownChangeId(changeId)) {
|
if (!toggleAll && !platformCompat.isKnownChangeId(changeId)) {
|
||||||
pw.println("Warning! Change " + changeId + " is not known yet. Enabling/disabling it"
|
pw.println("Warning! Change " + changeId + " is not known yet. Enabling/disabling it"
|
||||||
+ " could have no effect.");
|
+ " could have no effect.");
|
||||||
}
|
}
|
||||||
@@ -2958,22 +2968,49 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
|||||||
try {
|
try {
|
||||||
switch (toggleValue) {
|
switch (toggleValue) {
|
||||||
case "enable":
|
case "enable":
|
||||||
enabled.add(changeId);
|
if (toggleAll) {
|
||||||
CompatibilityChangeConfig overrides =
|
int numChanges = platformCompat.enableTargetSdkChanges(packageName,
|
||||||
new CompatibilityChangeConfig(
|
targetSdkVersion);
|
||||||
new Compatibility.ChangeConfig(enabled, disabled));
|
if (numChanges == 0) {
|
||||||
platformCompat.setOverrides(overrides, packageName);
|
pw.println("No changes were enabled.");
|
||||||
pw.println("Enabled change " + changeId + " for " + packageName + ".");
|
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;
|
return 0;
|
||||||
case "disable":
|
case "disable":
|
||||||
disabled.add(changeId);
|
if (toggleAll) {
|
||||||
overrides =
|
int numChanges = platformCompat.disableTargetSdkChanges(packageName,
|
||||||
new CompatibilityChangeConfig(
|
targetSdkVersion);
|
||||||
new Compatibility.ChangeConfig(enabled, disabled));
|
if (numChanges == 0) {
|
||||||
platformCompat.setOverrides(overrides, packageName);
|
pw.println("No changes were disabled.");
|
||||||
pw.println("Disabled change " + changeId + " for " + packageName + ".");
|
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;
|
return 0;
|
||||||
case "reset":
|
case "reset":
|
||||||
|
if (toggleAll) {
|
||||||
|
platformCompat.clearOverrides(packageName);
|
||||||
|
pw.println("Reset all changes for " + packageName + " to default value.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (platformCompat.clearOverride(changeId, packageName)) {
|
if (platformCompat.clearOverride(changeId, packageName)) {
|
||||||
pw.println("Reset change " + changeId + " for " + packageName
|
pw.println("Reset change " + changeId + " for " + packageName
|
||||||
+ " to default value.");
|
+ " 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(" 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(" 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(" 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(" reset-all <PACKAGE_NAME>");
|
||||||
pw.println(" Removes all existing overrides for all changes for ");
|
pw.println(" Removes all existing overrides for all changes for ");
|
||||||
pw.println(" <PACKAGE_NAME> (back to default behaviour).");
|
pw.println(" <PACKAGE_NAME> (back to default behaviour).");
|
||||||
|
|||||||
@@ -314,6 +314,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 registerListener(long changeId, CompatChange.ChangeListener listener) {
|
||||||
boolean alreadyKnown = true;
|
boolean alreadyKnown = true;
|
||||||
synchronized (mChanges) {
|
synchronized (mChanges) {
|
||||||
|
|||||||
@@ -165,6 +165,26 @@ public class PlatformCompat extends IPlatformCompat.Stub {
|
|||||||
mCompatConfig.addOverrides(overrides, packageName);
|
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
|
@Override
|
||||||
public void clearOverrides(String packageName) throws RemoteException, SecurityException {
|
public void clearOverrides(String packageName) throws RemoteException, SecurityException {
|
||||||
checkCompatChangeOverridePermission();
|
checkCompatChangeOverridePermission();
|
||||||
|
|||||||
@@ -266,6 +266,49 @@ public class CompatConfigTest {
|
|||||||
assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isTrue();
|
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
|
@Test
|
||||||
public void testLookupChangeId() throws Exception {
|
public void testLookupChangeId() throws Exception {
|
||||||
CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
|
CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
|
||||||
|
|||||||
Reference in New Issue
Block a user