summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/system-current.txt16
-rw-r--r--core/java/android/app/compat/CompatChanges.java9
-rw-r--r--core/java/android/app/compat/PackageOverride.java49
-rw-r--r--core/java/com/android/internal/compat/CompatibilityOverrideConfig.java5
-rw-r--r--core/java/com/android/internal/compat/IPlatformCompat.aidl14
-rw-r--r--core/res/AndroidManifest.xml7
-rw-r--r--services/core/java/com/android/server/compat/CompatChange.java14
-rw-r--r--services/core/java/com/android/server/compat/CompatConfig.java17
-rw-r--r--services/core/java/com/android/server/compat/OverrideValidatorImpl.java32
-rw-r--r--services/core/java/com/android/server/compat/PlatformCompat.java28
-rw-r--r--services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java45
-rw-r--r--services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java2
13 files changed, 185 insertions, 55 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 761774b373b7..e8bdd41467d9 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -187,6 +187,7 @@ package android {
field public static final String OBSERVE_ROLE_HOLDERS = "android.permission.OBSERVE_ROLE_HOLDERS";
field public static final String OBSERVE_SENSOR_PRIVACY = "android.permission.OBSERVE_SENSOR_PRIVACY";
field public static final String OPEN_ACCESSIBILITY_DETAILS_SETTINGS = "android.permission.OPEN_ACCESSIBILITY_DETAILS_SETTINGS";
+ field public static final String OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD = "android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD";
field public static final String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG";
field public static final String PACKAGE_VERIFICATION_AGENT = "android.permission.PACKAGE_VERIFICATION_AGENT";
field public static final String PACKET_KEEPALIVE_OFFLOAD = "android.permission.PACKET_KEEPALIVE_OFFLOAD";
@@ -1229,6 +1230,21 @@ package android.app.compat {
method public static boolean isChangeEnabled(long);
method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, @NonNull String, @NonNull android.os.UserHandle);
method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, int);
+ method @RequiresPermission(android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD) public static void setPackageOverride(@NonNull String, @NonNull java.util.Map<java.lang.Long,android.app.compat.PackageOverride>);
+ }
+
+ public final class PackageOverride {
+ method public long getMaxVersionCode();
+ method public long getMinVersionCode();
+ method public boolean isEnabled();
+ }
+
+ public static final class PackageOverride.Builder {
+ ctor public PackageOverride.Builder();
+ method @NonNull public android.app.compat.PackageOverride build();
+ method @NonNull public android.app.compat.PackageOverride.Builder setEnabled(boolean);
+ method @NonNull public android.app.compat.PackageOverride.Builder setMaxVersionCode(long);
+ method @NonNull public android.app.compat.PackageOverride.Builder setMinVersionCode(long);
}
}
diff --git a/core/java/android/app/compat/CompatChanges.java b/core/java/android/app/compat/CompatChanges.java
index ab38832458d6..74e1ece3fa89 100644
--- a/core/java/android/app/compat/CompatChanges.java
+++ b/core/java/android/app/compat/CompatChanges.java
@@ -104,16 +104,15 @@ public final class CompatChanges {
*
* @param packageName The package name of the app in question.
* @param overrides A map from changeId to the override applied for this change id.
- * @hide
*/
- @RequiresPermission(android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG)
- public static void setPackageOverride(String packageName,
- Map<Long, PackageOverride> overrides) {
+ @RequiresPermission(android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
+ public static void setPackageOverride(@NonNull String packageName,
+ @NonNull Map<Long, PackageOverride> overrides) {
IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
CompatibilityOverrideConfig config = new CompatibilityOverrideConfig(overrides);
try {
- platformCompat.setOverridesFromInstaller(config, packageName);
+ platformCompat.setOverridesOnReleaseBuilds(config, packageName);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/compat/PackageOverride.java b/core/java/android/app/compat/PackageOverride.java
index 9f97cd41128a..59b355523a30 100644
--- a/core/java/android/app/compat/PackageOverride.java
+++ b/core/java/android/app/compat/PackageOverride.java
@@ -17,8 +17,9 @@
package android.app.compat;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.os.Parcel;
-import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -32,15 +33,16 @@ import java.lang.annotation.RetentionPolicy;
*
* @hide
*/
-public class PackageOverride implements Parcelable {
+@SystemApi
+public final class PackageOverride {
+ /** @hide */
@IntDef({
VALUE_UNDEFINED,
VALUE_ENABLED,
VALUE_DISABLED
})
@Retention(RetentionPolicy.SOURCE)
- /** @hide */
public @interface EvaluatedOverride {
}
@@ -75,10 +77,6 @@ public class PackageOverride implements Parcelable {
this.mEnabled = enabled;
}
- private PackageOverride(Parcel in) {
- this(in.readLong(), in.readLong(), in.readBoolean());
- }
-
/**
* Evaluate the override for the given {@code versionCode}. If no override is defined for
* the specified version code, {@link #VALUE_UNDEFINED} is returned.
@@ -114,25 +112,23 @@ public class PackageOverride implements Parcelable {
}
/** Returns the enabled value for the override. */
- public boolean getEnabled() {
+ public boolean isEnabled() {
return mEnabled;
}
/** @hide */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** @hide */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(Parcel dest) {
dest.writeLong(mMinVersionCode);
dest.writeLong(mMaxVersionCode);
dest.writeBoolean(mEnabled);
}
/** @hide */
+ public static PackageOverride createFromParcel(Parcel in) {
+ return new PackageOverride(in.readLong(), in.readLong(), in.readBoolean());
+ }
+
+ /** @hide */
@Override
public String toString() {
if (mMinVersionCode == Long.MIN_VALUE && mMaxVersionCode == Long.MAX_VALUE) {
@@ -141,25 +137,10 @@ public class PackageOverride implements Parcelable {
return String.format("[%d,%d,%b]", mMinVersionCode, mMaxVersionCode, mEnabled);
}
- /** @hide */
- public static final Creator<PackageOverride> CREATOR =
- new Creator<PackageOverride>() {
-
- @Override
- public PackageOverride createFromParcel(Parcel in) {
- return new PackageOverride(in);
- }
-
- @Override
- public PackageOverride[] newArray(int size) {
- return new PackageOverride[size];
- }
- };
-
/**
* Builder to construct a PackageOverride.
*/
- public static class Builder {
+ public static final class Builder {
private long mMinVersionCode = Long.MIN_VALUE;
private long mMaxVersionCode = Long.MAX_VALUE;
private boolean mEnabled;
@@ -169,6 +150,7 @@ public class PackageOverride implements Parcelable {
*
* default value: {@code Long.MIN_VALUE}.
*/
+ @NonNull
public Builder setMinVersionCode(long minVersionCode) {
mMinVersionCode = minVersionCode;
return this;
@@ -179,6 +161,7 @@ public class PackageOverride implements Parcelable {
*
* default value: {@code Long.MAX_VALUE}.
*/
+ @NonNull
public Builder setMaxVersionCode(long maxVersionCode) {
mMaxVersionCode = maxVersionCode;
return this;
@@ -189,6 +172,7 @@ public class PackageOverride implements Parcelable {
*
* default value: {@code false}.
*/
+ @NonNull
public Builder setEnabled(boolean enabled) {
mEnabled = enabled;
return this;
@@ -200,6 +184,7 @@ public class PackageOverride implements Parcelable {
* @throws IllegalArgumentException if {@code minVersionCode} is larger than
* {@code maxVersionCode}.
*/
+ @NonNull
public PackageOverride build() {
if (mMinVersionCode > mMaxVersionCode) {
throw new IllegalArgumentException("minVersionCode must not be larger than "
diff --git a/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java b/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
index 1c222a73eabc..9a02b7b7aae9 100644
--- a/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
@@ -40,8 +40,7 @@ public final class CompatibilityOverrideConfig implements Parcelable {
overrides = new HashMap<>();
for (int i = 0; i < keyCount; i++) {
long key = in.readLong();
- PackageOverride override = in.readParcelable(PackageOverride.class.getClassLoader());
- overrides.put(key, override);
+ overrides.put(key, PackageOverride.createFromParcel(in));
}
}
@@ -55,7 +54,7 @@ public final class CompatibilityOverrideConfig implements Parcelable {
dest.writeInt(overrides.size());
for (Long key : overrides.keySet()) {
dest.writeLong(key);
- dest.writeParcelable(overrides.get(key), 0);
+ overrides.get(key).writeToParcel(dest);
}
}
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index 249c13402e4f..afcd0b0775a6 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -151,15 +151,23 @@ interface IPlatformCompat {
void setOverrides(in CompatibilityChangeConfig overrides, in String packageName);
/**
- * Adds overrides to compatibility changes.
+ * Adds overrides to compatibility changes on release builds.
*
- * <p>Kills the app to allow the changes to take effect.
+ * <p>The caller to this API needs to hold
+ * {@code android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD} and all change ids
+ * in {@code overrides} need to annotated with {@link android.compat.annotation.Overridable}.
+ *
+ * A release build in this definition means that {@link android.os.Build#IS_DEBUGGABLE} needs to
+ * be {@code false}.
+ *
+ * <p>Note that this does not kill the app, and therefore overrides read from the app process
+ * will not be updated. Overrides read from the system process do 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 setOverridesFromInstaller(in CompatibilityOverrideConfig overrides, in String packageName);
+ void setOverridesOnReleaseBuilds(in CompatibilityOverrideConfig overrides, in String packageName);
/**
* Adds overrides to compatibility changes.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b3b66c48fe6c..90755b96cba3 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5569,10 +5569,17 @@
<permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"
android:protectionLevel="signature|privileged" />
<!-- Allows an app to override compat change config.
+ This permission only allows to override config on debuggable builds or test-apks and is
+ therefore a less powerful version of OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD.
@hide <p>Not for use by third-party applications.</p> -->
<permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"
android:protectionLevel="signature|privileged" />
<uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"/>
+ <!-- @SystemApi Allows an app to override compat change config on release builds.
+ Only ChangeIds that are annotated as @Overridable can be overridden on release builds.
+ @hide -->
+ <permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"
+ android:protectionLevel="signature|privileged" />
<!-- Allows input events to be monitored. Very dangerous! @hide -->
<permission android:name="android.permission.MONITOR_INPUT"
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index ae9b0015de43..d29a0c715e95 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -23,7 +23,9 @@ import static android.app.compat.PackageOverride.VALUE_UNDEFINED;
import android.annotation.Nullable;
import android.app.compat.PackageOverride;
import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
import android.compat.annotation.EnabledSince;
+import android.compat.annotation.Overridable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -60,6 +62,15 @@ public final class CompatChange extends CompatibilityChangeInfo {
static final long CTS_SYSTEM_API_CHANGEID = 149391281; // This is a bug id.
/**
+ * An overridable change ID to be used only in the CTS test for this SystemApi
+ */
+ @ChangeId
+ @Disabled
+ @Overridable
+ static final long CTS_SYSTEM_API_OVERRIDABLE_CHANGEID = 174043039; // This is a bug id.
+
+
+ /**
* Callback listener for when compat changes are updated for a package.
* See {@link #registerListener(ChangeListener)} for more details.
*/
@@ -211,6 +222,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
boolean hasPackageOverride(String pname) {
return mRawOverrides.containsKey(pname);
}
+
/**
* Remove any package override for the given package name, restoring the default behaviour.
*
@@ -355,7 +367,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
override.setPackageName(entry.getKey());
override.setMinVersionCode(entry.getValue().getMinVersionCode());
override.setMaxVersionCode(entry.getValue().getMaxVersionCode());
- override.setEnabled(entry.getValue().getEnabled());
+ override.setEnabled(entry.getValue().isEnabled());
rawList.add(override);
}
changeOverrides.setRaw(rawOverrides);
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index ef86f42d6c3c..55e269630093 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -304,6 +304,16 @@ final class CompatConfig {
}
/**
+ * Returns whether the change is overridable.
+ */
+ boolean isOverridable(long changeId) {
+ synchronized (mChanges) {
+ CompatChange c = mChanges.get(changeId);
+ return c != null && c.getOverridable();
+ }
+ }
+
+ /**
* Removes an override previously added via {@link #addOverride(long, String, boolean)}.
*
* <p>This restores the default behaviour for the given change and app, once any app processes
@@ -343,7 +353,7 @@ final class CompatConfig {
/**
* Removes all overrides previously added via {@link #addOverride(long, String, boolean)} or
- * {@link #addOverrides(CompatibilityChangeConfig, String)} for a certain package.
+ * {@link #addOverrides(CompatibilityOverrideConfig, String)} for a certain package.
*
* <p>This restores the default behaviour for the given app.
*
@@ -632,8 +642,11 @@ final class CompatConfig {
}
boolean shouldInvalidateCache = false;
for (CompatChange c: changes) {
+ if (!c.hasPackageOverride(packageName)) {
+ continue;
+ }
OverrideAllowedState allowedState =
- mOverrideValidator.getOverrideAllowedState(c.getId(), packageName);
+ mOverrideValidator.getOverrideAllowedStateForRecheck(c.getId(), packageName);
shouldInvalidateCache |= c.recheckOverride(packageName, allowedState, mContext);
}
if (shouldInvalidateCache) {
diff --git a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
index aa66a1a8b01f..b5006913af35 100644
--- a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
+++ b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
@@ -16,6 +16,9 @@
package com.android.server.compat;
+import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
import static com.android.internal.compat.OverrideAllowedState.ALLOWED;
import static com.android.internal.compat.OverrideAllowedState.DEFERRED_VERIFICATION;
import static com.android.internal.compat.OverrideAllowedState.DISABLED_NON_TARGET_SDK;
@@ -24,6 +27,7 @@ import static com.android.internal.compat.OverrideAllowedState.DISABLED_TARGET_S
import static com.android.internal.compat.OverrideAllowedState.LOGGING_ONLY_CHANGE;
import static com.android.internal.compat.OverrideAllowedState.PLATFORM_TOO_OLD;
+import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -69,8 +73,25 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub {
mForceNonDebuggableFinalBuild = false;
}
+ /**
+ * Check the allowed state for the given changeId and packageName on a recheck.
+ *
+ * <p>Recheck happens when the given app is getting updated. In this case we cannot do a
+ * permission check on the caller, so we're using the fact that the override was present as
+ * proof that the original caller was allowed to set this override.
+ */
+ OverrideAllowedState getOverrideAllowedStateForRecheck(long changeId,
+ @NonNull String packageName) {
+ return getOverrideAllowedStateInternal(changeId, packageName, true);
+ }
+
@Override
public OverrideAllowedState getOverrideAllowedState(long changeId, String packageName) {
+ return getOverrideAllowedStateInternal(changeId, packageName, false);
+ }
+
+ private OverrideAllowedState getOverrideAllowedStateInternal(long changeId, String packageName,
+ boolean isRecheck) {
if (mCompatConfig.isLoggingOnly(changeId)) {
return new OverrideAllowedState(LOGGING_ONLY_CHANGE, -1, -1);
}
@@ -99,6 +120,16 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub {
} catch (NameNotFoundException e) {
return new OverrideAllowedState(DEFERRED_VERIFICATION, -1, -1);
}
+ // If the change is annotated as @Overridable, apps with the specific permission can
+ // set the override even on production builds. When rechecking the override, e.g. during an
+ // app update we can bypass this check, as it wouldn't have been here in the first place.
+ if (mCompatConfig.isOverridable(changeId)
+ && (isRecheck
+ || mContext.checkCallingOrSelfPermission(
+ OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
+ == PERMISSION_GRANTED)) {
+ return new OverrideAllowedState(ALLOWED, -1, -1);
+ }
int appTargetSdk = applicationInfo.targetSdkVersion;
// Only allow overriding debuggable apps.
if ((applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
@@ -130,5 +161,4 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub {
void forceNonDebuggableFinalForTest(boolean value) {
mForceNonDebuggableFinalBuild = value;
}
-
}
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 2be39aa24294..62de369aeb97 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -18,6 +18,7 @@ package com.android.server.compat;
import static android.Manifest.permission.LOG_COMPAT_CHANGE;
import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
+import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD;
import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Process.SYSTEM_UID;
@@ -182,11 +183,12 @@ public class PlatformCompat extends IPlatformCompat.Stub {
}
@Override
- public void setOverridesFromInstaller(CompatibilityOverrideConfig overrides,
+ public void setOverridesOnReleaseBuilds(CompatibilityOverrideConfig overrides,
String packageName) {
- checkCompatChangeOverridePermission();
+ // TODO(b/183630314): Unify the permission enforcement with the other setOverrides* methods.
+ checkCompatChangeOverrideOverridablePermission();
+ checkAllCompatOverridesAreOverridable(overrides);
mCompatConfig.addOverrides(overrides, packageName);
- killPackage(packageName);
}
@Override
@@ -383,6 +385,26 @@ public class PlatformCompat extends IPlatformCompat.Stub {
}
}
+ private void checkCompatChangeOverrideOverridablePermission() {
+ // Don't check for permissions within the system process
+ if (Binder.getCallingUid() == SYSTEM_UID) {
+ return;
+ }
+ if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
+ != PERMISSION_GRANTED) {
+ throw new SecurityException("Cannot override compat change");
+ }
+ }
+
+ private void checkAllCompatOverridesAreOverridable(CompatibilityOverrideConfig overrides) {
+ for (Long changeId : overrides.overrides.keySet()) {
+ if (!mCompatConfig.isOverridable(changeId)) {
+ throw new SecurityException("Only change ids marked as Overridable can be "
+ + "overridden.");
+ }
+ }
+ }
+
private void checkCompatChangeReadAndLogPermission() {
checkCompatChangeReadPermission();
checkCompatChangeLogPermission();
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
index fcd6b842426a..7bdc87ef6bd7 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
@@ -116,7 +116,7 @@ class CompatConfigBuilder {
}
CompatConfigBuilder addOverridableChangeWithId(long id) {
- mChanges.add(new CompatChange(id, "", -1, -1, false, true, "", true));
+ mChanges.add(new CompatChange(id, "", -1, -1, true, false, "", true));
return this;
}
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
index bd774056aef8..a866363f46e6 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
@@ -260,6 +260,36 @@ public class CompatConfigTest {
}
@Test
+ public void testInstallerCanSetOverrides() throws Exception {
+ final long changeId = 1234L;
+ final int installerUid = 23;
+ CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
+ .addOverridableChangeWithId(1234L)
+ .build();
+ ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
+ .withPackageName("com.some.package")
+ .build();
+ PackageManager packageManager = mock(PackageManager.class);
+ when(mContext.getPackageManager()).thenReturn(packageManager);
+ when(packageManager.getApplicationInfo(eq("com.some.package"), anyInt()))
+ .thenReturn(applicationInfo);
+
+ // Force the validator to prevent overriding the change by using a user build.
+ when(mBuildClassifier.isDebuggableBuild()).thenReturn(false);
+ when(mBuildClassifier.isFinalBuild()).thenReturn(true);
+
+ CompatibilityOverrideConfig config = new CompatibilityOverrideConfig(
+ Collections.singletonMap(1234L,
+ new PackageOverride.Builder()
+ .setMaxVersionCode(99L)
+ .setEnabled(true)
+ .build()));
+
+ compatConfig.addOverrides(config, "com.some.package");
+ assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isTrue();
+ }
+
+ @Test
public void testApplyDeferredOverridesAfterInstallingApp() throws Exception {
ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
.withPackageName("com.notinstalled.foo")
@@ -639,9 +669,18 @@ public class CompatConfigTest {
.build());
when(mPackageManager.getApplicationInfo(eq("bar.baz"), anyInt()))
.thenThrow(new NameNotFoundException());
-
- compatConfig.addOverride(1L, "foo.bar", true);
- compatConfig.addOverride(2L, "bar.baz", false);
+ compatConfig.addOverrides(
+ new CompatibilityOverrideConfig(
+ Collections.singletonMap(
+ 1L,
+ new PackageOverride.Builder().setEnabled(true).build())),
+ "foo.bar");
+ compatConfig.addOverrides(
+ new CompatibilityOverrideConfig(
+ Collections.singletonMap(
+ 2L,
+ new PackageOverride.Builder().setEnabled(false).build())),
+ "bar.baz");
assertThat(readFile(overridesFile)).isEqualTo("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<overrides>\n"
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 3fc6e9918382..a2664e5f3b0a 100644
--- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
@@ -113,7 +113,7 @@ public class PlatformCompatTest {
new CompatibilityChangeInfo(
6L, "", Build.VERSION_CODES.R, -1, false, false, "", false),
new CompatibilityChangeInfo(7L, "", -1, -1, false, true, "", false),
- new CompatibilityChangeInfo(8L, "", -1, -1, false, true, "", true));
+ new CompatibilityChangeInfo(8L, "", -1, -1, true, false, "", true));
}
@Test