summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/compat/CompatChange.java13
-rw-r--r--services/core/java/com/android/server/compat/CompatConfig.java19
-rw-r--r--services/core/java/com/android/server/compat/PlatformCompat.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java39
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);