diff options
| author | 2022-12-19 22:22:33 +0000 | |
|---|---|---|
| committer | 2022-12-20 15:31:39 +0000 | |
| commit | af9b4e450f64ab92f618ecc090f42e855298024c (patch) | |
| tree | 9c5158d16b427e3fcf36411e62f5cdb2f4568fa0 | |
| parent | dc01f138ce0fecefa1e4e5c63796cde5a21be754 (diff) | |
Expose set/clear monitor callback
Exposing set/clear monitor callback as part of moving rescue party calls to use device config apis instead
of depending on settings.config.
To follow API guildlines: add executor parameter, clear monitor
callback, pass monitorCallback interface instead of passing generic
remote callback function
Test: atest CtsProviderTestCases:android.provider.cts.settings.Settings_ConfigTest#testRegisterMonitorCallback, atest CtsDeviceConfigTestCases:android.deviceconfig.cts.DeviceConfigApiTests#testRegisterMonitorCallback
Bug: 261723248
Change-Id: I40e567a9eb6a4fe3e1d167b1ece909a859f6c2df
| -rw-r--r-- | core/api/module-lib-current.txt | 2 | ||||
| -rw-r--r-- | core/api/system-current.txt | 1 | ||||
| -rw-r--r-- | core/java/android/provider/Settings.java | 81 | ||||
| -rw-r--r-- | core/res/AndroidManifest.xml | 2 | ||||
| -rw-r--r-- | packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java | 15 | ||||
| -rw-r--r-- | packages/Shell/AndroidManifest.xml | 1 | ||||
| -rw-r--r-- | services/core/java/com/android/server/RescueParty.java | 43 | ||||
| -rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java | 134 |
8 files changed, 173 insertions, 106 deletions
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 314fd03a6991..5a8a86a6a795 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -430,6 +430,7 @@ package android.provider { } public static final class Settings.Config extends android.provider.Settings.NameValueTable { + method @RequiresPermission(android.Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS) public static void clearMonitorCallback(@NonNull android.content.ContentResolver); method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean deleteString(@NonNull String, @NonNull String); method @Nullable @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getString(@NonNull String); method @NonNull @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static java.util.Map<java.lang.String,java.lang.String> getStrings(@NonNull String, @NonNull java.util.List<java.lang.String>); @@ -437,6 +438,7 @@ package android.provider { method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean putString(@NonNull String, @NonNull String, @Nullable String, boolean); method public static void registerContentObserver(@Nullable String, boolean, @NonNull android.database.ContentObserver); method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static void resetToDefaults(int, @Nullable String); + method @RequiresPermission(android.Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS) public static void setMonitorCallback(@NonNull android.content.ContentResolver, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.MonitorCallback); method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setStrings(@NonNull String, @NonNull java.util.Map<java.lang.String,java.lang.String>) throws android.provider.DeviceConfig.BadConfigException; method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static void setSyncDisabledMode(int); method public static void unregisterContentObserver(@NonNull android.database.ContentObserver); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 46f51c7bb515..9d96e63a52af 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -212,6 +212,7 @@ package android { field public static final String MODIFY_PARENTAL_CONTROLS = "android.permission.MODIFY_PARENTAL_CONTROLS"; field public static final String MODIFY_QUIET_MODE = "android.permission.MODIFY_QUIET_MODE"; field public static final String MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE = "android.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE"; + field public static final String MONITOR_DEVICE_CONFIG_ACCESS = "android.permission.MONITOR_DEVICE_CONFIG_ACCESS"; field public static final String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE"; field public static final String NETWORK_AIRPLANE_MODE = "android.permission.NETWORK_AIRPLANE_MODE"; field public static final String NETWORK_CARRIER_PROVISIONING = "android.permission.NETWORK_CARRIER_PROVISIONING"; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index d01c33d39cba..efe8238c8a62 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -17,6 +17,7 @@ package android.provider; import android.Manifest; +import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; @@ -87,6 +88,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.MemoryIntArray; +import android.util.Slog; import android.view.Display; import android.view.MotionEvent; import android.view.ViewConfiguration; @@ -112,6 +114,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.Executor; + /** * The Settings provider contains global system-level device preferences. */ @@ -2719,6 +2723,10 @@ public final class Settings { public static final String CALL_METHOD_REGISTER_MONITOR_CALLBACK_CONFIG = "REGISTER_MONITOR_CALLBACK_config"; + /** @hide - Private call() method to unregister monitor callback for 'configuration' table */ + public static final String CALL_METHOD_UNREGISTER_MONITOR_CALLBACK_CONFIG = + "UNREGISTER_MONITOR_CALLBACK_config"; + /** @hide - String argument extra to the config monitor callback */ public static final String EXTRA_MONITOR_CALLBACK_TYPE = "monitor_callback_type"; @@ -18370,16 +18378,41 @@ public final class Settings { } /** - * Register callback for monitoring Config table. + * Setter callback for monitoring Config table. * - * @param callback callback to register + * @param executor the {@link Executor} on which to invoke the callback + * @param callback callback to set * * @hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @RequiresPermission(Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS) + public static void setMonitorCallback( + @NonNull ContentResolver resolver, + @NonNull @CallbackExecutor Executor executor, + @NonNull DeviceConfig.MonitorCallback callback) { + setMonitorCallbackAsUser(executor, resolver, resolver.getUserId(), callback); + } + + /** + * Clear callback for monitoring Config table. + * this may only be used to clear callback function registered by + * {@link Config#setMonitorCallback} + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @RequiresPermission(Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS) - public static void registerMonitorCallback(@NonNull ContentResolver resolver, - @NonNull RemoteCallback callback) { - registerMonitorCallbackAsUser(resolver, resolver.getUserId(), callback); + public static void clearMonitorCallback(@NonNull ContentResolver resolver) { + try { + Bundle arg = new Bundle(); + arg.putInt(CALL_METHOD_USER_KEY, resolver.getUserId()); + IContentProvider cp = sProviderHolder.getProvider(resolver); + cp.call(resolver.getAttributionSource(), + sProviderHolder.mUri.getAuthority(), + CALL_METHOD_UNREGISTER_MONITOR_CALLBACK_CONFIG, null, arg); + } catch (RemoteException e) { + Log.w(TAG, "Can't clear config monitor callback", e); + } } @@ -18446,19 +18479,23 @@ public final class Settings { } } - private static void registerMonitorCallbackAsUser( + private static void setMonitorCallbackAsUser( + @NonNull @CallbackExecutor Executor executor, @NonNull ContentResolver resolver, @UserIdInt int userHandle, - @NonNull RemoteCallback callback) { + @NonNull DeviceConfig.MonitorCallback callback) { try { Bundle arg = new Bundle(); arg.putInt(CALL_METHOD_USER_KEY, userHandle); - arg.putParcelable(CALL_METHOD_MONITOR_CALLBACK_KEY, callback); + arg.putParcelable(CALL_METHOD_MONITOR_CALLBACK_KEY, + new RemoteCallback(result -> { + handleMonitorCallback(result, executor, callback); + })); IContentProvider cp = sProviderHolder.getProvider(resolver); cp.call(resolver.getAttributionSource(), sProviderHolder.mUri.getAuthority(), CALL_METHOD_REGISTER_MONITOR_CALLBACK_CONFIG, null, arg); } catch (RemoteException e) { - Log.w(TAG, "Can't register config monitor callback", e); + Log.w(TAG, "Can't set config monitor callback", e); } } @@ -18468,6 +18505,32 @@ public final class Settings { sNameValueCache.clearGenerationTrackerForTest(); } + private static void handleMonitorCallback( + Bundle result, + @NonNull @CallbackExecutor Executor executor, + DeviceConfig.MonitorCallback monitorCallback) { + String callbackType = result.getString(EXTRA_MONITOR_CALLBACK_TYPE, ""); + switch (callbackType) { + case EXTRA_NAMESPACE_UPDATED_CALLBACK: + String updatedNamespace = result.getString(EXTRA_NAMESPACE); + if (updatedNamespace != null) { + executor.execute(() -> monitorCallback.onNamespaceUpdate(updatedNamespace)); + } + break; + case EXTRA_ACCESS_CALLBACK: + String callingPackage = result.getString(EXTRA_CALLING_PACKAGE, null); + String namespace = result.getString(EXTRA_NAMESPACE, null); + if (namespace != null && callingPackage != null) { + executor.execute(() -> + monitorCallback.onDeviceConfigAccess(callingPackage, namespace)); + } + break; + default: + Slog.w(TAG, "Unrecognized DeviceConfig callback"); + break; + } + } + private static String createCompositeName(@NonNull String namespace, @NonNull String name) { Preconditions.checkNotNull(namespace); Preconditions.checkNotNull(name); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 78a6a666c573..89d5c819ebe3 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3632,7 +3632,7 @@ <permission android:name="android.permission.SET_APP_SPECIFIC_LOCALECONFIG" android:protectionLevel="signature" /> - <!-- @hide Allows an application to monitor {@link android.provider.Settings.Config} access. + <!-- @SystemApi @hide Allows an application to monitor {@link android.provider.Settings.Config} access. <p>Not for use by third-party applications. --> <permission android:name="android.permission.MONITOR_DEVICE_CONFIG_ACCESS" android:protectionLevel="signature"/> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index ed8a457161e1..ed1a0f35f1bf 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -564,6 +564,11 @@ public class SettingsProvider extends ContentProvider { break; } + case Settings.CALL_METHOD_UNREGISTER_MONITOR_CALLBACK_CONFIG: { + clearMonitorCallback(); + break; + } + case Settings.CALL_METHOD_LIST_GLOBAL: { Bundle result = new Bundle(); result.putStringArrayList(RESULT_SETTINGS_LIST, @@ -2352,6 +2357,16 @@ public class SettingsProvider extends ContentProvider { } } + private void clearMonitorCallback() { + getContext().enforceCallingOrSelfPermission( + Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS, + "Permission denial: registering for config access requires: " + + Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS); + synchronized (mLock) { + mConfigMonitorCallback = null; + } + } + private void reportDeviceConfigAccess(@Nullable String prefix) { if (prefix == null) { return; diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index b8ac384cc009..af4d7d46f320 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -145,6 +145,7 @@ <uses-permission android:name="android.permission.LOCATION_BYPASS" /> <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" /> <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" /> + <uses-permission android:name="android.permission.MONITOR_DEVICE_CONFIG_ACCESS" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.MANAGE_ACCESSIBILITY" /> <!-- Development tool permissions granted to the shell. --> diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java index b4ab254b06e7..d1e0f16bd0ae 100644 --- a/services/core/java/com/android/server/RescueParty.java +++ b/services/core/java/com/android/server/RescueParty.java @@ -28,12 +28,10 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; import android.os.Build; -import android.os.Bundle; import android.os.Environment; import android.os.FileUtils; import android.os.PowerManager; import android.os.RecoverySystem; -import android.os.RemoteCallback; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; @@ -63,6 +61,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** @@ -188,9 +187,10 @@ public class RescueParty { public static void onSettingsProviderPublished(Context context) { handleNativeRescuePartyResets(); ContentResolver contentResolver = context.getContentResolver(); - Settings.Config.registerMonitorCallback(contentResolver, new RemoteCallback(result -> { - handleMonitorCallback(context, result); - })); + DeviceConfig.setMonitorCallback( + contentResolver, + Executors.newSingleThreadExecutor(), + new RescuePartyMonitorCallback(context)); } @@ -278,27 +278,22 @@ public class RescueParty { return SystemClock.elapsedRealtime(); } - private static void handleMonitorCallback(Context context, Bundle result) { - String callbackType = result.getString(Settings.EXTRA_MONITOR_CALLBACK_TYPE, ""); - switch (callbackType) { - case Settings.EXTRA_NAMESPACE_UPDATED_CALLBACK: - String updatedNamespace = result.getString(Settings.EXTRA_NAMESPACE); - if (updatedNamespace != null) { - startObservingPackages(context, updatedNamespace); - } - break; - case Settings.EXTRA_ACCESS_CALLBACK: - String callingPackage = result.getString(Settings.EXTRA_CALLING_PACKAGE, null); - String namespace = result.getString(Settings.EXTRA_NAMESPACE, null); - if (namespace != null && callingPackage != null) { - RescuePartyObserver.getInstance(context).recordDeviceConfigAccess( + private static class RescuePartyMonitorCallback implements DeviceConfig.MonitorCallback { + Context mContext; + + RescuePartyMonitorCallback(Context context) { + this.mContext = context; + } + + public void onNamespaceUpdate(@NonNull String updatedNamespace) { + startObservingPackages(mContext, updatedNamespace); + } + + public void onDeviceConfigAccess(@NonNull String callingPackage, + @NonNull String namespace) { + RescuePartyObserver.getInstance(mContext).recordDeviceConfigAccess( callingPackage, namespace); - } - break; - default: - Slog.w(TAG, "Unrecognized DeviceConfig callback"); - break; } } diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java index e7c384b48152..83441bfb8d1e 100644 --- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java @@ -40,9 +40,7 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; -import android.os.Bundle; import android.os.RecoverySystem; -import android.os.RemoteCallback; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.DeviceConfig; @@ -69,6 +67,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.concurrent.Executor; /** * Test RescueParty. @@ -111,7 +110,7 @@ public class RescuePartyTest { private PackageManager mPackageManager; @Captor - private ArgumentCaptor<RemoteCallback> mMonitorCallbackCaptor; + private ArgumentCaptor<DeviceConfig.MonitorCallback> mMonitorCallbackCaptor; @Captor private ArgumentCaptor<List<String>> mPackageListCaptor; @@ -125,7 +124,6 @@ public class RescuePartyTest { .spyStatic(SystemProperties.class) .spyStatic(Settings.Global.class) .spyStatic(Settings.Secure.class) - .spyStatic(Settings.Config.class) .spyStatic(SettingsToPropertiesMapper.class) .spyStatic(RecoverySystem.class) .spyStatic(RescueParty.class) @@ -222,7 +220,8 @@ public class RescuePartyTest { @Test public void testBootLoopDetectionWithExecutionForAllRescueLevels() { RescueParty.onSettingsProviderPublished(mMockContext); - verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), + verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver), + any(Executor.class), mMonitorCallbackCaptor.capture())); HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>(); @@ -233,9 +232,9 @@ public class RescuePartyTest { // Record DeviceConfig accesses RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); - RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue(); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2)); + DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue(); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2); final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2}; @@ -309,25 +308,27 @@ public class RescuePartyTest { @Test public void testNonPersistentAppCrashDetectionWithScopedResets() { RescueParty.onSettingsProviderPublished(mMockContext); - verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), + verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver), + any(Executor.class), mMonitorCallbackCaptor.capture())); // Record DeviceConfig accesses RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); - RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue(); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE2)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3)); + DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue(); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE2); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE3); + // Fake DeviceConfig value changes - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1)); + monitorCallback.onNamespaceUpdate(NAMESPACE1); verify(mMockPackageWatchdog).startObservingHealth(observer, Arrays.asList(CALLING_PACKAGE1), RescueParty.DEFAULT_OBSERVING_DURATION_MS); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2)); + monitorCallback.onNamespaceUpdate(NAMESPACE2); verify(mMockPackageWatchdog, times(2)).startObservingHealth(eq(observer), mPackageListCaptor.capture(), eq(RescueParty.DEFAULT_OBSERVING_DURATION_MS)); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3)); + monitorCallback.onNamespaceUpdate(NAMESPACE3); verify(mMockPackageWatchdog).startObservingHealth(observer, Arrays.asList(CALLING_PACKAGE2), RescueParty.DEFAULT_OBSERVING_DURATION_MS); assertTrue(mPackageListCaptor.getValue().containsAll( @@ -364,20 +365,21 @@ public class RescuePartyTest { @Test public void testNonDeviceConfigSettingsOnlyResetOncePerLevel() { RescueParty.onSettingsProviderPublished(mMockContext); - verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), + verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver), + any(Executor.class), mMonitorCallbackCaptor.capture())); // Record DeviceConfig accesses RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); - RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue(); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE2)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3)); + DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue(); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE2); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE3); // Fake DeviceConfig value changes - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1)); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2)); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3)); + monitorCallback.onNamespaceUpdate(NAMESPACE1); + monitorCallback.onNamespaceUpdate(NAMESPACE2); + monitorCallback.onNamespaceUpdate(NAMESPACE3); // Perform and verify scoped resets final String[] expectedPackage1ResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2}; final String[] expectedPackage2ResetNamespaces = new String[]{NAMESPACE2, NAMESPACE3}; @@ -549,20 +551,21 @@ public class RescuePartyTest { @Test public void testResetDeviceConfigForPackagesOnlyRuntimeMap() { RescueParty.onSettingsProviderPublished(mMockContext); - verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), + verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver), + any(Executor.class), mMonitorCallbackCaptor.capture())); // Record DeviceConfig accesses RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); - RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue(); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE2)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3)); + DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue(); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE2); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE3); // Fake DeviceConfig value changes - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1)); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2)); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3)); + monitorCallback.onNamespaceUpdate(NAMESPACE1); + monitorCallback.onNamespaceUpdate(NAMESPACE2); + monitorCallback.onNamespaceUpdate(NAMESPACE3); doReturn("").when(() -> DeviceConfig.getString( eq(RescueParty.NAMESPACE_CONFIGURATION), @@ -578,7 +581,8 @@ public class RescuePartyTest { @Test public void testResetDeviceConfigForPackagesOnlyPresetMap() { RescueParty.onSettingsProviderPublished(mMockContext); - verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), + verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver), + any(Executor.class), mMonitorCallbackCaptor.capture())); String presetMapping = NAMESPACE1 + ":" + CALLING_PACKAGE1 + "," @@ -598,22 +602,23 @@ public class RescuePartyTest { @Test public void testResetDeviceConfigForPackagesBothMaps() { RescueParty.onSettingsProviderPublished(mMockContext); - verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), + verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver), + any(Executor.class), mMonitorCallbackCaptor.capture())); // Record DeviceConfig accesses RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); - RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue(); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE2)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE3, NAMESPACE4)); + DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue(); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE2); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE3); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE3, NAMESPACE4); // Fake DeviceConfig value changes - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1)); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2)); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3)); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE4)); + monitorCallback.onNamespaceUpdate(NAMESPACE1); + monitorCallback.onNamespaceUpdate(NAMESPACE2); + monitorCallback.onNamespaceUpdate(NAMESPACE3); + monitorCallback.onNamespaceUpdate(NAMESPACE4); String presetMapping = NAMESPACE1 + ":" + CALLING_PACKAGE1 + "," + NAMESPACE2 + ":" + CALLING_PACKAGE2 + "," @@ -633,20 +638,21 @@ public class RescuePartyTest { @Test public void testResetDeviceConfigNoExceptionWhenFlagMalformed() { RescueParty.onSettingsProviderPublished(mMockContext); - verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), + verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver), + any(Executor.class), mMonitorCallbackCaptor.capture())); // Record DeviceConfig accesses RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); - RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue(); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3)); - monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE3, NAMESPACE4)); + DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue(); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE3); + monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE3, NAMESPACE4); // Fake DeviceConfig value changes - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1)); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2)); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3)); - monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE4)); + monitorCallback.onNamespaceUpdate(NAMESPACE1); + monitorCallback.onNamespaceUpdate(NAMESPACE2); + monitorCallback.onNamespaceUpdate(NAMESPACE3); + monitorCallback.onNamespaceUpdate(NAMESPACE4); String invalidPresetMapping = NAMESPACE2 + ":" + CALLING_PACKAGE2 + "," + NAMESPACE1 + "." + CALLING_PACKAGE2; @@ -696,20 +702,4 @@ public class RescuePartyTest { RescuePartyObserver.getInstance(mMockContext).execute(new VersionedPackage( packageName, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH, mitigationCount); } - - private Bundle getConfigAccessBundle(String callingPackage, String namespace) { - Bundle result = new Bundle(); - result.putString(Settings.EXTRA_MONITOR_CALLBACK_TYPE, Settings.EXTRA_ACCESS_CALLBACK); - result.putString(Settings.EXTRA_CALLING_PACKAGE, callingPackage); - result.putString(Settings.EXTRA_NAMESPACE, namespace); - return result; - } - - private Bundle getConfigNamespaceUpdateBundle(String updatedNamespace) { - Bundle result = new Bundle(); - result.putString(Settings.EXTRA_MONITOR_CALLBACK_TYPE, - Settings.EXTRA_NAMESPACE_UPDATED_CALLBACK); - result.putString(Settings.EXTRA_NAMESPACE, updatedNamespace); - return result; - } } |