summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/accessibility/flags/accessibility_flags.aconfig10
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java54
-rw-r--r--packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java85
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java44
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java98
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