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
This commit is contained in:
Christopher Tate
2015-03-16 16:55:14 -07:00
parent 6597e3435f
commit 2d4aadca94
2 changed files with 47 additions and 4 deletions

View File

@@ -62,8 +62,9 @@ public class SettingsHelper {
*/
private static final ArraySet<String> sBroadcastOnRestore;
static {
sBroadcastOnRestore = new ArraySet<String>(1);
sBroadcastOnRestore = new ArraySet<String>(2);
sBroadcastOnRestore.add(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
sBroadcastOnRestore.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
}
private interface SettingsLookup {

View File

@@ -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<ComponentName> 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 <code>names</code> 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<ComponentName> 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) {