diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index e5cba625e4d3f..7c02929e819c1 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -718,7 +718,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { synchronized (mLock) { // Disconnect from services for the old user. UserState oldUserState = getUserStateLocked(mCurrentUserId); - unbindAllServicesLocked(oldUserState); + oldUserState.onSwitchToAnotherUser(); // Disable the local managers for the old user. if (oldUserState.mClients.getRegisteredCallbackCount() > 0) { @@ -737,11 +737,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (userState.mUiAutomationService != null) { // Switching users disables the UI automation service. userState.mUiAutomationService.binderDied(); - } else if (readConfigurationForUserStateLocked(userState)) { - // Update the user state if needed. - onUserStateChangedLocked(userState); } + readConfigurationForUserStateLocked(userState); + // Even if reading did not yield change, we have to update + // the state since the context in which the current user + // state was used has changed since it was inactive. + onUserStateChangedLocked(userState); + if (announceNewUser) { // Schedule announcement of the current user if needed. mMainHandler.sendEmptyMessageDelayed(MainHandler.MSG_ANNOUNCE_NEW_USER_IF_NEEDED, @@ -2561,11 +2564,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private class UserState { public final int mUserId; - public final CopyOnWriteArrayList mBoundServices = new CopyOnWriteArrayList(); + // Non-transient state. public final RemoteCallbackList mClients = new RemoteCallbackList(); + public final SparseArray mInteractionConnections = + new SparseArray(); + + public final SparseArray mWindowTokens = new SparseArray(); + + // Transient state. + + public final CopyOnWriteArrayList mBoundServices = + new CopyOnWriteArrayList(); + public final Map mComponentNameToServiceMap = new HashMap(); @@ -2579,15 +2592,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { public final Set mTouchExplorationGrantedServices = new HashSet(); - public final SparseArray - mInteractionConnections = - new SparseArray(); - - public final SparseArray mWindowTokens = new SparseArray(); - public int mHandledFeedbackTypes = 0; - public int mLastSentClientState; + public int mLastSentClientState = -1; public boolean mIsAccessibilityEnabled; public boolean mIsTouchExplorationEnabled; @@ -2612,6 +2619,34 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } return clientState; } + + public void onSwitchToAnotherUser() { + // Clear UI test automation state. + if (mUiAutomationService != null) { + mUiAutomationService.binderDied(); + mUiAutomationService = null; + mUiAutomationServiceClient = null; + } + + // Unbind all services. + unbindAllServicesLocked(this); + + // Clear service management state. + mBoundServices.clear(); + mBindingServices.clear(); + + // Clear event management state. + mHandledFeedbackTypes = 0; + mLastSentClientState = -1; + + // Clear state persisted in settings. + mEnabledServices.clear(); + mTouchExplorationGrantedServices.clear(); + mIsAccessibilityEnabled = false; + mIsTouchExplorationEnabled = false; + mIsEnhancedWebAccessibilityEnabled = false; + mIsDisplayMagnificationEnabled = false; + } } private final class AccessibilityContentObserver extends ContentObserver {