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

Commit 227764bb authored by Yasin Kilicdere's avatar Yasin Kilicdere Committed by Automerger Merge Worker
Browse files

Merge "Wait for keyguard to be shown before completing the user switch." into...

Merge "Wait for keyguard to be shown before completing the user switch." into udc-dev am: df14a8f7

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23277508



Change-Id: I55303f8a47ccba2f5bf5abef6ffabb76cb7a72d4
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 7ea6ab32 df14a8f7
Loading
Loading
Loading
Loading
+47 −1
Original line number Original line Diff line number Diff line
@@ -151,6 +151,8 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.Iterator;
import java.util.List;
import java.util.List;
import java.util.Objects;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Consumer;
@@ -1707,7 +1709,8 @@ class UserController implements Handler.Callback {
                    mInjector.getWindowManager().setSwitchingUser(true);
                    mInjector.getWindowManager().setSwitchingUser(true);
                    // Only lock if the user has a secure keyguard PIN/Pattern/Pwd
                    // Only lock if the user has a secure keyguard PIN/Pattern/Pwd
                    if (mInjector.getKeyguardManager().isDeviceSecure(userId)) {
                    if (mInjector.getKeyguardManager().isDeviceSecure(userId)) {
                        mInjector.getWindowManager().lockNow(null);
                        // Make sure the device is locked before moving on with the user switch
                        mInjector.lockDeviceNowAndWaitForKeyguardShown();
                    }
                    }
                }
                }


@@ -3444,6 +3447,11 @@ class UserController implements Handler.Callback {
        WindowManagerService getWindowManager() {
        WindowManagerService getWindowManager() {
            return mService.mWindowManager;
            return mService.mWindowManager;
        }
        }

        ActivityTaskManagerInternal getActivityTaskManagerInternal() {
            return mService.mAtmInternal;
        }

        void activityManagerOnUserStopped(@UserIdInt int userId) {
        void activityManagerOnUserStopped(@UserIdInt int userId) {
            LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
            LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
        }
        }
@@ -3667,5 +3675,43 @@ class UserController implements Handler.Callback {
        void onSystemUserVisibilityChanged(boolean visible) {
        void onSystemUserVisibilityChanged(boolean visible) {
            getUserManagerInternal().onSystemUserVisibilityChanged(visible);
            getUserManagerInternal().onSystemUserVisibilityChanged(visible);
        }
        }

        void lockDeviceNowAndWaitForKeyguardShown() {
            if (getWindowManager().isKeyguardLocked()) {
                return;
            }

            final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
            t.traceBegin("lockDeviceNowAndWaitForKeyguardShown");

            final CountDownLatch latch = new CountDownLatch(1);
            ActivityTaskManagerInternal.ScreenObserver screenObserver =
                    new ActivityTaskManagerInternal.ScreenObserver() {
                        @Override
                        public void onAwakeStateChanged(boolean isAwake) {

                        }

                        @Override
                        public void onKeyguardStateChanged(boolean isShowing) {
                            if (isShowing) {
                                latch.countDown();
                            }
                        }
                    };

            getActivityTaskManagerInternal().registerScreenObserver(screenObserver);
            getWindowManager().lockDeviceNow();
            try {
                if (!latch.await(20, TimeUnit.SECONDS)) {
                    throw new RuntimeException("Keyguard is not shown in 20 seconds");
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                getActivityTaskManagerInternal().unregisterScreenObserver(screenObserver);
                t.traceEnd();
            }
        }
    }
    }
}
}
+8 −0
Original line number Original line Diff line number Diff line
@@ -262,8 +262,16 @@ public abstract class ActivityTaskManagerInternal {
     */
     */
    public abstract void setVr2dDisplayId(int vr2dDisplayId);
    public abstract void setVr2dDisplayId(int vr2dDisplayId);


    /**
     * Registers a {@link ScreenObserver}.
     */
    public abstract void registerScreenObserver(ScreenObserver observer);
    public abstract void registerScreenObserver(ScreenObserver observer);


    /**
     * Unregisters the given {@link ScreenObserver}.
     */
    public abstract void unregisterScreenObserver(ScreenObserver observer);

    /**
    /**
     * Returns is the caller has the same uid as the Recents component
     * Returns is the caller has the same uid as the Recents component
     */
     */
+8 −1
Original line number Original line Diff line number Diff line
@@ -296,6 +296,7 @@ import java.text.DateFormat;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Date;
import java.util.HashSet;
import java.util.HashSet;
import java.util.List;
import java.util.List;
@@ -652,7 +653,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
     */
     */
    float mMinPercentageMultiWindowSupportWidth;
    float mMinPercentageMultiWindowSupportWidth;


    final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
    final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers =
            Collections.synchronizedList(new ArrayList<>());


    // VR Vr2d Display Id.
    // VR Vr2d Display Id.
    int mVr2dDisplayId = INVALID_DISPLAY;
    int mVr2dDisplayId = INVALID_DISPLAY;
@@ -5868,6 +5870,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            mScreenObservers.add(observer);
            mScreenObservers.add(observer);
        }
        }


        @Override
        public void unregisterScreenObserver(ScreenObserver observer) {
            mScreenObservers.remove(observer);
        }

        @Override
        @Override
        public boolean isCallerRecents(int callingUid) {
        public boolean isCallerRecents(int callingUid) {
            return ActivityTaskManagerService.this.isCallerRecents(callingUid);
            return ActivityTaskManagerService.this.isCallerRecents(callingUid);
+50 −0
Original line number Original line Diff line number Diff line
@@ -58,6 +58,7 @@ import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mock;
@@ -103,11 +104,13 @@ import com.android.server.am.UserState.KeyEvictedCallback;
import com.android.server.pm.UserJourneyLogger;
import com.android.server.pm.UserJourneyLogger;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.UserManagerService;
import com.android.server.pm.UserManagerService;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerService;
import com.android.server.wm.WindowManagerService;


import org.junit.After;
import org.junit.After;
import org.junit.Before;
import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
import org.mockito.ArgumentCaptor;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
@@ -187,6 +190,7 @@ public class UserControllerTest {
            doNothing().when(mInjector).activityManagerOnUserStopped(anyInt());
            doNothing().when(mInjector).activityManagerOnUserStopped(anyInt());
            doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt());
            doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt());
            doNothing().when(mInjector).taskSupervisorRemoveUser(anyInt());
            doNothing().when(mInjector).taskSupervisorRemoveUser(anyInt());
            doNothing().when(mInjector).lockDeviceNowAndWaitForKeyguardShown();
            mockIsUsersOnSecondaryDisplaysEnabled(false);
            mockIsUsersOnSecondaryDisplaysEnabled(false);
            // All UserController params are set to default.
            // All UserController params are set to default.


@@ -951,6 +955,45 @@ public class UserControllerTest {
                .systemServiceManagerOnUserCompletedEvent(eq(user2), eq(event2a));
                .systemServiceManagerOnUserCompletedEvent(eq(user2), eq(event2a));
    }
    }


    @Test
    public void testStallUserSwitchUntilTheKeyguardIsShown() throws Exception {
        // enable user switch ui, because keyguard is only shown then
        mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
                /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);

        // mock the device to be secure in order to expect the keyguard to be shown
        when(mInjector.mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);

        // call real lockDeviceNowAndWaitForKeyguardShown method for this test
        doCallRealMethod().when(mInjector).lockDeviceNowAndWaitForKeyguardShown();

        // call startUser on a thread because we're expecting it to be blocked
        Thread threadStartUser = new Thread(()-> {
            mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
        });
        threadStartUser.start();

        // make sure the switch is stalled...
        Thread.sleep(2000);
        // by checking REPORT_USER_SWITCH_MSG is not sent yet
        assertNull(mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG));
        // and the thread is still alive
        assertTrue(threadStartUser.isAlive());

        // mock send the keyguard shown event
        ArgumentCaptor<ActivityTaskManagerInternal.ScreenObserver> captor = ArgumentCaptor.forClass(
                ActivityTaskManagerInternal.ScreenObserver.class);
        verify(mInjector.mActivityTaskManagerInternal).registerScreenObserver(captor.capture());
        captor.getValue().onKeyguardStateChanged(true);

        // verify the switch now moves on...
        Thread.sleep(1000);
        // by checking REPORT_USER_SWITCH_MSG is sent
        assertNotNull(mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG));
        // and the thread is finished
        assertFalse(threadStartUser.isAlive());
    }

    private void setUpAndStartUserInBackground(int userId) throws Exception {
    private void setUpAndStartUserInBackground(int userId) throws Exception {
        setUpUser(userId, 0);
        setUpUser(userId, 0);
        mUserController.startUser(userId, USER_START_MODE_BACKGROUND);
        mUserController.startUser(userId, USER_START_MODE_BACKGROUND);
@@ -1092,6 +1135,7 @@ public class UserControllerTest {
        private final IStorageManager mStorageManagerMock;
        private final IStorageManager mStorageManagerMock;
        private final UserManagerInternal mUserManagerInternalMock;
        private final UserManagerInternal mUserManagerInternalMock;
        private final WindowManagerService mWindowManagerMock;
        private final WindowManagerService mWindowManagerMock;
        private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
        private final KeyguardManager mKeyguardManagerMock;
        private final KeyguardManager mKeyguardManagerMock;
        private final LockPatternUtils mLockPatternUtilsMock;
        private final LockPatternUtils mLockPatternUtilsMock;


@@ -1111,6 +1155,7 @@ public class UserControllerTest {
            mUserManagerMock = mock(UserManagerService.class);
            mUserManagerMock = mock(UserManagerService.class);
            mUserManagerInternalMock = mock(UserManagerInternal.class);
            mUserManagerInternalMock = mock(UserManagerInternal.class);
            mWindowManagerMock = mock(WindowManagerService.class);
            mWindowManagerMock = mock(WindowManagerService.class);
            mActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
            mStorageManagerMock = mock(IStorageManager.class);
            mStorageManagerMock = mock(IStorageManager.class);
            mKeyguardManagerMock = mock(KeyguardManager.class);
            mKeyguardManagerMock = mock(KeyguardManager.class);
            when(mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
            when(mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
@@ -1171,6 +1216,11 @@ public class UserControllerTest {
            return mWindowManagerMock;
            return mWindowManagerMock;
        }
        }


        @Override
        ActivityTaskManagerInternal getActivityTaskManagerInternal() {
            return mActivityTaskManagerInternal;
        }

        @Override
        @Override
        KeyguardManager getKeyguardManager() {
        KeyguardManager getKeyguardManager() {
            return mKeyguardManagerMock;
            return mKeyguardManagerMock;