1 /* 2 * Copyright (C) 2020 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 17 package com.android.car.testapi; 18 19 import static android.car.test.mocks.JavaMockitoHelper.await; 20 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING; 21 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STOPPED; 22 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STOPPING; 23 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING; 24 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_UNLOCKED; 25 import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_UNLOCKING; 26 27 import static com.google.common.truth.Truth.assertThat; 28 import static com.google.common.truth.Truth.assertWithMessage; 29 30 import static org.junit.Assert.assertThrows; 31 32 import android.annotation.NonNull; 33 import android.annotation.UserIdInt; 34 import android.car.testapi.BlockingUserLifecycleListener; 35 import android.car.user.CarUserManager; 36 import android.car.user.CarUserManager.UserLifecycleEvent; 37 import android.os.UserHandle; 38 import android.util.Log; 39 40 import com.android.car.internal.common.CommonConstants.UserLifecycleEventType; 41 42 import org.junit.Test; 43 44 import java.util.Arrays; 45 import java.util.List; 46 import java.util.concurrent.CountDownLatch; 47 import java.util.stream.Collectors; 48 49 public final class BlockingUserLifecycleListenerTest { 50 51 private static final String TAG = BlockingUserLifecycleListenerTest.class.getSimpleName(); 52 private static final long TIMEOUT_MS = 500; 53 54 @Test testListener_forAnyEvent_invalidBuilderMethods()55 public void testListener_forAnyEvent_invalidBuilderMethods() throws Exception { 56 BlockingUserLifecycleListener.Builder builder = BlockingUserLifecycleListener.forAnyEvent() 57 .setTimeout(666); 58 59 assertThrows(IllegalStateException.class, () -> builder.forUser(10)); 60 assertThrows(IllegalStateException.class, () -> builder.forPreviousUser(10)); 61 assertThrows(IllegalStateException.class, 62 () -> builder.addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPED)); 63 } 64 65 @Test testForAnyEvent_invalidMethods()66 public void testForAnyEvent_invalidMethods() throws Exception { 67 BlockingUserLifecycleListener listener = BlockingUserLifecycleListener.forAnyEvent() 68 .build(); 69 70 assertThrows(IllegalStateException.class, () -> listener.waitForEvents()); 71 assertThrows(IllegalStateException.class, () -> listener.getAllReceivedEvents()); 72 } 73 74 @Test testForAnyEvent_timesout()75 public void testForAnyEvent_timesout() throws Exception { 76 BlockingUserLifecycleListener listener = BlockingUserLifecycleListener.forAnyEvent() 77 .build(); 78 79 assertThrows(IllegalStateException.class, () -> listener.waitForAnyEvent()); 80 } 81 82 @Test testForAnyEvent_ok()83 public void testForAnyEvent_ok() throws Exception { 84 BlockingUserLifecycleListener listener = BlockingUserLifecycleListener.forAnyEvent() 85 .build(); 86 sendAsyncEvents(listener, 10, USER_LIFECYCLE_EVENT_TYPE_UNLOCKED); 87 88 UserLifecycleEvent event = listener.waitForAnyEvent(); 89 assertEvent(event, 10, USER_LIFECYCLE_EVENT_TYPE_UNLOCKED); 90 } 91 92 @Test testForSpecificEvents_invalidMethods()93 public void testForSpecificEvents_invalidMethods() throws Exception { 94 BlockingUserLifecycleListener listener = BlockingUserLifecycleListener.forSpecificEvents() 95 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING).build(); 96 97 assertThrows(IllegalStateException.class, () -> listener.waitForAnyEvent()); 98 } 99 100 @Test testForSpecificEvents_receivedOnlyExpected()101 public void testForSpecificEvents_receivedOnlyExpected() throws Exception { 102 BlockingUserLifecycleListener listener = BlockingUserLifecycleListener.forSpecificEvents() 103 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING) 104 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED) 105 .build(); 106 107 sendAsyncEvents(listener, 10, 108 USER_LIFECYCLE_EVENT_TYPE_STARTING, 109 USER_LIFECYCLE_EVENT_TYPE_UNLOCKED); 110 111 List<UserLifecycleEvent> events = listener.waitForEvents(); 112 assertEvents(events, 10, 113 USER_LIFECYCLE_EVENT_TYPE_STARTING, 114 USER_LIFECYCLE_EVENT_TYPE_UNLOCKED); 115 116 List<UserLifecycleEvent> allReceivedEvents = listener.getAllReceivedEvents(); 117 assertThat(allReceivedEvents).containsAtLeastElementsIn(events).inOrder(); 118 } 119 120 @Test testForSpecificEvents_receivedExtraEvents()121 public void testForSpecificEvents_receivedExtraEvents() throws Exception { 122 BlockingUserLifecycleListener listener = BlockingUserLifecycleListener.forSpecificEvents() 123 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING) 124 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKING) 125 .build(); 126 127 CountDownLatch latch = sendAsyncEvents(listener, 10, 128 USER_LIFECYCLE_EVENT_TYPE_STARTING, 129 USER_LIFECYCLE_EVENT_TYPE_SWITCHING, 130 USER_LIFECYCLE_EVENT_TYPE_UNLOCKING, 131 USER_LIFECYCLE_EVENT_TYPE_UNLOCKED); 132 133 List<UserLifecycleEvent> events = listener.waitForEvents(); 134 assertEvents(events, 10, 135 USER_LIFECYCLE_EVENT_TYPE_STARTING, 136 USER_LIFECYCLE_EVENT_TYPE_UNLOCKING); 137 138 await(latch, TIMEOUT_MS); 139 List<UserLifecycleEvent> allReceivedEvents = listener.getAllReceivedEvents(); 140 assertEvents(allReceivedEvents, 10, 141 USER_LIFECYCLE_EVENT_TYPE_STARTING, 142 USER_LIFECYCLE_EVENT_TYPE_SWITCHING, 143 USER_LIFECYCLE_EVENT_TYPE_UNLOCKING, 144 USER_LIFECYCLE_EVENT_TYPE_UNLOCKED); 145 } 146 147 @Test testForSpecificEvents_filterByUser()148 public void testForSpecificEvents_filterByUser() throws Exception { 149 BlockingUserLifecycleListener listener = BlockingUserLifecycleListener.forSpecificEvents() 150 .forUser(10) 151 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING) 152 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED) 153 .build(); 154 UserLifecycleEvent wrong1 = new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPING, 11); 155 UserLifecycleEvent wrong2 = new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPED, 11); 156 UserLifecycleEvent right1 = new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING, 10); 157 UserLifecycleEvent right2 = new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED, 10); 158 159 CountDownLatch latch = sendAsyncEvents(listener, 160 Arrays.asList(wrong1, right1, right2, wrong2)); 161 162 List<UserLifecycleEvent> events = listener.waitForEvents(); 163 assertThat(events).containsExactly(right1, right2).inOrder(); 164 165 await(latch, TIMEOUT_MS); 166 List<UserLifecycleEvent> allReceivedEvents = listener.getAllReceivedEvents(); 167 assertThat(allReceivedEvents) 168 .containsExactly(wrong1, right1, right2, wrong2) 169 .inOrder(); 170 } 171 172 @Test testForSpecificEvents_filterByUserDuplicatedEventTypes()173 public void testForSpecificEvents_filterByUserDuplicatedEventTypes() throws Exception { 174 BlockingUserLifecycleListener listener = BlockingUserLifecycleListener.forSpecificEvents() 175 .forUser(10) 176 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING) 177 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED) 178 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING) 179 .build(); 180 UserLifecycleEvent wrong1 = new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPING, 11); 181 UserLifecycleEvent wrong2 = new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPED, 11); 182 UserLifecycleEvent wrong3 = new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING, 11); 183 UserLifecycleEvent right1 = new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING, 10); 184 UserLifecycleEvent right2 = new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED, 10); 185 UserLifecycleEvent right3 = new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING, 10); 186 187 CountDownLatch latch = sendAsyncEvents(listener, 188 Arrays.asList(wrong1, right1, wrong2, right2, right3, wrong3)); 189 190 List<UserLifecycleEvent> events = listener.waitForEvents(); 191 assertThat(events).containsExactly(right1, right2, right3).inOrder(); 192 193 await(latch, TIMEOUT_MS); 194 List<UserLifecycleEvent> allReceivedEvents = listener.getAllReceivedEvents(); 195 assertThat(allReceivedEvents) 196 .containsExactly(wrong1, right1, wrong2, right2, right3, wrong3) 197 .inOrder(); 198 } 199 200 @Test testForSpecificEvents_filterByPreviousUser()201 public void testForSpecificEvents_filterByPreviousUser() throws Exception { 202 BlockingUserLifecycleListener listener = BlockingUserLifecycleListener.forSpecificEvents() 203 .forPreviousUser(10) 204 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_SWITCHING) 205 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED) 206 .build(); 207 UserLifecycleEvent wrong1 = 208 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPING, 11); 209 UserLifecycleEvent wrong2 = 210 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPED, 10); 211 UserLifecycleEvent wrong3 = 212 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_SWITCHING, 11, 10); 213 UserLifecycleEvent right1 = 214 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_SWITCHING, 10, 11); 215 UserLifecycleEvent right2 = 216 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED, 10, 12); 217 218 CountDownLatch latch = sendAsyncEvents(listener, 219 Arrays.asList(wrong1, right1, wrong2, right2, wrong3)); 220 221 List<UserLifecycleEvent> events = listener.waitForEvents(); 222 assertThat(events).containsExactly(right1, right2).inOrder(); 223 224 await(latch, TIMEOUT_MS); 225 List<UserLifecycleEvent> allReceivedEvents = listener.getAllReceivedEvents(); 226 assertThat(allReceivedEvents) 227 .containsExactly(wrong1, right1, wrong2, right2, wrong3) 228 .inOrder(); 229 } 230 231 @Test testForSpecificEvents_filterByPreviousAndTargetUsers()232 public void testForSpecificEvents_filterByPreviousAndTargetUsers() throws Exception { 233 BlockingUserLifecycleListener listener = BlockingUserLifecycleListener.forSpecificEvents() 234 .forPreviousUser(10) 235 .forUser(11) 236 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_SWITCHING) 237 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED) 238 .build(); 239 UserLifecycleEvent wrong1 = 240 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPING, 11); 241 UserLifecycleEvent wrong2 = 242 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPED, 10); 243 UserLifecycleEvent wrong3 = 244 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_SWITCHING, 10, 12); 245 UserLifecycleEvent right1 = 246 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_SWITCHING, 10, 11); 247 UserLifecycleEvent right2 = 248 new UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED, 10, 11); 249 250 CountDownLatch latch = sendAsyncEvents(listener, 251 Arrays.asList(wrong1, right1, wrong2, right2, wrong3)); 252 253 List<UserLifecycleEvent> events = listener.waitForEvents(); 254 assertThat(events).containsExactly(right1, right2).inOrder(); 255 256 await(latch, TIMEOUT_MS); 257 List<UserLifecycleEvent> allReceivedEvents = listener.getAllReceivedEvents(); 258 assertThat(allReceivedEvents) 259 .containsExactly(wrong1, right1, wrong2, right2, wrong3) 260 .inOrder(); 261 } 262 263 @Test testForNoExpectedEvent_noEventsReceived()264 public void testForNoExpectedEvent_noEventsReceived() throws Exception { 265 BlockingUserLifecycleListener listener = BlockingUserLifecycleListener.forNoExpectedEvent() 266 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING) 267 .addExpectedEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED) 268 .build(); 269 270 List<UserLifecycleEvent> events = listener.waitForEvents(); 271 272 sendAsyncEvents(listener, /* userId= */ 10, 273 USER_LIFECYCLE_EVENT_TYPE_SWITCHING, 274 USER_LIFECYCLE_EVENT_TYPE_UNLOCKING); 275 276 assertThat(events).isEmpty(); 277 } 278 279 @NonNull sendAsyncEvents(@onNull BlockingUserLifecycleListener listener, @UserIdInt int userId, @UserLifecycleEventType int... eventTypes)280 private static CountDownLatch sendAsyncEvents(@NonNull BlockingUserLifecycleListener listener, 281 @UserIdInt int userId, @UserLifecycleEventType int... eventTypes) { 282 List<UserLifecycleEvent> events = Arrays.stream(eventTypes) 283 .mapToObj((type) -> new UserLifecycleEvent(type, userId)) 284 .collect(Collectors.toList()); 285 return sendAsyncEvents(listener, events); 286 } 287 288 @NonNull sendAsyncEvents(@onNull BlockingUserLifecycleListener listener, @NonNull List<UserLifecycleEvent> events)289 private static CountDownLatch sendAsyncEvents(@NonNull BlockingUserLifecycleListener listener, 290 @NonNull List<UserLifecycleEvent> events) { 291 Log.d(TAG, "sendAsyncEvents(" + events + "): called on thread " + Thread.currentThread()); 292 CountDownLatch latch = new CountDownLatch(1); 293 new Thread(() -> { 294 Log.d(TAG, "sending " + events.size() + " on thread " + Thread.currentThread()); 295 events.forEach((e) -> listener.onEvent(e)); 296 Log.d(TAG, "sent"); 297 latch.countDown(); 298 }, "AsyncEventsThread").start(); 299 return latch; 300 } 301 assertEvent(UserLifecycleEvent event, @UserIdInt int expectedUserId, @UserLifecycleEventType int expectedType)302 private static void assertEvent(UserLifecycleEvent event, @UserIdInt int expectedUserId, 303 @UserLifecycleEventType int expectedType) { 304 assertThat(event).isNotNull(); 305 assertWithMessage("wrong type on %s; expected %s", event, 306 CarUserManager.lifecycleEventTypeToString(expectedType)).that(event.getEventType()) 307 .isEqualTo(expectedType); 308 assertThat(event.getUserId()).isEqualTo(expectedUserId); 309 assertThat(event.getUserHandle().getIdentifier()).isEqualTo(expectedUserId); 310 assertThat(event.getPreviousUserId()).isEqualTo(UserHandle.USER_NULL); 311 assertThat(event.getPreviousUserHandle()).isNull(); 312 } 313 assertEvents(List<UserLifecycleEvent> events, @UserIdInt int expectedUserId, @UserLifecycleEventType int... expectedTypes)314 private static void assertEvents(List<UserLifecycleEvent> events, @UserIdInt int expectedUserId, 315 @UserLifecycleEventType int... expectedTypes) { 316 assertThat(events).isNotNull(); 317 assertThat(events).hasSize(expectedTypes.length); 318 for (int i = 0; i < expectedTypes.length; i++) { 319 int expectedType = expectedTypes[i]; 320 UserLifecycleEvent event = events.get(i); 321 assertEvent(event, expectedUserId, expectedType); 322 } 323 } 324 } 325