diff options
5 files changed, 201 insertions, 90 deletions
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig index 049ad20fd992..294e5da1edd1 100644 --- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig +++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig @@ -233,6 +233,16 @@ flag { } flag { + name: "restore_a11y_secure_settings_on_hsum_device" + namespace: "accessibility" + description: "Grab the a11y settings and send the settings restored broadcast for current visible foreground user" + bug: "381294327" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "supplemental_description" namespace: "accessibility" description: "Feature flag for supplemental description api" diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java index 9bbb509f323a..924c151a99a0 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java @@ -101,21 +101,26 @@ public class SettingsHelper { */ private static final ArraySet<String> sBroadcastOnRestore; private static final ArraySet<String> sBroadcastOnRestoreSystemUI; + private static final ArraySet<String> sBroadcastOnRestoreAccessibility; static { - sBroadcastOnRestore = new ArraySet<String>(12); + sBroadcastOnRestore = new ArraySet<>(7); sBroadcastOnRestore.add(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS); sBroadcastOnRestore.add(Settings.Secure.ENABLED_VR_LISTENERS); - sBroadcastOnRestore.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); sBroadcastOnRestore.add(Settings.Global.BLUETOOTH_ON); sBroadcastOnRestore.add(Settings.Secure.UI_NIGHT_MODE); sBroadcastOnRestore.add(Settings.Secure.DARK_THEME_CUSTOM_START_TIME); sBroadcastOnRestore.add(Settings.Secure.DARK_THEME_CUSTOM_END_TIME); - sBroadcastOnRestore.add(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED); - sBroadcastOnRestore.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); - sBroadcastOnRestore.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS); - sBroadcastOnRestore.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); sBroadcastOnRestore.add(Settings.Secure.SCREEN_RESOLUTION_MODE); - sBroadcastOnRestoreSystemUI = new ArraySet<String>(2); + + sBroadcastOnRestoreAccessibility = new ArraySet<>(5); + sBroadcastOnRestoreAccessibility.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); + sBroadcastOnRestoreAccessibility.add( + Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED); + sBroadcastOnRestoreAccessibility.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); + sBroadcastOnRestoreAccessibility.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS); + sBroadcastOnRestoreAccessibility.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); + + sBroadcastOnRestoreSystemUI = new ArraySet<>(2); sBroadcastOnRestoreSystemUI.add(Settings.Secure.QS_TILES); sBroadcastOnRestoreSystemUI.add(Settings.Secure.QS_AUTO_ADDED_TILES); } @@ -188,6 +193,7 @@ public class SettingsHelper { String oldValue = null; boolean sendBroadcast = false; boolean sendBroadcastSystemUI = false; + boolean sendBroadcastAccessibility = false; final SettingsLookup table; if (destination.equals(Settings.Secure.CONTENT_URI)) { @@ -200,6 +206,7 @@ public class SettingsHelper { sendBroadcast = sBroadcastOnRestore.contains(name); sendBroadcastSystemUI = sBroadcastOnRestoreSystemUI.contains(name); + sendBroadcastAccessibility = sBroadcastOnRestoreAccessibility.contains(name); if (sendBroadcast) { // TODO: http://b/22388012 @@ -209,6 +216,10 @@ public class SettingsHelper { // It would probably be correct to do it for the ones sent to the system, but consumers // may be depending on the current behavior. oldValue = table.lookup(cr, name, context.getUserId()); + } else if (sendBroadcastAccessibility) { + int userId = android.view.accessibility.Flags.restoreA11ySecureSettingsOnHsumDevice() + ? context.getUserId() : UserHandle.USER_SYSTEM; + oldValue = table.lookup(cr, name, userId); } try { @@ -251,11 +262,7 @@ public class SettingsHelper { } else if (Settings.System.ACCELEROMETER_ROTATION.equals(name) && shouldSkipAutoRotateRestore()) { return; - } else if (Settings.Secure.ACCESSIBILITY_QS_TARGETS.equals(name)) { - // Don't write it to setting. Let the broadcast receiver in - // AccessibilityManagerService handle restore/merging logic. - return; - } else if (Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE.equals(name)) { + } else if (shouldSkipAndLetBroadcastHandlesRestoreLogic(name)) { // Don't write it to setting. Let the broadcast receiver in // AccessibilityManagerService handle restore/merging logic. return; @@ -287,12 +294,13 @@ public class SettingsHelper { // If we fail to apply the setting, by definition nothing happened sendBroadcast = false; sendBroadcastSystemUI = false; + sendBroadcastAccessibility = false; Log.e(TAG, "Failed to restore setting name: " + name + " + value: " + value, e); } finally { // If this was an element of interest, send the "we just restored it" // broadcast with the historical value now that the new value has // been committed and observers kicked off. - if (sendBroadcast || sendBroadcastSystemUI) { + if (sendBroadcast || sendBroadcastSystemUI || sendBroadcastAccessibility) { Intent intent = new Intent(Intent.ACTION_SETTING_RESTORED) .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY) .putExtra(Intent.EXTRA_SETTING_NAME, name) @@ -309,6 +317,13 @@ public class SettingsHelper { context.getString(com.android.internal.R.string.config_systemUi)); context.sendBroadcastAsUser(intent, context.getUser(), null); } + if (sendBroadcastAccessibility) { + UserHandle userHandle = + android.view.accessibility.Flags.restoreA11ySecureSettingsOnHsumDevice() + ? context.getUser() : UserHandle.SYSTEM; + intent.setPackage("android"); + context.sendBroadcastAsUser(intent, userHandle, null); + } } } } @@ -474,6 +489,19 @@ public class SettingsHelper { } } + private boolean shouldSkipAndLetBroadcastHandlesRestoreLogic(String settingName) { + boolean restoreHandledByBroadcast = Settings.Secure.ACCESSIBILITY_QS_TARGETS.equals( + settingName) + || Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE.equals(settingName); + if (android.view.accessibility.Flags.restoreA11ySecureSettingsOnHsumDevice()) { + restoreHandledByBroadcast |= + Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS.equals(settingName) + || Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES.equals(settingName); + } + + return restoreHandledByBroadcast; + } + private void setAutoRestore(boolean enabled) { try { IBackupManager bm = IBackupManager.Stub.asInterface( diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java index 8bffba3cb75f..62c03ddc42b9 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java @@ -30,6 +30,7 @@ import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.provider.SettingsStringUtil; +import android.view.accessibility.Flags; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; @@ -41,7 +42,6 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mockito; import java.util.concurrent.ExecutionException; @@ -54,17 +54,17 @@ import java.util.concurrent.ExecutionException; public class SettingsHelperRestoreTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + public final BroadcastInterceptingContext mInterceptingContext = + new BroadcastInterceptingContext( + InstrumentationRegistry.getInstrumentation().getContext()); private static final float FLOAT_TOLERANCE = 0.01f; - - private Context mContext; private ContentResolver mContentResolver; private SettingsHelper mSettingsHelper; @Before public void setUp() { - mContext = InstrumentationRegistry.getInstrumentation().getContext(); - mContentResolver = mContext.getContentResolver(); - mSettingsHelper = new SettingsHelper(mContext); + mContentResolver = mInterceptingContext.getContentResolver(); + mSettingsHelper = new SettingsHelper(mInterceptingContext); } @After @@ -74,23 +74,22 @@ public class SettingsHelperRestoreTest { Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0); Settings.Secure.putString(mContentResolver, Settings.Secure.ACCESSIBILITY_QS_TARGETS, null); Settings.Secure.putString(mContentResolver, + Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, null); + Settings.Secure.putString(mContentResolver, Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, null); } @Test public void restoreHighTextContrastEnabled_currentlyEnabled_enableInRestoredFromVanilla_dontSendNotification_hctKeepsEnabled() throws ExecutionException, InterruptedException { - BroadcastInterceptingContext interceptingContext = new BroadcastInterceptingContext( - mContext); BroadcastInterceptingContext.FutureIntent futureIntent = - interceptingContext.nextBroadcastIntent( + mInterceptingContext.nextBroadcastIntent( SettingsHelper.HIGH_CONTRAST_TEXT_RESTORED_BROADCAST_ACTION); - mContentResolver = interceptingContext.getContentResolver(); String settingName = Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED; Settings.Secure.putInt(mContentResolver, settingName, 1); mSettingsHelper.restoreValue( - interceptingContext, + mInterceptingContext, mContentResolver, new ContentValues(2), Settings.Secure.getUriFor(settingName), @@ -106,17 +105,14 @@ public class SettingsHelperRestoreTest { @Test public void restoreHighTextContrastEnabled_currentlyDisabled_enableInRestoredFromVanilla_sendNotification_hctKeepsDisabled() throws ExecutionException, InterruptedException { - BroadcastInterceptingContext interceptingContext = new BroadcastInterceptingContext( - mContext); BroadcastInterceptingContext.FutureIntent futureIntent = - interceptingContext.nextBroadcastIntent( + mInterceptingContext.nextBroadcastIntent( SettingsHelper.HIGH_CONTRAST_TEXT_RESTORED_BROADCAST_ACTION); - mContentResolver = interceptingContext.getContentResolver(); String settingName = Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED; Settings.Secure.putInt(mContentResolver, settingName, 0); mSettingsHelper.restoreValue( - interceptingContext, + mInterceptingContext, mContentResolver, new ContentValues(2), Settings.Secure.getUriFor(settingName), @@ -133,17 +129,14 @@ public class SettingsHelperRestoreTest { @Test public void restoreHighTextContrastEnabled_currentlyDisabled_enableInRestoredFromAfterVanilla_dontSendNotification_hctShouldEnabled() throws ExecutionException, InterruptedException { - BroadcastInterceptingContext interceptingContext = new BroadcastInterceptingContext( - mContext); BroadcastInterceptingContext.FutureIntent futureIntent = - interceptingContext.nextBroadcastIntent( + mInterceptingContext.nextBroadcastIntent( SettingsHelper.HIGH_CONTRAST_TEXT_RESTORED_BROADCAST_ACTION); - mContentResolver = interceptingContext.getContentResolver(); String settingName = Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED; Settings.Secure.putInt(mContentResolver, settingName, 0); mSettingsHelper.restoreValue( - interceptingContext, + mInterceptingContext, mContentResolver, new ContentValues(2), Settings.Secure.getUriFor(settingName), @@ -169,7 +162,7 @@ public class SettingsHelperRestoreTest { Settings.Secure.putFloat(mContentResolver, settingName, configuredSettingValue); mSettingsHelper.restoreValue( - mContext, + mInterceptingContext, mContentResolver, new ContentValues(2), Settings.Secure.getUriFor(settingName), @@ -192,7 +185,7 @@ public class SettingsHelperRestoreTest { float restoreSettingValue = defaultSettingValue + 0.5f; mSettingsHelper.restoreValue( - Mockito.mock(Context.class), + mInterceptingContext, mContentResolver, new ContentValues(2), Settings.Secure.getUriFor(settingName), @@ -214,7 +207,7 @@ public class SettingsHelperRestoreTest { */ private float setDefaultAccessibilityDisplayMagnificationScale() { float defaultSettingValue = - mContext.getResources() + mInterceptingContext.getResources() .getFraction( R.fraction.def_accessibility_display_magnification_scale, 1, 1); Settings.Secure.putFloat( @@ -235,7 +228,7 @@ public class SettingsHelperRestoreTest { Settings.Secure.putInt(mContentResolver, settingName, configuredSettingValue); mSettingsHelper.restoreValue( - Mockito.mock(Context.class), + mInterceptingContext, mContentResolver, new ContentValues(2), Settings.Secure.getUriFor(settingName), @@ -257,7 +250,7 @@ public class SettingsHelperRestoreTest { int restoreSettingValue = 1; mSettingsHelper.restoreValue( - Mockito.mock(Context.class), + mInterceptingContext, mContentResolver, new ContentValues(2), Settings.Secure.getUriFor(settingName), @@ -271,17 +264,15 @@ public class SettingsHelperRestoreTest { @Test public void restoreAccessibilityQsTargets_broadcastSent() throws ExecutionException, InterruptedException { - BroadcastInterceptingContext interceptingContext = new BroadcastInterceptingContext( - mContext); final String settingName = Settings.Secure.ACCESSIBILITY_QS_TARGETS; final String restoreSettingValue = "com.android.server.accessibility/ColorInversion" + SettingsStringUtil.DELIMITER + "com.android.server.accessibility/ColorCorrectionTile"; BroadcastInterceptingContext.FutureIntent futureIntent = - interceptingContext.nextBroadcastIntent(Intent.ACTION_SETTING_RESTORED); + mInterceptingContext.nextBroadcastIntent(Intent.ACTION_SETTING_RESTORED); mSettingsHelper.restoreValue( - interceptingContext, + mInterceptingContext, mContentResolver, new ContentValues(2), Settings.Secure.getUriFor(settingName), @@ -300,15 +291,13 @@ public class SettingsHelperRestoreTest { @Test public void restoreAccessibilityShortcutTargetService_broadcastSent() throws ExecutionException, InterruptedException { - BroadcastInterceptingContext interceptingContext = new BroadcastInterceptingContext( - mContext); final String settingName = Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE; final String restoredValue = "com.android.a11y/Service"; BroadcastInterceptingContext.FutureIntent futureIntent = - interceptingContext.nextBroadcastIntent(Intent.ACTION_SETTING_RESTORED); + mInterceptingContext.nextBroadcastIntent(Intent.ACTION_SETTING_RESTORED); mSettingsHelper.restoreValue( - interceptingContext, + mInterceptingContext, mContentResolver, new ContentValues(2), Settings.Secure.getUriFor(settingName), @@ -323,4 +312,32 @@ public class SettingsHelperRestoreTest { Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, /* defaultValue= */ 0)) .isEqualTo(Build.VERSION.SDK_INT); } + + @EnableFlags(Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE) + @Test + public void restoreAccessibilityShortcutTargets_broadcastSent() + throws ExecutionException, InterruptedException { + final String settingName = Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS; + final String restoreSettingValue = "com.android.server.accessibility/ColorInversion" + + SettingsStringUtil.DELIMITER + + "com.android.server.accessibility/ColorCorrectionTile"; + BroadcastInterceptingContext.FutureIntent futureIntent = + mInterceptingContext.nextBroadcastIntent(Intent.ACTION_SETTING_RESTORED); + + mSettingsHelper.restoreValue( + mInterceptingContext, + mContentResolver, + new ContentValues(2), + Settings.Secure.getUriFor(settingName), + settingName, + restoreSettingValue, + Build.VERSION.SDK_INT); + + Intent intentReceived = futureIntent.get(); + assertThat(intentReceived.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE)) + .isEqualTo(restoreSettingValue); + assertThat(intentReceived.getIntExtra( + Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, /* defaultValue= */ 0)) + .isEqualTo(Build.VERSION.SDK_INT); + } } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 5c1ad74fac93..37d045bf6422 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -1057,17 +1057,20 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE); final int restoredFromSdk = intent.getIntExtra(Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, 0); + final int userId = + android.view.accessibility.Flags.restoreA11ySecureSettingsOnHsumDevice() + ? getSendingUserId() : UserHandle.USER_SYSTEM; switch (which) { case Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES -> { synchronized (mLock) { restoreEnabledAccessibilityServicesLocked( - previousValue, newValue, restoredFromSdk); + previousValue, newValue, restoredFromSdk, userId); } } case ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED -> { synchronized (mLock) { restoreLegacyDisplayMagnificationNavBarIfNeededLocked( - newValue, restoredFromSdk); + newValue, restoredFromSdk, userId); } } // Currently in SUW, the user can't see gesture shortcut option as the @@ -1078,7 +1081,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub Settings.Secure.ACCESSIBILITY_QS_TARGETS, Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE -> restoreShortcutTargets(newValue, - ShortcutUtils.convertToType(which)); + ShortcutUtils.convertToType(which), userId); } } } @@ -1144,10 +1147,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } - // Called only during settings restore; currently supports only the owner user - // TODO: b/22388012 - private void restoreLegacyDisplayMagnificationNavBarIfNeededLocked(String newSetting, - int restoreFromSdkInt) { + // Called only during settings restore; currently supports only the main user + // TODO: http://b/374830726 + private void restoreLegacyDisplayMagnificationNavBarIfNeededLocked( + String newSetting, int restoreFromSdkInt, int userId) { if (restoreFromSdkInt >= Build.VERSION_CODES.R) { return; } @@ -1160,7 +1163,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return; } - final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM); + final AccessibilityUserState userState = getUserStateLocked(userId); final Set<String> targetsFromSetting = new ArraySet<>(); readColonDelimitedSettingToSet(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, userState.mUserId, str -> str, targetsFromSetting); @@ -2225,20 +2228,20 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub getMagnificationController().onUserRemoved(userId); } - // Called only during settings restore; currently supports only the owner user - // TODO: http://b/22388012 - void restoreEnabledAccessibilityServicesLocked(String oldSetting, String newSetting, - int restoreFromSdkInt) { + // Called only during settings restore; currently supports only the main user + // TODO: http://b/374830726 + void restoreEnabledAccessibilityServicesLocked( + String oldSetting, String newSetting, int restoreFromSdkInt, int userId) { readComponentNamesFromStringLocked(oldSetting, mTempComponentNameSet, false); readComponentNamesFromStringLocked(newSetting, mTempComponentNameSet, true); - AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM); + AccessibilityUserState userState = getUserStateLocked(userId); userState.mEnabledServices.clear(); userState.mEnabledServices.addAll(mTempComponentNameSet); persistComponentNamesToSettingLocked( Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, userState.mEnabledServices, - UserHandle.USER_SYSTEM); + userState.mUserId); onUserStateChangedLocked(userState); migrateAccessibilityButtonSettingsIfNecessaryLocked(userState, null, restoreFromSdkInt); } @@ -2247,21 +2250,22 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub * User could configure accessibility shortcut during the SUW before restoring user data. * Merges the current value and the new value to make sure we don't lost the setting the user's * preferences of accessibility shortcut updated in SUW are not lost. - * Called only during settings restore; currently supports only the owner user. + * * <P> * Throws an exception if used with {@code TRIPLETAP} or {@code TWOFINGER_DOUBLETAP}. * </P> - * TODO: http://b/22388012 */ - private void restoreShortcutTargets(String newValue, - @UserShortcutType int shortcutType) { + // Called only during settings restore; currently supports only the main user. + // TODO: http://b/374830726 + private void restoreShortcutTargets( + String newValue, @UserShortcutType int shortcutType, int userId) { assertNoTapShortcut(shortcutType); if (shortcutType == QUICK_SETTINGS && !android.view.accessibility.Flags.a11yQsShortcut()) { return; } synchronized (mLock) { - final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM); + final AccessibilityUserState userState = getUserStateLocked(userId); final Set<String> mergedTargets = (shortcutType == HARDWARE) ? new ArraySet<>(ShortcutUtils.getShortcutTargetsFromSettings( mContext, shortcutType, userState.mUserId)) @@ -2295,7 +2299,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub userState.updateShortcutTargetsLocked(mergedTargets, shortcutType); persistColonDelimitedSetToSettingLocked(ShortcutUtils.convertToKey(shortcutType), - UserHandle.USER_SYSTEM, mergedTargets, str -> str); + userState.mUserId, mergedTargets, str -> str); scheduleNotifyClientsOfServicesStateChangeLocked(userState); onUserStateChangedLocked(userState); } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java index a2965b3c51f1..fa78dfce0a17 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java @@ -64,6 +64,7 @@ import android.Manifest; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.annotation.NonNull; +import android.annotation.UserIdInt; import android.app.PendingIntent; import android.app.RemoteAction; import android.app.admin.DevicePolicyManager; @@ -1652,10 +1653,17 @@ public class AccessibilityManagerServiceTest { @Test @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) - public void restoreShortcutTargets_qs_a11yQsTargetsRestored() { - // TODO: remove the assumption when we fix b/381294327 + @DisableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE) + public void restoreShortcutTargetsAssumeUser0_qs_a11yQsTargetsRestored() { assumeTrue("The test is setup to run as a user 0", mTestableContext.getUserId() == UserHandle.USER_SYSTEM); + restoreShortcutTargets_qs_a11yQsTargetsRestored(); + } + + @Test + @EnableFlags({android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT, + android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE}) + public void restoreShortcutTargets_qs_a11yQsTargetsRestored() { String daltonizerTile = AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME.flattenToString(); String colorInversionTile = @@ -1667,7 +1675,7 @@ public class AccessibilityManagerServiceTest { broadcastSettingRestored( ShortcutUtils.convertToKey(QUICK_SETTINGS), - /*newValue=*/colorInversionTile); + /*newValue=*/colorInversionTile, userState.mUserId); Set<String> expected = Set.of(daltonizerTile, colorInversionTile); assertThat(readStringsFromSetting(ShortcutUtils.convertToKey(QUICK_SETTINGS))) @@ -1677,11 +1685,18 @@ public class AccessibilityManagerServiceTest { } @Test - @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) - public void restoreShortcutTargets_qs_a11yQsTargetsNotRestored() { - // TODO: remove the assumption when we fix b/381294327 + @DisableFlags({android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT, + android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE}) + public void restoreShortcutTargetsAssumeUser0_qs_a11yQsTargetsNotRestored() { assumeTrue("The test is setup to run as a user 0", mTestableContext.getUserId() == UserHandle.USER_SYSTEM); + restoreShortcutTargets_qs_a11yQsTargetsNotRestored(); + } + + @Test + @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) + @EnableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE) + public void restoreShortcutTargets_qs_a11yQsTargetsNotRestored() { String daltonizerTile = AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME.flattenToString(); String colorInversionTile = @@ -1694,7 +1709,7 @@ public class AccessibilityManagerServiceTest { broadcastSettingRestored( ShortcutUtils.convertToKey(QUICK_SETTINGS), - /*newValue=*/colorInversionTile); + /*newValue=*/colorInversionTile, userState.mUserId); Set<String> expected = Set.of(daltonizerTile); assertThat(readStringsFromSetting(ShortcutUtils.convertToKey(QUICK_SETTINGS))) @@ -1762,10 +1777,16 @@ public class AccessibilityManagerServiceTest { } @Test - public void restoreShortcutTargets_hardware_targetsMerged() { - // TODO: remove the assumption when we fix b/381294327 + @DisableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE) + public void restoreShortcutTargetsAssumeUser0_hardware_targetsMerged() { assumeTrue("The test is setup to run as a user 0", mTestableContext.getUserId() == UserHandle.USER_SYSTEM); + restoreShortcutTargets_hardware_targetsMerged(); + } + + @Test + @EnableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE) + public void restoreShortcutTargets_hardware_targetsMerged() { mFakePermissionEnforcer.grant(Manifest.permission.MANAGE_ACCESSIBILITY); final String servicePrevious = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString(); final String otherPrevious = TARGET_MAGNIFICATION; @@ -1779,7 +1800,7 @@ public class AccessibilityManagerServiceTest { broadcastSettingRestored( ShortcutUtils.convertToKey(HARDWARE), - /*newValue=*/serviceRestored); + /*newValue=*/serviceRestored, userState.mUserId); final Set<String> expected = Set.of(servicePrevious, otherPrevious, serviceRestored); assertThat(readStringsFromSetting(ShortcutUtils.convertToKey(HARDWARE))) @@ -1789,10 +1810,16 @@ public class AccessibilityManagerServiceTest { } @Test - public void restoreShortcutTargets_hardware_alreadyHadDefaultService_doesNotClear() { - // TODO: remove the assumption when we fix b/381294327 + @DisableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE) + public void restoreShortcutTargetsAssumeUser0_hardware_alreadyHadDefaultService_doesNotClear() { assumeTrue("The test is setup to run as a user 0", mTestableContext.getUserId() == UserHandle.USER_SYSTEM); + restoreShortcutTargets_hardware_alreadyHadDefaultService_doesNotClear(); + } + + @Test + @EnableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE) + public void restoreShortcutTargets_hardware_alreadyHadDefaultService_doesNotClear() { final String serviceDefault = TARGET_STANDARD_A11Y_SERVICE_NAME; mTestableContext.getOrCreateTestableResources().addOverride( R.string.config_defaultAccessibilityService, serviceDefault); @@ -1807,7 +1834,7 @@ public class AccessibilityManagerServiceTest { broadcastSettingRestored( Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, - /*newValue=*/serviceDefault); + /*newValue=*/serviceDefault, userState.mUserId); final Set<String> expected = Set.of(serviceDefault); assertThat(readStringsFromSetting(ShortcutUtils.convertToKey(HARDWARE))) @@ -1817,10 +1844,16 @@ public class AccessibilityManagerServiceTest { } @Test - public void restoreShortcutTargets_hardware_didNotHaveDefaultService_clearsDefaultService() { - // TODO: remove the assumption when we fix b/381294327 + @DisableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE) + public void restoreShortcutTargetsAsUser0_hardware_noDefaultService_clearsDefaultService() { assumeTrue("The test is setup to run as a user 0", mTestableContext.getUserId() == UserHandle.USER_SYSTEM); + restoreShortcutTargets_hardware_didNotHaveDefaultService_clearsDefaultService(); + } + + @Test + @EnableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE) + public void restoreShortcutTargets_hardware_didNotHaveDefaultService_clearsDefaultService() { final String serviceDefault = TARGET_STANDARD_A11Y_SERVICE_NAME; final String serviceRestored = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString(); // Restored value from the broadcast contains both default and non-default service. @@ -1833,7 +1866,7 @@ public class AccessibilityManagerServiceTest { setupShortcutTargetServices(userState); broadcastSettingRestored(ShortcutUtils.convertToKey(HARDWARE), - /*newValue=*/combinedRestored); + /*newValue=*/combinedRestored, userState.mUserId); // The default service is cleared from the final restored value. final Set<String> expected = Set.of(serviceRestored); @@ -1844,10 +1877,16 @@ public class AccessibilityManagerServiceTest { } @Test - public void restoreShortcutTargets_hardware_nullSetting_clearsDefaultService() { - // TODO: remove the assumption when we fix b/381294327 + @DisableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE) + public void restoreShortcutTargetsAssumeUser0_hardware_nullSetting_clearsDefaultService() { assumeTrue("The test is setup to run as a user 0", mTestableContext.getUserId() == UserHandle.USER_SYSTEM); + restoreShortcutTargets_hardware_nullSetting_clearsDefaultService(); + } + + @Test + @EnableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SECURE_SETTINGS_ON_HSUM_DEVICE) + public void restoreShortcutTargets_hardware_nullSetting_clearsDefaultService() { final String serviceDefault = TARGET_STANDARD_A11Y_SERVICE_NAME; final String serviceRestored = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString(); // Restored value from the broadcast contains both default and non-default service. @@ -1864,7 +1903,7 @@ public class AccessibilityManagerServiceTest { putShortcutSettingForUser(HARDWARE, null, userState.mUserId); broadcastSettingRestored(ShortcutUtils.convertToKey(HARDWARE), - /*newValue=*/combinedRestored); + /*newValue=*/combinedRestored, userState.mUserId); // The default service is cleared from the final restored value. final Set<String> expected = Set.of(serviceRestored); @@ -2332,12 +2371,12 @@ public class AccessibilityManagerServiceTest { setting, mA11yms.getCurrentUserIdLocked(), strings, str -> str); } - private void broadcastSettingRestored(String setting, String newValue) { + private void broadcastSettingRestored(String setting, String newValue, @UserIdInt int userId) { Intent intent = new Intent(Intent.ACTION_SETTING_RESTORED) .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY) .putExtra(Intent.EXTRA_SETTING_NAME, setting) .putExtra(Intent.EXTRA_SETTING_NEW_VALUE, newValue); - sendBroadcastToAccessibilityManagerService(intent); + sendBroadcastToAccessibilityManagerService(intent, userId); mTestableLooper.processAllMessages(); } @@ -2421,12 +2460,24 @@ public class AccessibilityManagerServiceTest { userState.updateTileServiceMapForAccessibilityServiceLocked(); } - private void sendBroadcastToAccessibilityManagerService(Intent intent) { + private void sendBroadcastToAccessibilityManagerService(Intent intent, @UserIdInt int userId) { if (!mTestableContext.getBroadcastReceivers().containsKey(intent.getAction())) { return; } mTestableContext.getBroadcastReceivers().get(intent.getAction()).forEach( - broadcastReceiver -> broadcastReceiver.onReceive(mTestableContext, intent)); + broadcastReceiver -> { + BroadcastReceiver.PendingResult result = mock( + BroadcastReceiver.PendingResult.class); + try { + FieldSetter.setField(result, + BroadcastReceiver.PendingResult.class.getDeclaredField( + "mSendingUser"), userId); + } catch (NoSuchFieldException e) { + // do nothing + } + broadcastReceiver.setPendingResult(result); + broadcastReceiver.onReceive(mTestableContext, intent); + }); } public static class FakeInputFilter extends AccessibilityInputFilter { @@ -2449,6 +2500,7 @@ public class AccessibilityManagerServiceTest { A11yTestableContext(Context base) { super(base); mMockContext = mock(Context.class); + } @Override |