1 /*
2  * Copyright (C) 2021 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.bedstead.multiuser;
18 
19 import static android.Manifest.permission.CREATE_USERS;
20 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
21 import static android.os.Build.VERSION_CODES.Q;
22 import static android.os.Build.VERSION_CODES.S;
23 
24 import static com.android.bedstead.nene.types.OptionalBoolean.FALSE;
25 
26 import static com.google.common.truth.Truth.assertThat;
27 import static com.google.common.truth.Truth.assertWithMessage;
28 
29 import static org.testng.Assert.assertThrows;
30 
31 import android.app.ActivityManager;
32 import android.content.Context;
33 import android.os.Process;
34 import android.os.UserHandle;
35 import android.os.UserManager;
36 import android.view.Display;
37 
38 import com.android.bedstead.harrier.BedsteadJUnit4;
39 import com.android.bedstead.harrier.DeviceState;
40 import com.android.bedstead.harrier.annotations.EnsureHasAdditionalUser;
41 import com.android.bedstead.harrier.annotations.EnsureHasSecondaryUser;
42 import com.android.bedstead.enterprise.annotations.EnsureHasWorkProfile;
43 import com.android.bedstead.harrier.annotations.EnsurePasswordNotSet;
44 import com.android.bedstead.harrier.annotations.RequireNotHeadlessSystemUserMode;
45 import com.android.bedstead.harrier.annotations.RequireNotVisibleBackgroundUsers;
46 import com.android.bedstead.harrier.annotations.RequireRunNotOnSecondaryUser;
47 import com.android.bedstead.harrier.annotations.RequireRunOnInitialUser;
48 import com.android.bedstead.harrier.annotations.RequireRunOnPrimaryUser;
49 import com.android.bedstead.harrier.annotations.RequireRunOnWorkProfile;
50 import com.android.bedstead.harrier.annotations.RequireSdkVersion;
51 import com.android.bedstead.harrier.annotations.RequireVisibleBackgroundUsers;
52 import com.android.bedstead.nene.TestApis;
53 import com.android.bedstead.nene.exceptions.NeneException;
54 import com.android.bedstead.nene.users.UserReference;
55 import com.android.bedstead.permissions.PermissionContext;
56 import com.android.bedstead.permissions.annotations.EnsureHasPermission;
57 
58 import org.junit.ClassRule;
59 import org.junit.Ignore;
60 import org.junit.Rule;
61 import org.junit.Test;
62 import org.junit.runner.RunWith;
63 
64 @RunWith(BedsteadJUnit4.class)
65 public class UserReferenceTest {
66     private static final int NON_EXISTING_USER_ID = 10000;
67     private static final int USER_ID = NON_EXISTING_USER_ID;
68     public static final UserHandle USER_HANDLE = new UserHandle(USER_ID);
69     private static final Context sContext = TestApis.context().instrumentedContext();
70     private static final UserManager sUserManager = sContext.getSystemService(UserManager.class);
71     private static final String PASSWORD = "1234";
72     private static final String PIN = "1234";
73     private static final String PATTERN = "1234";
74     private static final String DIFFERENT_PASSWORD = "2345";
75     private static final String DIFFERENT_PIN = "2345";
76     private static final String DIFFERENT_PATTERN = "2345";
77 
78 
79     @ClassRule @Rule
80     public static final DeviceState sDeviceState = new DeviceState();
81 
82     @Test
of_returnsUserReferenceWithValidId()83     public void of_returnsUserReferenceWithValidId() {
84         assertThat(UserReference.of(USER_HANDLE).id()).isEqualTo(USER_ID);
85     }
86 
87     @Test
id_returnsId()88     public void id_returnsId() {
89         assertThat(TestApis.users().find(USER_ID).id()).isEqualTo(USER_ID);
90     }
91 
92     @Test
userHandle_referencesId()93     public void userHandle_referencesId() {
94         assertThat(TestApis.users().find(USER_ID).userHandle().getIdentifier()).isEqualTo(USER_ID);
95     }
96 
97     @Test
exists_doesNotExist_returnsFalse()98     public void exists_doesNotExist_returnsFalse() {
99         assertThat(TestApis.users().find(NON_EXISTING_USER_ID).exists()).isFalse();
100     }
101 
102     @Test
103     @EnsureHasSecondaryUser
exists_doesExist_returnsTrue()104     public void exists_doesExist_returnsTrue() {
105         assertThat(sDeviceState.secondaryUser().exists()).isTrue();
106     }
107 
108     @Test
109     @EnsureHasAdditionalUser
remove_userExists_removesUser()110     public void remove_userExists_removesUser() {
111         UserReference user = sDeviceState.additionalUser();
112 
113         user.remove();
114 
115         assertThat(TestApis.users().all()).doesNotContain(user);
116     }
117 
118     @Test
119     @EnsureHasWorkProfile(isOrganizationOwned = true)
remove_copeUser_removeUser()120     public void remove_copeUser_removeUser() {
121         sDeviceState.workProfile().remove();
122 
123         assertThat(sDeviceState.workProfile().exists()).isFalse();
124     }
125 
126     @Test
start_userDoesNotExist_throwsException()127     public void start_userDoesNotExist_throwsException() {
128         assertThrows(NeneException.class,
129                 () -> TestApis.users().find(NON_EXISTING_USER_ID).start());
130     }
131 
132     @Test
133     @EnsureHasAdditionalUser
start_userNotStarted_userIsUnlocked()134     public void start_userNotStarted_userIsUnlocked() {
135         sDeviceState.additionalUser().stop();
136 
137         sDeviceState.additionalUser().start();
138 
139         assertThat(sDeviceState.additionalUser().isUnlocked()).isTrue();
140     }
141 
142     @Test
143     @EnsureHasSecondaryUser
start_userAlreadyStarted_doesNothing()144     public void start_userAlreadyStarted_doesNothing() {
145         sDeviceState.secondaryUser().start();
146 
147         sDeviceState.secondaryUser().start();
148 
149         assertThat(sDeviceState.secondaryUser().isUnlocked()).isTrue();
150     }
151 
152     @Test
153     @EnsureHasAdditionalUser
154     @RequireNotVisibleBackgroundUsers(reason = "because otherwise it wouldn't throw")
start_onDisplay_notSupported_throwsException()155     public void start_onDisplay_notSupported_throwsException() {
156         UserReference user = sDeviceState.additionalUser().stop();
157 
158         assertThrows(UnsupportedOperationException.class,
159                 () -> user.startVisibleOnDisplay(Display.DEFAULT_DISPLAY));
160 
161         assertWithMessage("%s is visible", user).that(user.isVisible()).isFalse();
162         assertWithMessage("%s is running", user).that(user.isRunning()).isFalse();
163     }
164 
165     @Test
166     @EnsureHasAdditionalUser
167     @RequireVisibleBackgroundUsers(reason = "because that's what being tested")
start_onDisplay_success()168     public void start_onDisplay_success() {
169         UserReference user = sDeviceState.additionalUser().stop();
170         int displayId = getDisplayIdForStartingVisibleBackgroundUser();
171 
172         user.startVisibleOnDisplay(displayId);
173 
174         try {
175             assertWithMessage("%s is visible", user).that(user.isVisible()).isTrue();
176             assertWithMessage("%s is running", user).that(user.isRunning()).isTrue();
177         } finally {
178             // Need to explicitly stop it, otherwise the display won't be available on failure
179             user.stop();
180         }
181     }
182 
183     @Test
184     @EnsureHasAdditionalUser
185     @RequireVisibleBackgroundUsers(reason = "because that's what being tested")
start_onDisplay_userAlreadyStarted_doesNothing()186     public void start_onDisplay_userAlreadyStarted_doesNothing() {
187         UserReference user = sDeviceState.additionalUser().stop();
188         int displayId = getDisplayIdForStartingVisibleBackgroundUser();
189 
190         user.startVisibleOnDisplay(displayId);
191 
192         try {
193             user.startVisibleOnDisplay(displayId);
194             assertWithMessage("%s is visible", user).that(user.isVisible()).isTrue();
195             assertWithMessage("%s is running", user).that(user.isRunning()).isTrue();
196         } finally {
197             // Need to explicitly stop it, otherwise the display won't be available on failure
198             user.stop();
199         }
200     }
201 
202     @Test
stop_userDoesNotExist_doesNothing()203     public void stop_userDoesNotExist_doesNothing() {
204         TestApis.users().find(NON_EXISTING_USER_ID).stop();
205     }
206 
207     @Test
208     @EnsureHasSecondaryUser
209     @RequireRunNotOnSecondaryUser
stop_userStarted_userIsStopped()210     public void stop_userStarted_userIsStopped() {
211         sDeviceState.secondaryUser().stop();
212 
213         assertThat(sDeviceState.secondaryUser().isRunning()).isFalse();
214     }
215 
216     @Test
217     @EnsureHasSecondaryUser
218     @RequireRunNotOnSecondaryUser
stop_userNotStarted_doesNothing()219     public void stop_userNotStarted_doesNothing() {
220         sDeviceState.secondaryUser().stop();
221 
222         sDeviceState.secondaryUser().stop();
223 
224         assertThat(sDeviceState.secondaryUser().isRunning()).isFalse();
225     }
226 
227     @Test
228     @EnsureHasSecondaryUser
229     @RequireRunNotOnSecondaryUser
230     @RequireSdkVersion(min = Q)
switchTo_userIsSwitched()231     public void switchTo_userIsSwitched() {
232         sDeviceState.secondaryUser().switchTo();
233 
234         assertThat(TestApis.users().current()).isEqualTo(sDeviceState.secondaryUser());
235     }
236 
237     @Test
238     @RequireRunOnWorkProfile(switchedToParentUser = FALSE)
switchTo_profile_switchesToParent()239     public void switchTo_profile_switchesToParent() {
240         sDeviceState.workProfile().switchTo();
241 
242         assertThat(TestApis.users().current()).isEqualTo(sDeviceState.workProfile().parent());
243     }
244 
245     @Test
246     @RequireRunOnInitialUser
247     @EnsureHasWorkProfile
stop_isWorkProfileOfCurrentUser_stops()248     public void stop_isWorkProfileOfCurrentUser_stops() {
249         sDeviceState.workProfile().stop();
250 
251         assertThat(sDeviceState.workProfile().isRunning()).isFalse();
252     }
253 
254     @Test
serialNo_returnsSerialNo()255     public void serialNo_returnsSerialNo() {
256         UserReference user = TestApis.users().instrumented();
257 
258         assertThat(user.serialNo())
259                 .isEqualTo(sUserManager.getSerialNumberForUser(Process.myUserHandle()));
260     }
261 
262     @Test
serialNo_userDoesNotExist_throwsException()263     public void serialNo_userDoesNotExist_throwsException() {
264         UserReference user = TestApis.users().find(NON_EXISTING_USER_ID);
265 
266         assertThrows(NeneException.class, user::serialNo);
267     }
268 
269     @Test
270     @EnsureHasPermission(CREATE_USERS)
271     @RequireSdkVersion(min = S, reason = "getUserName is only available on S+")
name_returnsName()272     public void name_returnsName() {
273         UserReference user = TestApis.users().instrumented();
274 
275         assertThat(user.name()).isEqualTo(sUserManager.getUserName());
276     }
277 
278     @Test
name_userDoesNotExist_throwsException()279     public void name_userDoesNotExist_throwsException() {
280         UserReference user = TestApis.users().find(NON_EXISTING_USER_ID);
281 
282         assertThrows(NeneException.class, user::name);
283     }
284 
285     @Test
286     @EnsureHasPermission(CREATE_USERS)
287     @RequireSdkVersion(min = S, reason = "getUserType is only available on S+")
type_returnsType()288     public void type_returnsType() {
289         UserReference user = TestApis.users().instrumented();
290 
291         assertThat(user.type().name()).isEqualTo(sUserManager.getUserType());
292     }
293 
294     @Test
type_userDoesNotExist_throwsException()295     public void type_userDoesNotExist_throwsException() {
296         UserReference user = TestApis.users().find(NON_EXISTING_USER_ID);
297 
298         assertThrows(NeneException.class, user::type);
299     }
300 
301     @Test
302     @RequireRunOnPrimaryUser
isPrimary_isPrimary_returnsTrue()303     public void isPrimary_isPrimary_returnsTrue() {
304         UserReference user = TestApis.users().instrumented();
305 
306         assertThat(user.isPrimary()).isTrue();
307     }
308 
309     @Test
310     @EnsureHasSecondaryUser
isPrimary_isNotPrimary_returnsFalse()311     public void isPrimary_isNotPrimary_returnsFalse() {
312         UserReference user = sDeviceState.secondaryUser();
313 
314         assertThat(user.isPrimary()).isFalse();
315     }
316 
317     @Test
isPrimary_userDoesNotExist_throwsException()318     public void isPrimary_userDoesNotExist_throwsException() {
319         UserReference user = TestApis.users().find(NON_EXISTING_USER_ID);
320 
321         assertThrows(NeneException.class, user::isPrimary);
322     }
323 
324     @Test
325     @EnsureHasAdditionalUser
isRunning_userNotStarted_returnsFalse()326     public void isRunning_userNotStarted_returnsFalse() {
327         sDeviceState.additionalUser().stop();
328 
329         assertThat(sDeviceState.additionalUser().isRunning()).isFalse();
330     }
331 
332     @Test
333     @EnsureHasAdditionalUser
isRunning_userIsRunning_returnsTrue()334     public void isRunning_userIsRunning_returnsTrue() {
335         sDeviceState.additionalUser().start();
336 
337         assertThat(sDeviceState.additionalUser().isRunning()).isTrue();
338     }
339 
340     @Test
isRunning_userDoesNotExist_returnsFalse()341     public void isRunning_userDoesNotExist_returnsFalse() {
342         UserReference user = TestApis.users().find(NON_EXISTING_USER_ID);
343 
344         assertThat(user.isRunning()).isFalse();
345     }
346 
347     @Test
isVisible_currentUser_returnsTrue()348     public void isVisible_currentUser_returnsTrue() {
349         UserReference user = TestApis.users().current();
350 
351         assertWithMessage("%s is visible", user).that(user.isVisible()).isTrue();
352     }
353 
354     @Test
355     @EnsureHasAdditionalUser
356     @RequireVisibleBackgroundUsers(reason = "because that's what being tested")
isVisible_visibleBgUser_returnsTrue()357     public void isVisible_visibleBgUser_returnsTrue() {
358         int displayId = getDisplayIdForStartingVisibleBackgroundUser();
359 
360         UserReference user = sDeviceState.additionalUser().startVisibleOnDisplay(displayId);
361 
362         try {
363             assertWithMessage("%s is visible", user).that(user.isVisible()).isTrue();
364         } finally {
365             // Need to explicitly stop it, otherwise the display won't be available on failure
366             user.stop();
367         }
368     }
369 
370     @Test
371     @EnsureHasAdditionalUser
isVisible_nonStartedUser_returnsFalse()372     public void isVisible_nonStartedUser_returnsFalse() {
373         UserReference user = sDeviceState.additionalUser().stop();
374 
375         assertWithMessage("%s is visible", user).that(user.isVisible()).isFalse();
376     }
377 
378     @Test
379     @EnsureHasAdditionalUser
isVisible_bgUser_returnsFalse()380     public void isVisible_bgUser_returnsFalse() {
381         UserReference user = sDeviceState.additionalUser().start();
382 
383         assertWithMessage("%s is visible", user).that(user.isVisible()).isFalse();
384     }
385 
386     @Test
isVisible_userDoesNotExist_returnsFalse()387     public void isVisible_userDoesNotExist_returnsFalse() {
388         UserReference user = TestApis.users().find(NON_EXISTING_USER_ID);
389 
390         assertWithMessage("%s is visible", user).that(user.isVisible()).isFalse();
391     }
392 
393     @Test
isVisibleBagroundNonProfileUser_currentUser_returnsTrue()394     public void isVisibleBagroundNonProfileUser_currentUser_returnsTrue() {
395         UserReference user = TestApis.users().current();
396 
397         assertWithMessage("%s is visible bg user", user)
398                 .that(user.isVisibleBagroundNonProfileUser()).isFalse();
399     }
400 
401     @Test
402     @EnsureHasAdditionalUser
403     @RequireVisibleBackgroundUsers(reason = "because that's what being tested")
isVisibleBagroundNonProfileUser_visibleBgUser_returnsTrue()404     public void isVisibleBagroundNonProfileUser_visibleBgUser_returnsTrue() {
405         int displayId = getDisplayIdForStartingVisibleBackgroundUser();
406 
407         UserReference user = sDeviceState.additionalUser().startVisibleOnDisplay(displayId);
408 
409         try {
410             assertWithMessage("%s is visible bg user", user)
411                     .that(user.isVisibleBagroundNonProfileUser()).isTrue();
412         } finally {
413             // Need to explicitly stop it, otherwise the display won't be available on failure
414             user.stop();
415         }
416     }
417 
418     @Test
419     @EnsureHasAdditionalUser
isVisibleBagroundNonProfileUser_nonStartedUser_returnsFalse()420     public void isVisibleBagroundNonProfileUser_nonStartedUser_returnsFalse() {
421         UserReference user = sDeviceState.additionalUser().stop();
422 
423         assertWithMessage("%s is visible bg user", user)
424                 .that(user.isVisibleBagroundNonProfileUser()).isFalse();
425     }
426 
427     @Test
428     @EnsureHasAdditionalUser
isVisibleBagroundNonProfileUser_bgUser_returnsFalse()429     public void isVisibleBagroundNonProfileUser_bgUser_returnsFalse() {
430         UserReference user = sDeviceState.additionalUser().start();
431 
432         assertWithMessage("%s is visible bg user", user)
433                 .that(user.isVisibleBagroundNonProfileUser()).isFalse();
434     }
435 
436     @Test
isVisibleBagroundNonProfileUser_userDoesNotExist_returnsFalse()437     public void isVisibleBagroundNonProfileUser_userDoesNotExist_returnsFalse() {
438         UserReference user = TestApis.users().find(NON_EXISTING_USER_ID);
439 
440         assertWithMessage("%s is visible bg user", user)
441                 .that(user.isVisibleBagroundNonProfileUser()).isFalse();
442     }
443 
444     // TODO(b/239961027): should be @EnsureHasProfile instead of @EnsureHasWorkProfile
445     @Test
446     @EnsureHasWorkProfile
isVisibleBagroundNonProfileUser_profileUser_returnsFalse()447     public void isVisibleBagroundNonProfileUser_profileUser_returnsFalse() {
448         UserReference user = sDeviceState.workProfile().start();
449 
450         assertWithMessage("%s is visible bg user", user)
451                 .that(user.isVisibleBagroundNonProfileUser()).isFalse();
452     }
453 
454     @Test
isForeground_currentUser_returnsTrue()455     public void isForeground_currentUser_returnsTrue() {
456         UserReference user = TestApis.users().current();
457 
458         assertWithMessage("%s is foreground", user).that(user.isForeground()).isTrue();
459     }
460 
461     @Test
462     @EnsureHasAdditionalUser
isForeground_nonStartedUser_returnsFalse()463     public void isForeground_nonStartedUser_returnsFalse() {
464         UserReference user = sDeviceState.additionalUser().stop();
465 
466         assertWithMessage("%s is foreground", user).that(user.isForeground()).isFalse();
467     }
468 
469     @Test
470     @EnsureHasAdditionalUser
isForeground_bgUser_returnsFalse()471     public void isForeground_bgUser_returnsFalse() {
472         UserReference user = sDeviceState.additionalUser().start();
473 
474         assertWithMessage("%s is foreground", user).that(user.isForeground()).isFalse();
475     }
476 
477     @Test
478     @EnsureHasAdditionalUser
479     @RequireVisibleBackgroundUsers(reason = "because that's what being tested")
isForeground_visibleBgUser_returnsFalse()480     public void isForeground_visibleBgUser_returnsFalse() {
481         int displayId = getDisplayIdForStartingVisibleBackgroundUser();
482 
483         UserReference user = sDeviceState.additionalUser().startVisibleOnDisplay(displayId);
484 
485         try {
486             assertWithMessage("%s is foreground", user).that(user.isForeground()).isFalse();
487         } finally {
488             // Need to explicitly stop it, otherwise the display won't be available on failure
489             user.stop();
490         }
491     }
492 
493     @Test
isForeground_userDoesNotExist_returnsFalse()494     public void isForeground_userDoesNotExist_returnsFalse() {
495         UserReference user = TestApis.users().find(NON_EXISTING_USER_ID);
496 
497         assertWithMessage("%s is foreground", user).that(user.isForeground()).isFalse();
498     }
499 
500     @Test
501     @EnsureHasAdditionalUser
isUnlocked_userIsUnlocked_returnsTrue()502     public void isUnlocked_userIsUnlocked_returnsTrue() {
503         sDeviceState.additionalUser().start();
504 
505         assertThat(sDeviceState.additionalUser().isUnlocked()).isTrue();
506     }
507 
508     // TODO(b/203542772): add tests for locked state
509 
510     @Test
isUnlocked_userDoesNotExist_returnsFalse()511     public void isUnlocked_userDoesNotExist_returnsFalse() {
512         UserReference user = TestApis.users().find(NON_EXISTING_USER_ID);
513 
514         assertThat(user.isUnlocked()).isFalse();
515     }
516 
517     @Test
518     @EnsureHasWorkProfile
parent_returnsParent()519     public void parent_returnsParent() {
520         assertThat(sDeviceState.workProfile().parent()).isNotNull();
521     }
522 
523     @Test
524     @RequireRunOnInitialUser
parent_noParent_returnsNull()525     public void parent_noParent_returnsNull() {
526         UserReference user = TestApis.users().instrumented();
527 
528         assertThat(user.parent()).isNull();
529     }
530 
531     @Test
parent_userDoesNotExist_throwsException()532     public void parent_userDoesNotExist_throwsException() {
533         UserReference user = TestApis.users().find(NON_EXISTING_USER_ID);
534 
535         assertThrows(NeneException.class, user::parent);
536     }
537 
538     @Test
539     @EnsureHasAdditionalUser
autoclose_removesUser()540     public void autoclose_removesUser() {
541         UserReference additionalUser = sDeviceState.additionalUser();
542 
543         try (UserReference user = additionalUser) {
544             // We intentionally don't do anything here, just rely on the auto-close behaviour
545         }
546 
547         assertThat(TestApis.users().all()).doesNotContain(additionalUser);
548     }
549 
550     @Test
551     @EnsurePasswordNotSet
552     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
setPassword_hasLockCredential()553     public void setPassword_hasLockCredential() {
554         try {
555             TestApis.users().instrumented().setPassword(PASSWORD);
556 
557             assertThat(TestApis.users().instrumented().hasLockCredential()).isTrue();
558         } finally {
559             TestApis.users().instrumented().clearPassword(PASSWORD);
560         }
561     }
562 
563     @Test
564     @EnsurePasswordNotSet
565     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
setPin_hasLockCredential()566     public void setPin_hasLockCredential() {
567         try {
568             TestApis.users().instrumented().setPin(PIN);
569 
570             assertThat(TestApis.users().instrumented().hasLockCredential()).isTrue();
571         } finally {
572             TestApis.users().instrumented().clearPin(PIN);
573         }
574     }
575 
576     @Test
577     @EnsurePasswordNotSet
578     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
setPattern_hasLockCredential()579     public void setPattern_hasLockCredential() {
580         try {
581             TestApis.users().instrumented().setPattern(PATTERN);
582 
583             assertThat(TestApis.users().instrumented().hasLockCredential()).isTrue();
584         } finally {
585             TestApis.users().instrumented().clearPattern(PATTERN);
586         }
587     }
588 
589     @Test
590     @EnsurePasswordNotSet
591     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
clearPassword_hasLockCredential_returnsFalse()592     public void clearPassword_hasLockCredential_returnsFalse() {
593         TestApis.users().instrumented().setPassword(PASSWORD);
594         TestApis.users().instrumented().clearPassword(PASSWORD);
595 
596         assertThat(TestApis.users().instrumented().hasLockCredential()).isFalse();
597     }
598 
599     @Test
600     @EnsurePasswordNotSet
601     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
clearPin_hasLockCredential_returnsFalse()602     public void clearPin_hasLockCredential_returnsFalse() {
603         TestApis.users().instrumented().setPin(PIN);
604         TestApis.users().instrumented().clearPin(PIN);
605 
606         assertThat(TestApis.users().instrumented().hasLockCredential()).isFalse();
607     }
608 
609     @Test
610     @EnsurePasswordNotSet
611     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
clearPattern_hasLockCredential_returnsFalse()612     public void clearPattern_hasLockCredential_returnsFalse() {
613         TestApis.users().instrumented().setPattern(PATTERN);
614         TestApis.users().instrumented().clearPattern(PATTERN);
615 
616         assertThat(TestApis.users().instrumented().hasLockCredential()).isFalse();
617     }
618 
619     @Test
620     @EnsurePasswordNotSet
clearPassword_doesNotHavePassword_doesNothing()621     public void clearPassword_doesNotHavePassword_doesNothing() {
622         TestApis.users().instrumented().clearPassword(PASSWORD);
623 
624         assertThat(TestApis.users().instrumented().hasLockCredential()).isFalse();
625     }
626 
627     @Test
628     @EnsurePasswordNotSet
clearPin_doesNotHavePin_doesNothing()629     public void clearPin_doesNotHavePin_doesNothing() {
630         TestApis.users().instrumented().clearPin(PIN);
631 
632         assertThat(TestApis.users().instrumented().hasLockCredential()).isFalse();
633     }
634 
635     @Test
636     @EnsurePasswordNotSet
clearPattern_doesNotHavePattern_doesNothing()637     public void clearPattern_doesNotHavePattern_doesNothing() {
638         TestApis.users().instrumented().clearPattern(PATTERN);
639 
640         assertThat(TestApis.users().instrumented().hasLockCredential()).isFalse();
641     }
642 
643     @Test
644     @EnsurePasswordNotSet
645     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
clearPassword_incorrectOldPassword_throwsException()646     public void clearPassword_incorrectOldPassword_throwsException() {
647         try {
648             TestApis.users().instrumented().setPassword(PASSWORD);
649 
650             assertThrows(NeneException.class,
651                     () -> TestApis.users().instrumented().clearPassword(DIFFERENT_PASSWORD));
652         } finally {
653             TestApis.users().instrumented().clearPassword(PASSWORD);
654         }
655     }
656 
657     @Test
658     @EnsurePasswordNotSet
659     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
clearPin_incorrectOldPin_throwsException()660     public void clearPin_incorrectOldPin_throwsException() {
661         try {
662             TestApis.users().instrumented().setPin(PIN);
663 
664             assertThrows(NeneException.class,
665                     () -> TestApis.users().instrumented().clearPin(DIFFERENT_PIN));
666         } finally {
667             TestApis.users().instrumented().clearPin(PIN);
668         }
669     }
670 
671     @Test
672     @EnsurePasswordNotSet
673     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
clearPattern_incorrectOldPattern_throwsException()674     public void clearPattern_incorrectOldPattern_throwsException() {
675         try {
676             TestApis.users().instrumented().setPattern(PATTERN);
677 
678             assertThrows(NeneException.class,
679                     () -> TestApis.users().instrumented().clearPattern(DIFFERENT_PATTERN));
680         } finally {
681             TestApis.users().instrumented().clearPattern(PATTERN);
682         }
683     }
684 
685     @Test
686     @EnsurePasswordNotSet
687     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
688     @Ignore // This is no longer correct - as long as nene knows the existing password it will
689     // replace - we need to change the password outside of nene to simulate the actual case
setPassword_alreadyHasPassword_throwsException()690     public void setPassword_alreadyHasPassword_throwsException() {
691         try {
692             TestApis.users().instrumented().setPassword(PASSWORD);
693 
694             assertThrows(NeneException.class,
695                     () -> TestApis.users().instrumented().setPassword(DIFFERENT_PASSWORD));
696         } finally {
697             TestApis.users().instrumented().clearPassword(PASSWORD);
698         }
699     }
700 
701     @Test
702     @EnsurePasswordNotSet
703     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
704     @Ignore // This is no longer correct - as long as nene knows the existing password it will
705     // replace - we need to change the password outside of nene to simulate the actual case
setPin_alreadyHasPin_throwsException()706     public void setPin_alreadyHasPin_throwsException() {
707         try {
708             TestApis.users().instrumented().setPin(PIN);
709 
710             assertThrows(NeneException.class,
711                     () -> TestApis.users().instrumented().setPin(DIFFERENT_PIN));
712         } finally {
713             TestApis.users().instrumented().clearPin(PIN);
714         }
715     }
716 
717     @Test
718     @EnsurePasswordNotSet
719     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
720     @Ignore // This is no longer correct - as long as nene knows the existing password it will
721     // replace - we need to change the password outside of nene to simulate the actual case
setPattern_alreadyHasPattern_throwsException()722     public void setPattern_alreadyHasPattern_throwsException() {
723         try {
724             TestApis.users().instrumented().setPattern(PATTERN);
725 
726             assertThrows(NeneException.class,
727                     () -> TestApis.users().instrumented().setPattern(DIFFERENT_PATTERN));
728         } finally {
729             TestApis.users().instrumented().clearPattern(PATTERN);
730         }
731     }
732 
733     @Test
734     @EnsurePasswordNotSet
735     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
setPassword_clearAsPinAndPattern_throwsException()736     public void setPassword_clearAsPinAndPattern_throwsException() {
737         try {
738             TestApis.users().instrumented().setPassword(PASSWORD);
739 
740             assertThrows(NeneException.class,
741                     () -> TestApis.users().instrumented().clearPin(PASSWORD));
742 
743             assertThrows(NeneException.class,
744                     () -> TestApis.users().instrumented().clearPattern(PASSWORD));
745         } finally {
746             TestApis.users().instrumented().clearPassword(PASSWORD);
747         }
748     }
749 
750     @Test
751     @EnsurePasswordNotSet
752     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
setPin_clearAsPasswordAndPattern_throwsException()753     public void setPin_clearAsPasswordAndPattern_throwsException() {
754         try {
755             TestApis.users().instrumented().setPin(PIN);
756 
757             assertThrows(NeneException.class,
758                     () -> TestApis.users().instrumented().clearPassword(PIN));
759 
760             assertThrows(NeneException.class,
761                     () -> TestApis.users().instrumented().clearPattern(PIN));
762         } finally {
763             TestApis.users().instrumented().clearPin(PIN);
764         }
765     }
766 
767     @Test
768     @EnsurePasswordNotSet
769     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
setPattern_clearAsPasswordAndPin_throwsException()770     public void setPattern_clearAsPasswordAndPin_throwsException() {
771         try {
772             TestApis.users().instrumented().setPattern(PATTERN);
773 
774             assertThrows(NeneException.class,
775                     () -> TestApis.users().instrumented().clearPassword(PATTERN));
776 
777             assertThrows(NeneException.class,
778                     () -> TestApis.users().instrumented().clearPin(PATTERN));
779         } finally {
780             TestApis.users().instrumented().clearPattern(PATTERN);
781         }
782     }
783 
784     @Test
785     @EnsurePasswordNotSet
786     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
setPassword_getAsPinAndPattern_throwsException()787     public void setPassword_getAsPinAndPattern_throwsException() {
788         try {
789             TestApis.users().instrumented().setPassword(PASSWORD);
790 
791             assertThrows(NeneException.class,
792                     () -> TestApis.users().instrumented().pin());
793 
794             assertThrows(NeneException.class,
795                     () -> TestApis.users().instrumented().pattern());
796         } finally {
797             TestApis.users().instrumented().clearPassword(PASSWORD);
798         }
799     }
800 
801     @Test
802     @EnsurePasswordNotSet
803     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
setPin_getAsPasswordAndPattern_throwsException()804     public void setPin_getAsPasswordAndPattern_throwsException() {
805         try {
806             TestApis.users().instrumented().setPin(PIN);
807 
808             assertThrows(NeneException.class,
809                     () -> TestApis.users().instrumented().password());
810 
811             assertThrows(NeneException.class,
812                     () -> TestApis.users().instrumented().pattern());
813         } finally {
814             TestApis.users().instrumented().clearPin(PIN);
815         }
816     }
817 
818     @Test
819     @EnsurePasswordNotSet
820     @RequireNotHeadlessSystemUserMode(reason = "b/248248444")
setPattern_getAsPasswordAndPin_throwsException()821     public void setPattern_getAsPasswordAndPin_throwsException() {
822         try {
823             TestApis.users().instrumented().setPattern(PATTERN);
824 
825             assertThrows(NeneException.class,
826                     () -> TestApis.users().instrumented().password());
827 
828             assertThrows(NeneException.class,
829                     () -> TestApis.users().instrumented().pin());
830         } finally {
831             TestApis.users().instrumented().clearPattern(PATTERN);
832         }
833     }
834 
835     // TODO(b/271153404): create new TestApis / users() API for this
getDisplayIdForStartingVisibleBackgroundUser()836     private int getDisplayIdForStartingVisibleBackgroundUser() {
837         int[] displayIds;
838         try (PermissionContext p =
839                 TestApis.permissions().withPermission(INTERACT_ACROSS_USERS)) {
840             displayIds = sContext.getSystemService(ActivityManager.class)
841                 .getDisplayIdsForStartingVisibleBackgroundUsers();
842         }
843         assertWithMessage("available displays").that(displayIds).isNotNull();
844         assertWithMessage("# of available displays").that(displayIds.length).isAtLeast(1);
845         return displayIds[0];
846     }
847 
848     @Test
remove_instrumentedUser_throwsException()849     public void remove_instrumentedUser_throwsException() {
850         assertThrows(NeneException.class, ()->TestApis.users().instrumented().remove());
851     }
852 }
853