diff options
4 files changed, 74 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java index c4ff99bae694..18907a19f96d 100644 --- a/services/core/java/com/android/server/compat/CompatChange.java +++ b/services/core/java/com/android/server/compat/CompatChange.java @@ -213,6 +213,19 @@ public final class CompatChange extends CompatibilityChangeInfo { } /** + * Find if this change will be enabled for the given package after installation. + * + * @param packageName The package name in question + * @return {@code true} if the change should be enabled for the package. + */ + boolean willBeEnabled(String packageName) { + if (hasDeferredOverride(packageName)) { + return mDeferredOverrides.get(packageName); + } + return defaultValue(); + } + + /** * Returns the default value for the change id, assuming there are no overrides. * * @return {@code false} if it's a default disabled change, {@code true} otherwise. diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index f03a608232a2..9376e8dc16ea 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -146,6 +146,25 @@ final class CompatConfig { } /** + * Find if a given change will be enabled for a given package name, prior to installation. + * + * @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. + */ + boolean willChangeBeEnabled(long changeId, String packageName) { + synchronized (mChanges) { + CompatChange c = mChanges.get(changeId); + if (c == null) { + // we know nothing about this change: default behaviour is enabled. + return true; + } + return c.willBeEnabled(packageName); + } + } + + /** * 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. diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 283dba7aff8a..1ea468c341d2 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -137,6 +137,9 @@ public class PlatformCompat extends IPlatformCompat.Stub { @UserIdInt int userId) { checkCompatChangeReadAndLogPermission(); ApplicationInfo appInfo = getApplicationInfo(packageName, userId); + if (appInfo == null) { + return mCompatConfig.willChangeBeEnabled(changeId, packageName); + } return isChangeEnabled(changeId, appInfo); } diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java index 3f65a4621778..a70c51045340 100644 --- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java +++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.when; import static org.mockito.internal.verification.VerificationModeFactory.times; import static org.testng.Assert.assertThrows; +import android.compat.Compatibility.ChangeConfig; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; @@ -35,6 +36,7 @@ import android.os.Build; import androidx.test.runner.AndroidJUnit4; import com.android.internal.compat.AndroidBuildClassifier; +import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.compat.CompatibilityChangeInfo; import com.android.server.LocalServices; @@ -44,6 +46,9 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.HashSet; +import java.util.Set; + @RunWith(AndroidJUnit4.class) public class PlatformCompatTest { private static final String PACKAGE_NAME = "my.package"; @@ -70,6 +75,8 @@ public class PlatformCompatTest { new PackageManager.NameNotFoundException()); when(mPackageManagerInternal.getPackageUid(eq(PACKAGE_NAME), eq(0), anyInt())) .thenReturn(-1); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenThrow(new PackageManager.NameNotFoundException()); mCompatConfig = new CompatConfig(mBuildClassifier, mContext); mPlatformCompat = new PlatformCompat(mContext, mCompatConfig); // Assume userdebug/eng non-final build @@ -125,6 +132,38 @@ public class PlatformCompatTest { } @Test + public void testOverrideAtInstallTime() throws Exception { + mCompatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addEnabledChangeWithId(1L) + .addDisabledChangeWithId(2L) + .addEnableAfterSdkChangeWithId(Build.VERSION_CODES.O, 3L) + .build(); + mCompatConfig.forceNonDebuggableFinalForTest(true); + mPlatformCompat = new PlatformCompat(mContext, mCompatConfig); + + // Before adding overrides. + assertThat(mPlatformCompat.isChangeEnabledByPackageName(1, PACKAGE_NAME, 0)).isTrue(); + assertThat(mPlatformCompat.isChangeEnabledByPackageName(2, PACKAGE_NAME, 0)).isFalse(); + assertThat(mPlatformCompat.isChangeEnabledByPackageName(3, PACKAGE_NAME, 0)).isTrue(); + + // Add overrides. + Set<Long> enabled = new HashSet<>(); + enabled.add(2L); + Set<Long> disabled = new HashSet<>(); + disabled.add(1L); + disabled.add(3L); + ChangeConfig changeConfig = new ChangeConfig(enabled, disabled); + CompatibilityChangeConfig compatibilityChangeConfig = + new CompatibilityChangeConfig(changeConfig); + mPlatformCompat.setOverridesForTest(compatibilityChangeConfig, PACKAGE_NAME); + + // After adding overrides. + assertThat(mPlatformCompat.isChangeEnabledByPackageName(1, PACKAGE_NAME, 0)).isFalse(); + assertThat(mPlatformCompat.isChangeEnabledByPackageName(2, PACKAGE_NAME, 0)).isTrue(); + assertThat(mPlatformCompat.isChangeEnabledByPackageName(3, PACKAGE_NAME, 0)).isFalse(); + } + + @Test public void testRegisterListenerToSameIdThrows() throws Exception { // Registering a listener to change 1 is successful. mPlatformCompat.registerListener(1, mListener1); |