diff options
10 files changed, 265 insertions, 30 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 300bb7603722..1e14e3a4a701 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -13283,6 +13283,16 @@ public final class Settings { @TestApi public static final String HIDDEN_API_POLICY = "hidden_api_policy"; + /** + * Flag for forcing {@link com.android.server.compat.OverrideValidatorImpl} + * to consider this a non-debuggable build. + * + * @hide + */ + public static final String FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT = + "force_non_debuggable_final_build_for_compat"; + + /** * Current version of signed configuration applied. * diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index e90bb36214a8..5ecb17102438 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -300,6 +300,7 @@ public class SettingsBackupTest { Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, Settings.Global.HIDDEN_API_POLICY, + Settings.Global.FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT, Settings.Global.HIDE_ERROR_DIALOGS, Settings.Global.HTTP_PROXY, HYBRID_SYSUI_BATTERY_WARNING_FLAGS, diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index e4cdfe92ec8a..8cf9f6fa5afb 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -9481,6 +9481,7 @@ public class ActivityManagerService extends IActivityManager.Stub final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver, NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS); mHiddenApiBlacklist.registerObserver(); + mPlatformCompat.registerContentObserver(); final long pssDeferralMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, ACTIVITY_START_PSS_DEFER_CONFIG, 0L); diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index 1cbaa1e3451e..f03a608232a2 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -65,7 +65,7 @@ final class CompatConfig { @GuardedBy("mChanges") private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>(); - private IOverrideValidator mOverrideValidator; + private OverrideValidatorImpl mOverrideValidator; @VisibleForTesting CompatConfig(AndroidBuildClassifier androidBuildClassifier, Context context) { @@ -161,7 +161,7 @@ final class CompatConfig { * @return {@code true} if the change existed before adding the override. */ boolean addOverride(long changeId, String packageName, boolean enabled) - throws RemoteException, SecurityException { + throws SecurityException { boolean alreadyKnown = true; OverrideAllowedState allowedState = mOverrideValidator.getOverrideAllowedState(changeId, packageName); @@ -254,7 +254,7 @@ final class CompatConfig { * @return {@code true} if an override existed; */ boolean removeOverride(long changeId, String packageName) - throws RemoteException, SecurityException { + throws SecurityException { boolean overrideExists = false; synchronized (mChanges) { CompatChange c = mChanges.get(changeId); @@ -307,7 +307,7 @@ final class CompatConfig { * * @param packageName The package for which the overrides should be purged. */ - void removePackageOverrides(String packageName) throws RemoteException, SecurityException { + void removePackageOverrides(String packageName) throws SecurityException { synchronized (mChanges) { for (int i = 0; i < mChanges.size(); ++i) { CompatChange change = mChanges.valueAt(i); @@ -323,20 +323,15 @@ final class CompatConfig { LongArray allowed = new LongArray(); synchronized (mChanges) { for (int i = 0; i < mChanges.size(); ++i) { - try { - CompatChange change = mChanges.valueAt(i); - if (change.getEnableSinceTargetSdk() != 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 AssertionError("Unable to call override validator!", e); + CompatChange change = mChanges.valueAt(i); + if (change.getEnableSinceTargetSdk() != targetSdkVersion) { + continue; + } + OverrideAllowedState allowedState = + mOverrideValidator.getOverrideAllowedState(change.getId(), + packageName); + if (allowedState.state == OverrideAllowedState.ALLOWED) { + allowed.add(change.getId()); } } } @@ -397,6 +392,11 @@ final class CompatConfig { } @VisibleForTesting + void forceNonDebuggableFinalForTest(boolean value) { + mOverrideValidator.forceNonDebuggableFinalForTest(value); + } + + @VisibleForTesting void clearChanges() { synchronized (mChanges) { mChanges.clear(); @@ -515,19 +515,18 @@ final class CompatConfig { boolean shouldInvalidateCache = false; for (int idx = 0; idx < mChanges.size(); ++idx) { CompatChange c = mChanges.valueAt(idx); - try { - OverrideAllowedState allowedState = - mOverrideValidator.getOverrideAllowedState(c.getId(), packageName); - boolean allowedOverride = (allowedState.state == OverrideAllowedState.ALLOWED); - shouldInvalidateCache |= c.recheckOverride(packageName, allowedOverride); - } catch (RemoteException e) { - // Should never occur, since validator is in the same process. - throw new AssertionError("Unable to call override validator!", e); - } + OverrideAllowedState allowedState = + mOverrideValidator.getOverrideAllowedState(c.getId(), packageName); + boolean allowedOverride = (allowedState.state == OverrideAllowedState.ALLOWED); + shouldInvalidateCache |= c.recheckOverride(packageName, allowedOverride); } if (shouldInvalidateCache) { invalidateCache(); } } } + + void registerContentObserver() { + mOverrideValidator.registerContentObserver(); + } } diff --git a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java index 58250407b864..fe5b4a98797d 100644 --- a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java +++ b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java @@ -27,6 +27,9 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.database.ContentObserver; +import android.os.Handler; +import android.provider.Settings; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.compat.AndroidBuildClassifier; @@ -41,6 +44,20 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub { private AndroidBuildClassifier mAndroidBuildClassifier; private Context mContext; private CompatConfig mCompatConfig; + private boolean mForceNonDebuggableFinalBuild; + + private class SettingsObserver extends ContentObserver { + SettingsObserver() { + super(new Handler()); + } + @Override + public void onChange(boolean selfChange) { + mForceNonDebuggableFinalBuild = Settings.Global.getInt( + mContext.getContentResolver(), + Settings.Global.FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT, + 0) == 1; + } + } @VisibleForTesting OverrideValidatorImpl(AndroidBuildClassifier androidBuildClassifier, @@ -48,6 +65,7 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub { mAndroidBuildClassifier = androidBuildClassifier; mContext = context; mCompatConfig = config; + mForceNonDebuggableFinalBuild = false; } @Override @@ -56,8 +74,10 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub { return new OverrideAllowedState(LOGGING_ONLY_CHANGE, -1, -1); } - boolean debuggableBuild = mAndroidBuildClassifier.isDebuggableBuild(); - boolean finalBuild = mAndroidBuildClassifier.isFinalBuild(); + boolean debuggableBuild = mAndroidBuildClassifier.isDebuggableBuild() + && !mForceNonDebuggableFinalBuild; + boolean finalBuild = mAndroidBuildClassifier.isFinalBuild() + || mForceNonDebuggableFinalBuild; int maxTargetSdk = mCompatConfig.maxTargetSdkForChangeIdOptIn(changeId); boolean disabled = mCompatConfig.isDisabled(changeId); @@ -94,4 +114,17 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub { } return new OverrideAllowedState(DISABLED_TARGET_SDK_TOO_HIGH, appTargetSdk, maxTargetSdk); } + + void registerContentObserver() { + mContext.getContentResolver().registerContentObserver( + Settings.Global.getUriFor( + Settings.Global.FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT), + false, + new SettingsObserver()); + } + + 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 fada37bce82c..283dba7aff8a 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -424,4 +424,12 @@ public class PlatformCompat extends IPlatformCompat.Stub { filter.addDataScheme("package"); context.registerReceiver(receiver, filter); } + + /** + * Register the observer for + * {@link android.provider.Settings.Global#FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT} + */ + public void registerContentObserver() { + mCompatConfig.registerContentObserver(); + } } 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 870fe4a0837e..4f4aa3f16f09 100644 --- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java +++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java @@ -117,6 +117,7 @@ class CompatConfigBuilder { CompatConfig build() { CompatConfig config = new CompatConfig(mBuildClassifier, mContext); + config.forceNonDebuggableFinalForTest(false); for (CompatChange change : mChanges) { config.addChange(change); } 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 6cb2dbc7cbff..ac8dc341999a 100644 --- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java @@ -82,6 +82,8 @@ public class CompatConfigTest { @Test public void testUnknownChangeEnabled() throws Exception { CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext); + compatConfig.forceNonDebuggableFinalForTest(false); + assertThat(compatConfig.isChangeEnabled(1234L, ApplicationInfoBuilder.create().build())) .isTrue(); } @@ -181,6 +183,8 @@ public class CompatConfigTest { @Test public void testPackageOverrideUnknownPackage() throws Exception { CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext); + compatConfig.forceNonDebuggableFinalForTest(false); + compatConfig.addOverride(1234L, "com.some.package", false); @@ -438,6 +442,8 @@ public class CompatConfigTest { @Test public void testLookupChangeIdNotPresent() throws Exception { CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext); + compatConfig.forceNonDebuggableFinalForTest(false); + assertThat(compatConfig.lookupChangeId("MY_CHANGE")).isEqualTo(-1L); } @@ -452,6 +458,8 @@ public class CompatConfigTest { File dir = createTempDir(); writeToFile(dir, "platform_compat_config.xml", configXml); CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext); + compatConfig.forceNonDebuggableFinalForTest(false); + compatConfig.initConfigFromLib(dir); assertThat(compatConfig.isChangeEnabled(1234L, @@ -478,6 +486,8 @@ public class CompatConfigTest { writeToFile(dir, "libcore_platform_compat_config.xml", configXml1); writeToFile(dir, "frameworks_platform_compat_config.xml", configXml2); CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext); + compatConfig.forceNonDebuggableFinalForTest(false); + compatConfig.initConfigFromLib(dir); assertThat(compatConfig.isChangeEnabled(1234L, diff --git a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java index 019c615fed38..0fd6445fbeeb 100644 --- a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java +++ b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java @@ -34,7 +34,6 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; - import androidx.test.runner.AndroidJUnit4; import com.android.internal.compat.AndroidBuildClassifier; @@ -452,4 +451,176 @@ public class OverrideValidatorImplTest { assertThat(stateDLoggingOnlyChange) .isEqualTo(new OverrideAllowedState(LOGGING_ONLY_CHANGE, -1, -1)); } + + @Test + public void getOverrideAllowedState_forceFinalBuildTargetSdkChangeDebugAppOptin_allowOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(debuggableBuild(), mContext) + .addEnableAfterSdkChangeWithId(TARGET_SDK_AFTER, 1) + .addEnableAfterSdkChangeWithId(TARGET_SDK, 2).build(); + config.forceNonDebuggableFinalForTest(true); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .debuggable() + .withTargetSdk(TARGET_SDK) + .withPackageName(PACKAGE_NAME).build()); + + OverrideAllowedState stateTargetSdkGreaterChange = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkEqualChange = + overrideValidator.getOverrideAllowedState(2, PACKAGE_NAME); + + assertThat(stateTargetSdkGreaterChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, TARGET_SDK, TARGET_SDK_AFTER)); + + assertThat(stateTargetSdkEqualChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, TARGET_SDK, TARGET_SDK)); + } + + @Test + public void getOverrideAllowedState_forceFinalBldTargetSdkChangeDebugAppOptout_rejectOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(debuggableBuild(), mContext) + .addEnableAfterSdkChangeWithId(TARGET_SDK_BEFORE, 1).build(); + config.forceNonDebuggableFinalForTest(true); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .withPackageName(PACKAGE_NAME) + .withTargetSdk(TARGET_SDK) + .debuggable() + .build()); + + OverrideAllowedState stateTargetSdkLessChange = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + + assertThat(stateTargetSdkLessChange).isEqualTo( + new OverrideAllowedState(DISABLED_TARGET_SDK_TOO_HIGH, TARGET_SDK, + TARGET_SDK_BEFORE)); + } + + @Test + public void getOverrideAllowedState_forceFinalBuildEnabledChangeDebugApp_rejectOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(debuggableBuild(), mContext) + .addEnabledChangeWithId(1).build(); + config.forceNonDebuggableFinalForTest(true); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .withPackageName(PACKAGE_NAME) + .debuggable().build()); + + OverrideAllowedState allowedState = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + + assertThat(allowedState) + .isEqualTo(new OverrideAllowedState(DISABLED_NON_TARGET_SDK, -1, -1)); + } + + @Test + public void getOverrideAllowedState_forceFinalBuildDisabledChangeDebugApp_allowOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(debuggableBuild(), mContext) + .addDisabledChangeWithId(1).build(); + config.forceNonDebuggableFinalForTest(true); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .withPackageName(PACKAGE_NAME) + .withTargetSdk(TARGET_SDK) + .debuggable().build()); + + OverrideAllowedState allowedState = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + + assertThat(allowedState) + .isEqualTo(new OverrideAllowedState(ALLOWED, TARGET_SDK, -1)); + } + + @Test + public void getOverrideAllowedState_forceFinalBuildAnyChangeReleaseApp_rejectOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(debuggableBuild(), mContext) + .addEnableAfterSdkChangeWithId(TARGET_SDK_BEFORE, 1) + .addEnableAfterSdkChangeWithId(TARGET_SDK, 2) + .addEnableAfterSdkChangeWithId(TARGET_SDK_AFTER, 3) + .addEnabledChangeWithId(4) + .addDisabledChangeWithId(5) + .addLoggingOnlyChangeWithId(6).build(); + config.forceNonDebuggableFinalForTest(true); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .withPackageName(PACKAGE_NAME) + .withTargetSdk(TARGET_SDK).build()); + + OverrideAllowedState stateTargetSdkLessChange = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkEqualChange = + overrideValidator.getOverrideAllowedState(2, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkAfterChange = + overrideValidator.getOverrideAllowedState(3, PACKAGE_NAME); + OverrideAllowedState stateEnabledChange = + overrideValidator.getOverrideAllowedState(4, PACKAGE_NAME); + OverrideAllowedState stateDisabledChange = + overrideValidator.getOverrideAllowedState(5, PACKAGE_NAME); + OverrideAllowedState stateDLoggingOnlyChange = + overrideValidator.getOverrideAllowedState(6, PACKAGE_NAME); + + assertThat(stateTargetSdkLessChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateTargetSdkEqualChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateTargetSdkAfterChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateEnabledChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateDisabledChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateDLoggingOnlyChange) + .isEqualTo(new OverrideAllowedState(LOGGING_ONLY_CHANGE, -1, -1)); + } + @Test + public void getOverrideAllowedState_forceFinalBuildAnyChangeNotInstalledApp_deferOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(debuggableBuild(), mContext) + .addEnableAfterSdkChangeWithId(TARGET_SDK_BEFORE, 1) + .addEnableAfterSdkChangeWithId(TARGET_SDK, 2) + .addEnableAfterSdkChangeWithId(TARGET_SDK_AFTER, 3) + .addEnabledChangeWithId(4) + .addDisabledChangeWithId(5) + .addLoggingOnlyChangeWithId(6).build(); + config.forceNonDebuggableFinalForTest(true); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenThrow(new NameNotFoundException()); + + OverrideAllowedState stateTargetSdkLessChange = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkEqualChange = + overrideValidator.getOverrideAllowedState(2, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkAfterChange = + overrideValidator.getOverrideAllowedState(3, PACKAGE_NAME); + OverrideAllowedState stateEnabledChange = + overrideValidator.getOverrideAllowedState(4, PACKAGE_NAME); + OverrideAllowedState stateDisabledChange = + overrideValidator.getOverrideAllowedState(5, PACKAGE_NAME); + OverrideAllowedState stateDLoggingOnlyChange = + overrideValidator.getOverrideAllowedState(6, PACKAGE_NAME); + + assertThat(stateTargetSdkLessChange) + .isEqualTo(new OverrideAllowedState(DEFERRED_VERIFICATION, -1, -1)); + assertThat(stateTargetSdkEqualChange) + .isEqualTo(new OverrideAllowedState(DEFERRED_VERIFICATION, -1, -1)); + assertThat(stateTargetSdkAfterChange) + .isEqualTo(new OverrideAllowedState(DEFERRED_VERIFICATION, -1, -1)); + assertThat(stateEnabledChange) + .isEqualTo(new OverrideAllowedState(DEFERRED_VERIFICATION, -1, -1)); + assertThat(stateDisabledChange) + .isEqualTo(new OverrideAllowedState(DEFERRED_VERIFICATION, -1, -1)); + assertThat(stateDLoggingOnlyChange) + .isEqualTo(new OverrideAllowedState(LOGGING_ONLY_CHANGE, -1, -1)); + } } 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 1d3b643ba83f..3f65a4621778 100644 --- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java +++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java @@ -73,6 +73,7 @@ public class PlatformCompatTest { mCompatConfig = new CompatConfig(mBuildClassifier, mContext); mPlatformCompat = new PlatformCompat(mContext, mCompatConfig); // Assume userdebug/eng non-final build + mCompatConfig.forceNonDebuggableFinalForTest(false); when(mBuildClassifier.isDebuggableBuild()).thenReturn(true); when(mBuildClassifier.isFinalBuild()).thenReturn(false); LocalServices.removeServiceForTest(PackageManagerInternal.class); |