• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.nene.users;
18 
19 import static android.os.Build.VERSION.SDK_INT;
20 
21 import static com.android.bedstead.nene.types.OptionalBoolean.ANY;
22 import static com.android.bedstead.nene.types.OptionalBoolean.FALSE;
23 import static com.android.bedstead.nene.types.OptionalBoolean.TRUE;
24 import static com.android.bedstead.nene.users.UserType.MANAGED_PROFILE_TYPE_NAME;
25 import static com.android.bedstead.nene.users.UserType.SECONDARY_USER_TYPE_NAME;
26 import static com.android.bedstead.nene.users.UserType.SYSTEM_USER_TYPE_NAME;
27 
28 import static com.google.common.truth.Truth.assertThat;
29 
30 import static org.junit.Assume.assumeTrue;
31 import static org.testng.Assert.assertThrows;
32 
33 import android.os.Build;
34 import android.os.UserHandle;
35 
36 import com.android.bedstead.harrier.BedsteadJUnit4;
37 import com.android.bedstead.harrier.DeviceState;
38 import com.android.bedstead.harrier.annotations.EnsureCanAddUser;
39 import com.android.bedstead.harrier.annotations.EnsureHasNoSecondaryUser;
40 import com.android.bedstead.harrier.annotations.EnsureHasNoWorkProfile;
41 import com.android.bedstead.harrier.annotations.EnsureHasSecondaryUser;
42 import com.android.bedstead.harrier.annotations.EnsureHasWorkProfile;
43 import com.android.bedstead.harrier.annotations.RequireHeadlessSystemUserMode;
44 import com.android.bedstead.harrier.annotations.RequireRunNotOnSecondaryUser;
45 import com.android.bedstead.harrier.annotations.RequireRunOnPrimaryUser;
46 import com.android.bedstead.harrier.annotations.RequireRunOnSecondaryUser;
47 import com.android.bedstead.harrier.annotations.enterprise.EnsureHasNoDeviceOwner;
48 import com.android.bedstead.nene.TestApis;
49 import com.android.bedstead.nene.exceptions.NeneException;
50 import com.android.bedstead.nene.utils.Poll;
51 
52 import org.junit.ClassRule;
53 import org.junit.Ignore;
54 import org.junit.Rule;
55 import org.junit.Test;
56 import org.junit.runner.RunWith;
57 
58 import java.util.Iterator;
59 import java.util.Set;
60 
61 @RunWith(BedsteadJUnit4.class)
62 public final class UsersTest {
63 
64     private static final int MAX_SYSTEM_USERS = 1;
65     private static final int MAX_SYSTEM_USERS_PER_PARENT = UserType.UNLIMITED;
66     private static final String INVALID_TYPE_NAME = "invalidTypeName";
67     private static final int MAX_MANAGED_PROFILES = UserType.UNLIMITED;
68     private static final int MAX_MANAGED_PROFILES_PER_PARENT = 1;
69     private static final int NON_EXISTING_USER_ID = 10000;
70     private static final int USER_ID = NON_EXISTING_USER_ID;
71     private static final String USER_NAME = "userName";
72 
73     private final UserType mSecondaryUserType =
74             TestApis.users().supportedType(SECONDARY_USER_TYPE_NAME);
75     private final UserType mManagedProfileType =
76             TestApis.users().supportedType(MANAGED_PROFILE_TYPE_NAME);
77     private final UserReference mInstrumentedUser = TestApis.users().instrumented();
78 
79     @ClassRule
80     @Rule
81     public static final DeviceState sDeviceState = new DeviceState();
82 
83     // We don't want to test the exact list of any specific device, so we check that it returns
84     // some known types which will exist on the emulators (used for presubmit tests).
85 
86     @Test
supportedTypes_containsManagedProfile()87     public void supportedTypes_containsManagedProfile() {
88         UserType managedProfileUserType =
89                 TestApis.users().supportedTypes().stream().filter(
90                         (ut) -> ut.name().equals(MANAGED_PROFILE_TYPE_NAME)).findFirst().get();
91 
92         assertThat(managedProfileUserType.baseType()).containsExactly(UserType.BaseType.PROFILE);
93         assertThat(managedProfileUserType.enabled()).isTrue();
94         assertThat(managedProfileUserType.maxAllowed()).isEqualTo(MAX_MANAGED_PROFILES);
95         assertThat(managedProfileUserType.maxAllowedPerParent())
96                 .isEqualTo(MAX_MANAGED_PROFILES_PER_PARENT);
97     }
98 
99     @Test
supportedTypes_containsSystemUser()100     public void supportedTypes_containsSystemUser() {
101         UserType systemUserType =
102                 TestApis.users().supportedTypes().stream().filter(
103                         (ut) -> ut.name().equals(SYSTEM_USER_TYPE_NAME)).findFirst().get();
104 
105         assertThat(systemUserType.baseType()).containsExactly(
106                 UserType.BaseType.SYSTEM, UserType.BaseType.FULL);
107         assertThat(systemUserType.enabled()).isTrue();
108         assertThat(systemUserType.maxAllowed()).isEqualTo(MAX_SYSTEM_USERS);
109         assertThat(systemUserType.maxAllowedPerParent()).isEqualTo(MAX_SYSTEM_USERS_PER_PARENT);
110     }
111 
112     @Test
supportedType_validType_returnsType()113     public void supportedType_validType_returnsType() {
114         UserType managedProfileUserType =
115                 TestApis.users().supportedType(MANAGED_PROFILE_TYPE_NAME);
116 
117         assertThat(managedProfileUserType.baseType()).containsExactly(UserType.BaseType.PROFILE);
118         assertThat(managedProfileUserType.enabled()).isTrue();
119         assertThat(managedProfileUserType.maxAllowed()).isEqualTo(MAX_MANAGED_PROFILES);
120         assertThat(managedProfileUserType.maxAllowedPerParent())
121                 .isEqualTo(MAX_MANAGED_PROFILES_PER_PARENT);
122     }
123 
124     @Test
supportedType_invalidType_returnsNull()125     public void supportedType_invalidType_returnsNull() {
126         assertThat(TestApis.users().supportedType(INVALID_TYPE_NAME)).isNull();
127     }
128 
129     @Test
130     @EnsureCanAddUser
all_containsCreatedUser()131     public void all_containsCreatedUser() {
132         UserReference user = TestApis.users().createUser().create();
133 
134         try {
135             assertThat(TestApis.users().all()).contains(user);
136         } finally {
137             user.remove();
138         }
139     }
140 
141     @Test
142     @EnsureCanAddUser(number = 2)
all_userAddedSinceLastCallToUsers_containsNewUser()143     public void all_userAddedSinceLastCallToUsers_containsNewUser() {
144         UserReference user = TestApis.users().createUser().create();
145         TestApis.users().all();
146         UserReference user2 = TestApis.users().createUser().create();
147 
148         try {
149             assertThat(TestApis.users().all()).contains(user2);
150         } finally {
151             user.remove();
152             user2.remove();
153         }
154     }
155 
156     @Test
157     @EnsureCanAddUser
all_userRemovedSinceLastCallToUsers_doesNotContainRemovedUser()158     public void all_userRemovedSinceLastCallToUsers_doesNotContainRemovedUser() {
159         UserReference user = TestApis.users().createUser().create();
160         TestApis.users().all();
161         user.remove();
162 
163         assertThat(TestApis.users().all()).doesNotContain(user);
164     }
165 
166     @Test
167     @EnsureCanAddUser
find_userExists_returnsUserReference()168     public void find_userExists_returnsUserReference() {
169         UserReference user = TestApis.users().createUser().create();
170         try {
171             assertThat(TestApis.users().find(user.id())).isEqualTo(user);
172         } finally {
173             user.remove();
174         }
175     }
176 
177     @Test
find_userDoesNotExist_returnsUserReference()178     public void find_userDoesNotExist_returnsUserReference() {
179         assertThat(TestApis.users().find(NON_EXISTING_USER_ID)).isNotNull();
180     }
181 
182     @Test
find_fromUserHandle_referencesCorrectId()183     public void find_fromUserHandle_referencesCorrectId() {
184         assertThat(TestApis.users().find(UserHandle.of(USER_ID)).id()).isEqualTo(USER_ID);
185     }
186 
187     @Test
find_constructedReferenceReferencesCorrectId()188     public void find_constructedReferenceReferencesCorrectId() {
189         assertThat(TestApis.users().find(USER_ID).id()).isEqualTo(USER_ID);
190     }
191 
192     @Test
193     @EnsureCanAddUser
createUser_additionalSystemUser_throwsException()194     public void createUser_additionalSystemUser_throwsException() {
195         assertThrows(NeneException.class, () ->
196                 TestApis.users().createUser()
197                         .type(TestApis.users().supportedType(SYSTEM_USER_TYPE_NAME))
198                         .create());
199     }
200 
201     @Test
202     @EnsureCanAddUser
createUser_userIsCreated()203     public void createUser_userIsCreated() {
204         UserReference user = TestApis.users().createUser().create();
205 
206         try {
207             assertThat(TestApis.users().all()).contains(user);
208         } finally {
209             user.remove();
210         }
211     }
212 
213     @Test
214     @EnsureCanAddUser
createUser_createdUserHasCorrectName()215     public void createUser_createdUserHasCorrectName() {
216         UserReference userReference = TestApis.users().createUser()
217                 .name(USER_NAME)
218                 .create();
219 
220         try {
221             assertThat(userReference.name()).isEqualTo(USER_NAME);
222         } finally {
223             userReference.remove();
224         }
225     }
226 
227     @Test
228     @EnsureCanAddUser
createUser_createdUserHasCorrectTypeName()229     public void createUser_createdUserHasCorrectTypeName() {
230         UserReference userReference = TestApis.users().createUser()
231                 .type(mSecondaryUserType)
232                 .create();
233 
234         try {
235             assertThat(userReference.type()).isEqualTo(mSecondaryUserType);
236         } finally {
237             userReference.remove();
238         }
239     }
240 
241     @Test
242     @EnsureCanAddUser
createUser_specifiesNullStringUserType_throwsException()243     public void createUser_specifiesNullStringUserType_throwsException() {
244         UserBuilder userBuilder = TestApis.users().createUser();
245 
246         assertThrows(NullPointerException.class, () -> userBuilder.type((String) null));
247     }
248 
249     @Test
250     @EnsureCanAddUser
createUser_specifiesNullUserType_throwsException()251     public void createUser_specifiesNullUserType_throwsException() {
252         UserBuilder userBuilder = TestApis.users().createUser();
253 
254         assertThrows(NullPointerException.class, () -> userBuilder.type((UserType) null));
255     }
256 
257     @Test
258     @EnsureCanAddUser
createUser_specifiesSystemUserType_throwsException()259     public void createUser_specifiesSystemUserType_throwsException() {
260         UserType type = TestApis.users().supportedType(SYSTEM_USER_TYPE_NAME);
261         UserBuilder userBuilder = TestApis.users().createUser()
262                 .type(type);
263 
264         assertThrows(NeneException.class, userBuilder::create);
265     }
266 
267     @Test
268     @EnsureCanAddUser
createUser_specifiesSecondaryUserType_createsUser()269     public void createUser_specifiesSecondaryUserType_createsUser() {
270         UserReference user = TestApis.users().createUser().type(mSecondaryUserType).create();
271 
272         try {
273             assertThat(user.exists()).isTrue();
274         } finally {
275             user.remove();
276         }
277     }
278 
279     @Test
280     @EnsureHasNoDeviceOwner // Device Owners can disable managed profiles
281     @EnsureHasNoWorkProfile
282     @EnsureCanAddUser
createUser_specifiesManagedProfileUserType_createsUser()283     public void createUser_specifiesManagedProfileUserType_createsUser() {
284         UserReference personalUser = TestApis.users().instrumented();
285         UserReference user =
286                 TestApis.users()
287                         .createUser()
288                         .type(mManagedProfileType)
289                         .parent(personalUser)
290                         .create();
291 
292         try {
293             assertThat(user.exists()).isTrue();
294         } finally {
295             user.remove();
296         }
297     }
298 
299     @Test
300     @EnsureHasNoWorkProfile
301     @EnsureCanAddUser
createUser_createsProfile_parentIsSet()302     public void createUser_createsProfile_parentIsSet() {
303         UserReference personalUser = TestApis.users().instrumented();
304         UserReference user =
305                 TestApis.users()
306                         .createUser()
307                         .type(mManagedProfileType)
308                         .parent(personalUser)
309                         .create();
310 
311         try {
312             assertThat(user.parent()).isEqualTo(TestApis.users().instrumented());
313         } finally {
314             user.remove();
315         }
316     }
317 
318     @Test
319     @EnsureCanAddUser
createUser_specifiesParentOnNonProfileType_throwsException()320     public void createUser_specifiesParentOnNonProfileType_throwsException() {
321         UserReference systemUser = TestApis.users().system();
322         UserBuilder userBuilder = TestApis.users().createUser()
323                 .type(mSecondaryUserType).parent(systemUser);
324 
325         assertThrows(NeneException.class, userBuilder::create);
326     }
327 
328     @Test
329     @EnsureCanAddUser
createUser_specifiesProfileTypeWithoutParent_throwsException()330     public void createUser_specifiesProfileTypeWithoutParent_throwsException() {
331         UserBuilder userBuilder = TestApis.users().createUser()
332                 .type(mManagedProfileType);
333 
334         assertThrows(NeneException.class, userBuilder::create);
335     }
336 
337     @Test
338     @EnsureCanAddUser
createUser_androidLessThanS_createsManagedProfileNotOnSystemUser_throwsException()339     public void createUser_androidLessThanS_createsManagedProfileNotOnSystemUser_throwsException() {
340         assumeTrue("After Android S, managed profiles may be a profile of a non-system user",
341                 SDK_INT < Build.VERSION_CODES.S);
342 
343         UserReference nonSystemUser = TestApis.users().createUser().create();
344 
345         try {
346             UserBuilder userBuilder = TestApis.users().createUser()
347                     .type(mManagedProfileType)
348                     .parent(nonSystemUser);
349 
350             assertThrows(NeneException.class, userBuilder::create);
351         } finally {
352             nonSystemUser.remove();
353         }
354     }
355 
356     @Test
357     @EnsureCanAddUser
createAndStart_isStarted()358     public void createAndStart_isStarted() {
359         UserReference user = null;
360 
361         try {
362             user = TestApis.users().createUser().name(USER_NAME).createAndStart();
363             assertThat(user.isUnlocked()).isTrue();
364         } finally {
365             if (user != null) {
366                 user.remove();
367             }
368         }
369     }
370 
371     @Test
system_hasId0()372     public void system_hasId0() {
373         assertThat(TestApis.users().system().id()).isEqualTo(0);
374     }
375 
376     @Test
instrumented_hasCurrentProccessId()377     public void instrumented_hasCurrentProccessId() {
378         assertThat(TestApis.users().instrumented().id())
379                 .isEqualTo(android.os.Process.myUserHandle().getIdentifier());
380     }
381 
382     @Test
383     @EnsureHasNoSecondaryUser
findUsersOfType_noMatching_returnsEmptySet()384     public void findUsersOfType_noMatching_returnsEmptySet() {
385         assertThat(TestApis.users().findUsersOfType(mSecondaryUserType)).isEmpty();
386     }
387 
388     @Test
findUsersOfType_nullType_throwsException()389     public void findUsersOfType_nullType_throwsException() {
390         assertThrows(NullPointerException.class,
391                 () -> TestApis.users().findUsersOfType(null));
392     }
393 
394     @Test
395     @EnsureHasSecondaryUser
396     @Ignore(
397             "TODO: Re-enable when harrier .secondaryUser() only"
398                     + " returns the harrier-managed secondary user")
399     @EnsureCanAddUser
findUsersOfType_returnsUsers()400     public void findUsersOfType_returnsUsers() {
401         try (UserReference additionalUser = TestApis.users().createUser().create()) {
402             assertThat(TestApis.users().findUsersOfType(mSecondaryUserType))
403                     .containsExactly(sDeviceState.secondaryUser(), additionalUser);
404         }
405     }
406 
407     @Test
findUsersOfType_profileType_throwsException()408     public void findUsersOfType_profileType_throwsException() {
409         assertThrows(NeneException.class,
410                 () -> TestApis.users().findUsersOfType(mManagedProfileType));
411     }
412 
413     @Test
414     @EnsureHasNoSecondaryUser
findUserOfType_noMatching_returnsNull()415     public void findUserOfType_noMatching_returnsNull() {
416         assertThat(TestApis.users().findUserOfType(mSecondaryUserType)).isNull();
417     }
418 
419     @Test
findUserOfType_nullType_throwsException()420     public void findUserOfType_nullType_throwsException() {
421         assertThrows(NullPointerException.class,
422                 () -> TestApis.users().findUserOfType(null));
423     }
424 
425     @Test
426     @EnsureHasSecondaryUser
427     @EnsureCanAddUser
findUserOfType_multipleMatchingUsers_throwsException()428     public void findUserOfType_multipleMatchingUsers_throwsException() {
429         try (UserReference additionalUser = TestApis.users().createUser().create()) {
430             assertThrows(NeneException.class,
431                     () -> TestApis.users().findUserOfType(mSecondaryUserType));
432         }
433     }
434 
435     @Test
436     @EnsureHasSecondaryUser
findUserOfType_oneMatchingUser_returnsUser()437     public void findUserOfType_oneMatchingUser_returnsUser() {
438         Set<UserReference> users = TestApis.users().findUsersOfType(mSecondaryUserType);
439         Iterator<UserReference> i = users.iterator();
440         i.next(); // Skip the first one so we leave one
441         while (i.hasNext()) {
442             i.next().remove();
443         }
444 
445         assertThat(TestApis.users().findUserOfType(mSecondaryUserType)).isNotNull();
446     }
447 
448     @Test
findUserOfType_profileType_throwsException()449     public void findUserOfType_profileType_throwsException() {
450         assertThrows(NeneException.class,
451                 () -> TestApis.users().findUserOfType(mManagedProfileType));
452     }
453 
454     @Test
455     @EnsureHasNoWorkProfile
findProfilesOfType_noMatching_returnsEmptySet()456     public void findProfilesOfType_noMatching_returnsEmptySet() {
457         assertThat(TestApis.users().findProfilesOfType(mManagedProfileType, mInstrumentedUser))
458                 .isEmpty();
459     }
460 
461     @Test
findProfilesOfType_nullType_throwsException()462     public void findProfilesOfType_nullType_throwsException() {
463         assertThrows(NullPointerException.class,
464                 () -> TestApis.users().findProfilesOfType(
465                         /* userType= */ null, mInstrumentedUser));
466     }
467 
468     @Test
findProfilesOfType_nullParent_throwsException()469     public void findProfilesOfType_nullParent_throwsException() {
470         assertThrows(NullPointerException.class,
471                 () -> TestApis.users().findProfilesOfType(
472                         mManagedProfileType, /* parent= */ null));
473     }
474 
475     // TODO(scottjonathan): Once we have profiles which support more than one instance, test this
476 
477     @Test
478     @EnsureHasNoWorkProfile
findProfileOfType_noMatching_returnsNull()479     public void findProfileOfType_noMatching_returnsNull() {
480         assertThat(TestApis.users().findProfileOfType(mManagedProfileType, mInstrumentedUser))
481                 .isNull();
482     }
483 
484     @Test
findProfilesOfType_nonProfileType_throwsException()485     public void findProfilesOfType_nonProfileType_throwsException() {
486         assertThrows(NeneException.class,
487                 () -> TestApis.users().findProfilesOfType(mSecondaryUserType, mInstrumentedUser));
488     }
489 
490     @Test
findProfileOfType_nullType_throwsException()491     public void findProfileOfType_nullType_throwsException() {
492         assertThrows(NullPointerException.class,
493                 () -> TestApis.users().findProfileOfType(/* userType= */ null, mInstrumentedUser));
494     }
495 
496     @Test
findProfileOfType_nonProfileType_throwsException()497     public void findProfileOfType_nonProfileType_throwsException() {
498         assertThrows(NeneException.class,
499                 () -> TestApis.users().findProfileOfType(mSecondaryUserType, mInstrumentedUser));
500     }
501 
502     @Test
findProfileOfType_nullParent_throwsException()503     public void findProfileOfType_nullParent_throwsException() {
504         assertThrows(NullPointerException.class,
505                 () -> TestApis.users().findProfileOfType(mManagedProfileType, /* parent= */ null));
506     }
507 
508     @Test
509     @EnsureHasWorkProfile // TODO(scottjonathan): This should have a way of specifying exactly 1
findProfileOfType_oneMatchingUser_returnsUser()510     public void findProfileOfType_oneMatchingUser_returnsUser() {
511         assertThat(TestApis.users().findProfileOfType(mManagedProfileType, mInstrumentedUser))
512                 .isNotNull();
513     }
514 
515     @Test
nonExisting_userDoesNotExist()516     public void nonExisting_userDoesNotExist() {
517         UserReference userReference = TestApis.users().nonExisting();
518 
519         assertThat(userReference.exists()).isFalse();
520     }
521 
522     @Test
523     @EnsureHasSecondaryUser(switchedToUser = TRUE)
currentUser_secondaryUser_returnsCurrentUser()524     public void currentUser_secondaryUser_returnsCurrentUser() {
525         assertThat(TestApis.users().current()).isEqualTo(sDeviceState.secondaryUser());
526     }
527 
528     @Test
529     @RequireRunOnPrimaryUser(switchedToUser = TRUE)
currentUser_primaryUser_returnsCurrentUser()530     public void currentUser_primaryUser_returnsCurrentUser() {
531         assertThat(TestApis.users().current()).isEqualTo(sDeviceState.primaryUser());
532     }
533 
534     @Test
535     @RequireRunNotOnSecondaryUser
536     @EnsureHasSecondaryUser
537     @RequireHeadlessSystemUserMode(reason = "stopBgUsersOnSwitch is only for headless")
switch_hasSetStopBgUsersOnSwitch_stopsUser()538     public void switch_hasSetStopBgUsersOnSwitch_stopsUser() throws Exception {
539         try {
540             sDeviceState.secondaryUser().switchTo();
541             TestApis.users().setStopBgUsersOnSwitch(TRUE);
542             TestApis.users().system().switchTo();
543 
544             Poll.forValue("Secondary user running",
545                     () -> sDeviceState.secondaryUser().isRunning())
546                     .toBeEqualTo(false)
547                     .errorOnFail()
548                     .await();
549 
550             assertThat(sDeviceState.secondaryUser().isRunning()).isFalse();
551         } finally {
552             sDeviceState.secondaryUser().start();
553             TestApis.users().setStopBgUsersOnSwitch(ANY);
554         }
555     }
556 
557     @Test
558     @RequireRunOnSecondaryUser
switch_hasSetStopBgUsersOnSwitchFalse_doesNotStopUser()559     public void switch_hasSetStopBgUsersOnSwitchFalse_doesNotStopUser() {
560         try {
561             TestApis.users().setStopBgUsersOnSwitch(FALSE);
562             TestApis.users().system().switchTo();
563 
564             assertThat(sDeviceState.secondaryUser().isRunning()).isTrue();
565         } finally {
566             TestApis.users().setStopBgUsersOnSwitch(ANY);
567             sDeviceState.secondaryUser().start();
568             sDeviceState.secondaryUser().switchTo();
569         }
570     }
571 }
572