1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.car.hiddenapitest; 17 18 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_INVISIBLE; 19 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING; 20 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STOPPED; 21 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STOPPING; 22 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_UNLOCKED; 23 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_UNLOCKING; 24 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_VISIBLE; 25 26 import static com.google.common.truth.Truth.assertThat; 27 import static com.google.common.truth.Truth.assertWithMessage; 28 29 import android.car.testapi.BlockingUserLifecycleListener; 30 import android.car.user.CarUserManager.UserLifecycleEvent; 31 import android.util.Log; 32 33 import org.junit.AfterClass; 34 import org.junit.BeforeClass; 35 import org.junit.Test; 36 37 import java.util.List; 38 import java.util.concurrent.Executor; 39 40 // DO NOT ADD ANY TEST TO THIS CLASS 41 // This class will have only one test testUserVisibilityEvents. 42 public final class CarUserManagerUserVisibilityEventTest extends CarMultiUserTestBase { 43 44 private static final String TAG = CarUserManagerUserVisibilityEventTest.class.getSimpleName(); 45 46 private static final int START_TIMEOUT_MS = 100_000; 47 // A large stop timeout is required as sometimes stop user broadcast takes a significantly 48 // long time to complete. This happens when there are multiple users starting/stopping in 49 // background which is the case in this test class. 50 private static final int STOP_TIMEOUT_MS = 600_000; 51 52 // TODO(b/253264316) Stopping the user takes a while, even when calling force stop - change it 53 // to {@code false} if {@code testLifecycleListener} becomes flaky. 54 private static final boolean TEST_STOP_EVENTS = true; 55 56 @BeforeClass setUp()57 public static void setUp() { 58 setupMaxNumberOfUsers(3); // system user, current user, 1 extra user 59 } 60 61 @AfterClass cleanUp()62 public static void cleanUp() { 63 restoreMaxNumberOfUsers(); 64 } 65 66 @Test(timeout = 600_000) testUserVisibilityEvents()67 public void testUserVisibilityEvents() throws Exception { 68 69 // Check if the device supports MUMD. If not, skip the test. 70 requireMumd(); 71 72 int displayId = getDisplayForStartingBackgroundUser(); 73 int newUserId = createUser().id; 74 75 BlockingUserLifecycleListener startListener = BlockingUserLifecycleListener 76 .forSpecificEvents() 77 .forUser(newUserId) 78 .setTimeout(START_TIMEOUT_MS) 79 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING) 80 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKING) 81 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED) 82 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_VISIBLE) 83 .build(); 84 85 Log.d(TAG, "registering start listener: " + startListener); 86 87 Executor directExecutor = r -> r.run(); 88 mCarUserManager.addListener(directExecutor, startListener); 89 90 // Start new user on the secondary display. 91 startUserInBackgroundOnSecondaryDisplay(newUserId, displayId); 92 93 List<UserLifecycleEvent> startEvents = startListener.waitForEvents(); 94 Log.d(TAG, "Received expected events: " + startEvents); 95 assertWithMessage("Background user start events").that(startEvents) 96 .containsExactly( 97 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING, newUserId), 98 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKING, newUserId), 99 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED, newUserId), 100 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_VISIBLE, newUserId)); 101 102 Log.d(TAG, "unregistering start listener: " + startListener); 103 mCarUserManager.removeListener(startListener); 104 105 BlockingUserLifecycleListener stopListener = BlockingUserLifecycleListener 106 .forSpecificEvents() 107 .forUser(newUserId) 108 .setTimeout(STOP_TIMEOUT_MS) 109 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPING) 110 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPED) 111 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_INVISIBLE) 112 .build(); 113 114 Log.d(TAG, "registering stop listener: " + stopListener); 115 mCarUserManager.addListener(directExecutor, stopListener); 116 117 // Stop the background user on the virtual display. 118 forceStopUser(newUserId); 119 120 if (TEST_STOP_EVENTS) { 121 // Must force stop the user, otherwise it can take minutes for its process to finish 122 forceStopUser(newUserId); 123 124 List<UserLifecycleEvent> stopEvents = stopListener.waitForEvents(); 125 Log.d(TAG, "stopEvents: " + stopEvents + "; all events on stop listener: " 126 + stopListener.getAllReceivedEvents()); 127 assertWithMessage("Background user stop events").that(stopEvents) 128 .containsExactly( 129 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPING, newUserId), 130 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPED, newUserId), 131 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_INVISIBLE, newUserId)); 132 } else { 133 Log.w(TAG, "NOT testing user stop events"); 134 } 135 136 // Make sure unregistered listener didn't receive any more events 137 List<UserLifecycleEvent> allStartEvents = startListener.getAllReceivedEvents(); 138 Log.d(TAG, "All start events: " + startEvents); 139 assertThat(allStartEvents).containsAtLeastElementsIn(startEvents).inOrder(); 140 141 Log.d(TAG, "unregistering stop listener: " + stopListener); 142 mCarUserManager.removeListener(stopListener); 143 } 144 } 145