blob: e375aef3b7f06dc318d8371d54319ee360b76795 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.server.pm;
import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import android.content.pm.UserInfo;
import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.LocalServices;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
/**
* <p>Run with:<pre>
* runtest -c com.android.server.pm.UserManagerServiceCreateProfileTest frameworks-services
* </pre>
*/
@RunWith(AndroidJUnit4.class)
@MediumTest
public class UserManagerServiceCreateProfileTest {
private UserManagerService mUserManagerService;
@Before
public void setup() {
// Currently UserManagerService cannot be instantiated twice inside a VM without a cleanup
// TODO: Remove once UMS supports proper dependency injection
if (Looper.myLooper() == null) {
Looper.prepare();
}
LocalServices.removeServiceForTest(UserManagerInternal.class);
mUserManagerService = new UserManagerService(InstrumentationRegistry.getContext());
// The tests assume that the device has one user and its the system user.
List<UserInfo> users = mUserManagerService.getUsers(/* excludeDying */ false);
assertEquals("Multiple users so this test can't run.", 1, users.size());
assertEquals("Only user present isn't the system user.",
UserHandle.USER_SYSTEM, users.get(0).id);
}
@After
public void tearDown() {
removeUsers();
}
/** Tests UMS.getProfileIds() when no specific userType is specified. */
@Test
public void testGetProfiles() {
// Pretend we have a secondary user with a profile.
UserInfo secondaryUser = addUser();
UserInfo profile = addProfile(secondaryUser);
// System user should still have no profile so getProfiles should just return 1 user.
List<UserInfo> users =
mUserManagerService.getProfiles(UserHandle.USER_SYSTEM, /*excludeDying*/ false);
assertEquals("Profiles returned where none should exist", 1, users.size());
assertEquals("Missing system user from profile list of system user",
UserHandle.USER_SYSTEM, users.get(0).id);
// Secondary user should have 1 profile, so return that and itself.
users = mUserManagerService.getProfiles(secondaryUser.id, /*excludeDying*/ false);
assertEquals("Profiles returned where none should exist", 2, users.size());
assertTrue("Missing secondary user id", users.get(0).id == secondaryUser.id
|| users.get(1).id == secondaryUser.id);
assertTrue("Missing profile user id", users.get(0).id == profile.id
|| users.get(1).id == profile.id);
}
/** Tests UMS.getProfileIds() when a specific userType is specified. */
@Test
public void testGetProfileIds_specifyType() {
// Pretend we have a secondary user with a profile.
UserInfo secondaryUser = addUser();
UserInfo profile = addProfile(secondaryUser);
// TODO: When there are multiple profiles types, ensure correct output for mixed types.
final String userType1 = USER_TYPE_PROFILE_MANAGED;
// System user should still have no userType1 profile so getProfileIds should be empty.
int[] users = mUserManagerService.getProfileIds(UserHandle.USER_SYSTEM, userType1, false);
assertEquals("System user should have no managed profiles", 0, users.length);
// Secondary user should have one userType1 profile, so return just that.
users = mUserManagerService.getProfileIds(secondaryUser.id, userType1, false);
assertEquals("Wrong number of profiles", 1, users.length);
assertEquals("Wrong profile id", profile.id, users[0]);
// The profile itself is a userType1 profile, so it should return just itself.
users = mUserManagerService.getProfileIds(profile.id, userType1, false);
assertEquals("Wrong number of profiles", 1, users.length);
assertEquals("Wrong profile id", profile.id, users[0]);
}
@Test
public void testProfileBadge() {
// First profile for system user should get badge 0
assertEquals("First profile isn't given badge index 0", 0,
mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM,
USER_TYPE_PROFILE_MANAGED));
// Pretend we have a secondary user.
UserInfo secondaryUser = addUser();
// Check first profile badge for secondary user is also 0.
assertEquals("First profile for secondary user isn't given badge index 0", 0,
mUserManagerService.getFreeProfileBadgeLU(secondaryUser.id,
USER_TYPE_PROFILE_MANAGED));
// Shouldn't impact the badge for profile in system user
assertEquals("First profile isn't given badge index 0 with secondary user", 0,
mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM,
USER_TYPE_PROFILE_MANAGED));
// Pretend a secondary user has a profile.
addProfile(secondaryUser);
// Shouldn't have impacted the badge for the system user
assertEquals("First profile isn't given badge index 0 in secondary user", 0,
mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM,
USER_TYPE_PROFILE_MANAGED));
}
@Test
public void testProfileBadgeUnique() {
List<UserInfo> users = mUserManagerService.getUsers(/* excludeDying */ false);
UserInfo system = users.get(0);
int max = mUserManagerService.getMaxUsersOfTypePerParent(USER_TYPE_PROFILE_MANAGED);
if (max < 0) {
// Indicates no max. Instead of infinite, we'll just do 10.
max = 10;
}
// Badges should get allocated 0 -> max
for (int i = 0; i < max; ++i) {
int nextBadge = mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM,
USER_TYPE_PROFILE_MANAGED);
assertEquals("Wrong badge allocated", i, nextBadge);
UserInfo profile = addProfile(system);
profile.profileBadge = nextBadge;
}
}
@Test
public void testProfileBadgeReuse() {
// Pretend we have a secondary user with a profile.
UserInfo secondaryUser = addUser();
UserInfo profile = addProfile(secondaryUser);
// Add the profile it to the users being removed.
mUserManagerService.addRemovingUserIdLocked(profile.id);
// We should reuse the badge from the profile being removed.
assertEquals("Badge index not reused while removing a user", 0,
mUserManagerService.getFreeProfileBadgeLU(secondaryUser.id,
USER_TYPE_PROFILE_MANAGED));
// Edge case of reuse that only applies if we ever support 3 managed profiles
// We should prioritise using lower badge indexes
int max = mUserManagerService.getMaxUsersOfTypePerParent(USER_TYPE_PROFILE_MANAGED);
if (max < 0 || max > 2) {
UserInfo profileBadgeOne = addProfile(secondaryUser);
profileBadgeOne.profileBadge = 1;
// 0 and 2 are free, we should reuse 0 rather than 2.
assertEquals("Lower index not used", 0,
mUserManagerService.getFreeProfileBadgeLU(secondaryUser.id,
USER_TYPE_PROFILE_MANAGED));
}
}
@Test
public void testCanAddMoreManagedProfiles_removeProfile() {
// if device is low-ram or doesn't support managed profiles for some other reason, just
// skip the test
if (!mUserManagerService.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
false /* disallow remove */)) {
return;
}
if (mUserManagerService.getMaxUsersOfTypePerParent(USER_TYPE_PROFILE_MANAGED) < 0) {
// Indicates no limit, so we cannot run this test;
return;
}
// GIVEN we've reached the limit of managed profiles possible on the system user
while (mUserManagerService.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
false /* disallow remove */)) {
addProfile(mUserManagerService.getPrimaryUser());
}
// THEN you should be able to add a new profile if you remove an existing one
assertTrue("Cannot add a managed profile by removing another one",
mUserManagerService.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
true /* allow remove */));
}
@Test
public void testCanAddMoreManagedProfiles_removeDisabledProfile() {
// if device is low-ram or doesn't support managed profiles for some other reason, just
// skip the test
if (!mUserManagerService.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
false /* disallow remove */)) {
return;
}
if (mUserManagerService.getMaxUsersOfTypePerParent(USER_TYPE_PROFILE_MANAGED) < 0) {
// Indicates no limit, so we cannot run this test;
return;
}
// GIVEN we've reached the limit of managed profiles possible on the system user
// GIVEN that the profiles are not enabled yet
while (mUserManagerService.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
false /* disallow remove */)) {
addProfile(mUserManagerService.getPrimaryUser(), true /* disabled */);
}
// THEN you should be able to add a new profile if you remove an existing one
assertTrue("Cannot add a managed profile by removing another one",
mUserManagerService.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
true /* allow remove */));
}
private void removeUsers() {
List<UserInfo> users = mUserManagerService.getUsers(/* excludeDying */ false);
for (UserInfo user: users) {
if (user.id != UserHandle.USER_SYSTEM) {
mUserManagerService.removeUserInfo(user.id);
}
}
}
private UserInfo addProfile(UserInfo user) {
return addProfile(user, false);
}
private UserInfo addProfile(UserInfo user, boolean disabled) {
user.profileGroupId = user.id;
int flags = UserInfo.FLAG_MANAGED_PROFILE;
if (disabled) {
flags |= UserInfo.FLAG_DISABLED;
}
UserInfo profile = new UserInfo(
mUserManagerService.getNextAvailableId(), "profile", flags);
profile.profileGroupId = user.id;
mUserManagerService.putUserInfo(profile);
return profile;
}
private UserInfo addUser() {
UserInfo secondaryUser = new UserInfo(
mUserManagerService.getNextAvailableId(), "secondary", /* flags */ 0);
mUserManagerService.putUserInfo(secondaryUser);
return secondaryUser;
}
}