Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9baabab3 authored by Riley Jones's avatar Riley Jones
Browse files

Adds a measure to A11yManagerService#switchUser to avoid switching to profiles

Runs the userId input through a function that replaces it with a parent userId, if one exists.
This prevents manager from switching to a profile userId, which would end up using the wrong settings.

Bug: 393626471
Test: atest AccessibilityManagerTest
Flag: com.android.server.accessibility.manager_lifecycle_user_change
Change-Id: I709392fac48b7d5b30ff6cca19e5c710b6d748ad
parent 34eaed1a
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -518,6 +518,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
            mService.onBootPhase(phase);
        }

        @Override
        public void onUserStarting(@androidx.annotation.NonNull TargetUser user) {
            super.onUserStarting(user);
            if (Flags.managerLifecycleUserChange()) {
                mService.switchUser(user.getUserIdentifier());
            }
        }

        @Override
        public void onUserSwitching(@androidx.annotation.Nullable TargetUser from,
                @androidx.annotation.NonNull TargetUser to) {
@@ -2127,13 +2135,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        mMagnificationController.updateUserIdIfNeeded(userId);
        List<AccessibilityServiceInfo> parsedAccessibilityServiceInfos = null;
        List<AccessibilityShortcutInfo> parsedAccessibilityShortcutInfos = null;
        parsedAccessibilityServiceInfos = parseAccessibilityServiceInfos(userId);
        parsedAccessibilityShortcutInfos = parseAccessibilityShortcutInfos(userId);

        synchronized (mLock) {
            if (Flags.managerLifecycleUserChange()) {
                userId = mSecurityPolicy.resolveProfileParentLocked(userId);
            }
            if (mCurrentUserId == userId && mInitialized) {
                return;
            }
        }

        // parse outside of a lock, but after verifying userId
        parsedAccessibilityServiceInfos = parseAccessibilityServiceInfos(userId);
        parsedAccessibilityShortcutInfos = parseAccessibilityShortcutInfos(userId);

        synchronized (mLock) {
            // Disconnect from services for the old user.
            AccessibilityUserState oldUserState = getCurrentUserStateLocked();
            oldUserState.onSwitchToAnotherUserLocked();
+20 −1
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@@ -2115,8 +2116,9 @@ public class AccessibilityManagerServiceTest {
    @Test
    public void switchUser_callsUserInitializationCompleteCallback() throws RemoteException {
        mA11yms.mUserInitializationCompleteCallbacks.add(mUserInitializationCompleteCallback);

        int newUserId = mA11yms.getCurrentUserIdLocked() + 1;
        when(mMockSecurityPolicy.resolveProfileParentLocked(anyInt())).thenReturn(newUserId);

        mA11yms.switchUser(newUserId);
        mTestableLooper.processAllMessages();

@@ -2130,6 +2132,7 @@ public class AccessibilityManagerServiceTest {
        AccessibilityManagerService.Lifecycle lifecycle =
                new AccessibilityManagerService.Lifecycle(mTestableContext, mA11yms);
        int newUserId = mA11yms.getCurrentUserIdLocked() + 1;
        when(mMockSecurityPolicy.resolveProfileParentLocked(anyInt())).thenReturn(newUserId);

        lifecycle.onUserSwitching(
                new SystemService.TargetUser(new UserInfo(0, "USER", 0)),
@@ -2139,6 +2142,21 @@ public class AccessibilityManagerServiceTest {
        verify(mUserInitializationCompleteCallback).onUserInitializationComplete(newUserId);
    }

    @Test
    @EnableFlags(Flags.FLAG_MANAGER_LIFECYCLE_USER_CHANGE)
    public void switchUser_sameParent_noChange() throws RemoteException {
        mA11yms.mUserInitializationCompleteCallbacks.add(mUserInitializationCompleteCallback);
        int newUserId = mA11yms.getCurrentUserIdLocked() + 1;
        when(mMockSecurityPolicy.resolveProfileParentLocked(anyInt())).thenReturn(
                mA11yms.getCurrentUserIdLocked());

        mA11yms.switchUser(newUserId);
        mTestableLooper.processAllMessages();

        verify(mUserInitializationCompleteCallback, never())
                .onUserInitializationComplete(newUserId);
    }

    @Test
    @DisableFlags(Flags.FLAG_MANAGER_LIFECYCLE_USER_CHANGE)
    public void intent_user_switched_switchesUser() throws RemoteException {
@@ -2146,6 +2164,7 @@ public class AccessibilityManagerServiceTest {
        int newUserId = mA11yms.getCurrentUserIdLocked() + 1;
        final Intent intent = new Intent(Intent.ACTION_USER_SWITCHED);
        intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
        when(mMockSecurityPolicy.resolveProfileParentLocked(anyInt())).thenReturn(newUserId);

        sendBroadcastToAccessibilityManagerService(intent, mA11yms.getCurrentUserIdLocked());
        mTestableLooper.processAllMessages();