• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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