Create a new permission to override Overridable change ids
With this change we allow system packages with the new permission to override ChangeIds specifically annotated as Overridable to set overrides even on non-debuggable builds. Bug: 174043039 Bug: 175874108 CTS-Coverage-Bug: 180396382 Test: atest FrameworksServicesTests:CompatConfigTest Test: atest FrameworksServicesTests:PlatformCompatTest Change-Id: Ib8d5d83b5fd62acb5808d10f5c413616f29ee65c
This commit is contained in:
@@ -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";
|
||||
@@ -1227,6 +1228,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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,24 +112,22 @@ 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() {
|
||||
@@ -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 "
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -5560,10 +5560,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"
|
||||
|
||||
@@ -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;
|
||||
@@ -59,6 +61,15 @@ public final class CompatChange extends CompatibilityChangeInfo {
|
||||
@EnabledSince(targetSdkVersion = 31) // Needs to be > test APK targetSdkVersion.
|
||||
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);
|
||||
|
||||
@@ -303,6 +303,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)}.
|
||||
*
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -259,6 +259,36 @@ public class CompatConfigTest {
|
||||
assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isFalse();
|
||||
}
|
||||
|
||||
@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()
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user