From 2d4aadca9487d76cb7220bdba90afa53119664ea Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Mon, 16 Mar 2015 16:55:14 -0700 Subject: [PATCH] Merge restored accessibility enable state, don't overwrite We do not want to accidentally disable the user's currently-enabled accessibility service(s); presumably they turned them on during setup for a reason. We now merge the prior + current states rather than simply replacing the current state with the former. Bug 19427367 Change-Id: I96eb47df57318c88066c5da6862f23f656639148 --- .../providers/settings/SettingsHelper.java | 3 +- .../AccessibilityManagerService.java | 48 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java index 1cad610e794f5..30786f057fbf7 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java @@ -62,8 +62,9 @@ public class SettingsHelper { */ private static final ArraySet sBroadcastOnRestore; static { - sBroadcastOnRestore = new ArraySet(1); + sBroadcastOnRestore = new ArraySet(2); sBroadcastOnRestore.add(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS); + sBroadcastOnRestore.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); } private interface SettingsLookup { diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index a712d789946c9..bb5ff1b09bd71 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -352,6 +352,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { intentFilter.addAction(Intent.ACTION_USER_SWITCHED); intentFilter.addAction(Intent.ACTION_USER_REMOVED); intentFilter.addAction(Intent.ACTION_USER_PRESENT); + intentFilter.addAction(Intent.ACTION_SETTING_RESTORED); mContext.registerReceiverAsUser(new BroadcastReceiver() { @Override @@ -369,6 +370,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { onUserStateChangedLocked(userState); } } + } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) { + final String which = intent.getStringExtra(Intent.EXTRA_SETTING_NAME); + if (Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES.equals(which)) { + synchronized (mLock) { + restoreEnabledAccessibilityServicesLocked( + intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE), + intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE)); + } + } } } }, UserHandle.ALL, intentFilter, null, null); @@ -857,6 +867,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } + // Called only during settings restore; currently supports only the owner user + void restoreEnabledAccessibilityServicesLocked(String oldSetting, String newSetting) { + readComponentNamesFromStringLocked(oldSetting, mTempComponentNameSet, false); + readComponentNamesFromStringLocked(newSetting, mTempComponentNameSet, true); + + UserState userState = getUserStateLocked(UserHandle.USER_OWNER); + userState.mEnabledServices.clear(); + userState.mEnabledServices.addAll(mTempComponentNameSet); + persistComponentNamesToSettingLocked( + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, + userState.mEnabledServices, + UserHandle.USER_OWNER); + onUserStateChangedLocked(userState); + } + private InteractionBridge getInteractionBridgeLocked() { if (mInteractionBridge == null) { mInteractionBridge = new InteractionBridge(); @@ -1129,10 +1154,27 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { Set outComponentNames) { String settingValue = Settings.Secure.getStringForUser(mContext.getContentResolver(), settingName, userId); - outComponentNames.clear(); - if (settingValue != null) { + readComponentNamesFromStringLocked(settingValue, outComponentNames, false); + } + + /** + * Populates a set with the {@link ComponentName}s contained in a colon-delimited string. + * + * @param names The colon-delimited string to parse. + * @param outComponentNames The set of component names to be populated based on + * the contents of the names string. + * @param doMerge If true, the parsed component names will be merged into the output + * set, rather than replacing the set's existing contents entirely. + */ + private void readComponentNamesFromStringLocked(String names, + Set outComponentNames, + boolean doMerge) { + if (!doMerge) { + outComponentNames.clear(); + } + if (names != null) { TextUtils.SimpleStringSplitter splitter = mStringColonSplitter; - splitter.setString(settingValue); + splitter.setString(names); while (splitter.hasNext()) { String str = splitter.next(); if (str == null || str.length() <= 0) {