Loading core/java/android/content/pm/UserInfo.java +6 −2 Original line number Diff line number Diff line Loading @@ -494,10 +494,14 @@ public class UserInfo implements Parcelable { // TODO(b/142482943): Make this logic more specific and customizable. (canHaveProfile(userType)) /* @hide */ public boolean canHaveProfile() { if (isProfile() || isGuest() || isRestricted()) { if (!isFull() || isProfile() || isGuest() || isRestricted() || isDemo()) { return false; } return isMain(); // NOTE: profiles used to be restricted just to the system user (and later to the main // user), but from the framework point of view there is no need for such restriction, hence // it's lifted // TODO(b/374832167): check value of config_supportProfilesOnNonMainUser return isMain() || android.multiuser.Flags.profilesForAll(); } // TODO(b/142482943): Get rid of this (after removing it from all tests) if feasible. Loading core/java/android/content/pm/multiuser.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -646,3 +646,10 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "profiles_for_all" namespace: "multiuser" description: "Allows any regular user to have profiles" bug: "374832167" } core/tests/coretests/src/android/content/pm/UserInfoTest.java +86 −4 Original line number Diff line number Diff line Loading @@ -16,19 +16,44 @@ package android.content.pm; import static android.content.pm.UserInfo.FLAG_DEMO; import static android.content.pm.UserInfo.FLAG_FULL; import static android.content.pm.UserInfo.FLAG_GUEST; import static android.content.pm.UserInfo.FLAG_MAIN; import static android.content.pm.UserInfo.FLAG_PROFILE; import static android.content.pm.UserInfo.FLAG_SYSTEM; import static android.os.UserManager.USER_TYPE_FULL_RESTRICTED; import static android.os.UserManager.USER_TYPE_FULL_SYSTEM; import static android.os.UserManager.USER_TYPE_SYSTEM_HEADLESS; import static com.google.common.truth.Truth.assertThat; import android.content.pm.UserInfo.UserInfoFlag; import android.os.UserHandle; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.google.common.truth.Expect; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class UserInfoTest { public final class UserInfoTest { @Rule public final SetFlagsRule flags = new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT); @Rule public final Expect expect = Expect.create(); @Test public void testSimple() throws Exception { final UserInfo ui = new UserInfo(10, "Test", UserInfo.FLAG_GUEST); Loading Loading @@ -56,9 +81,6 @@ public class UserInfoTest { assertThat(ui.isInitialized()).isEqualTo(false); assertThat(ui.isFull()).isEqualTo(false); assertThat(ui.isMain()).isEqualTo(false); // Derived dynamically assertThat(ui.canHaveProfile()).isEqualTo(false); } @Test Loading @@ -68,4 +90,64 @@ public class UserInfoTest { assertThat(ui.toString()).isNotEmpty(); assertThat(ui.toFullString()).isNotEmpty(); } @Test @DisableFlags(android.multiuser.Flags.FLAG_PROFILES_FOR_ALL) public void testCanHaveProfile_flagProfilesForAllDisabled() { expectCannotHaveProfile("non-full user", createTestUserInfo(/* flags= */ 0)); expectCannotHaveProfile("guest user", createTestUserInfo(FLAG_FULL | FLAG_GUEST)); expectCanHaveProfile("main user", createTestUserInfo(FLAG_FULL | FLAG_MAIN)); expectCannotHaveProfile("non-main user", createTestUserInfo(FLAG_FULL)); expectCannotHaveProfile("demo user", createTestUserInfo(FLAG_FULL | FLAG_DEMO)); expectCannotHaveProfile("restricted user", createTestUserInfo(USER_TYPE_FULL_RESTRICTED, FLAG_FULL)); expectCannotHaveProfile("profile user", createTestUserInfo(FLAG_PROFILE)); expectCanHaveProfile("(full) system user that's also main user", createTestUserInfo(USER_TYPE_FULL_SYSTEM, FLAG_FULL | FLAG_SYSTEM | FLAG_MAIN)); expectCannotHaveProfile("headless system user that's not main user", createTestUserInfo(USER_TYPE_SYSTEM_HEADLESS, FLAG_SYSTEM)); } @Test @EnableFlags(android.multiuser.Flags.FLAG_PROFILES_FOR_ALL) public void testCanHaveProfile_flagProfilesForAllEnabled() { expectCannotHaveProfile("non-full user", createTestUserInfo(/* flags= */ 0)); expectCannotHaveProfile("guest user", createTestUserInfo(FLAG_FULL | FLAG_GUEST)); expectCanHaveProfile("main user", createTestUserInfo(FLAG_FULL | FLAG_MAIN)); expectCanHaveProfile("non-main user", createTestUserInfo(FLAG_FULL)); expectCannotHaveProfile("demo user", createTestUserInfo(FLAG_FULL | FLAG_DEMO)); expectCannotHaveProfile("restricted user", createTestUserInfo(USER_TYPE_FULL_RESTRICTED, FLAG_FULL)); expectCannotHaveProfile("profile user", createTestUserInfo(FLAG_PROFILE)); expectCanHaveProfile("(full) system user that's also main user", createTestUserInfo(USER_TYPE_FULL_SYSTEM, FLAG_FULL | FLAG_SYSTEM | FLAG_MAIN)); expectCannotHaveProfile("headless system user that's not main user", createTestUserInfo(USER_TYPE_SYSTEM_HEADLESS, FLAG_SYSTEM)); } /** * Creates a new {@link UserInfo} with id {@code 10}, name {@code Test}, and the given * {@code flags}. */ private UserInfo createTestUserInfo(@UserInfoFlag int flags) { return new UserInfo(10, "Test", flags); } /** * Creates a new {@link UserInfo} with id {@code 10}, name {@code Test}, and the given * {@code userType} and {@code flags}. */ private UserInfo createTestUserInfo(String userType, @UserInfoFlag int flags) { return new UserInfo(10, "Test", /* iconPath= */ null, flags, userType); } private void expectCanHaveProfile(String description, UserInfo user) { expect.withMessage("canHaveProfile() on %s (%s)", description, user) .that(user.canHaveProfile()).isTrue(); } private void expectCannotHaveProfile(String description, UserInfo user) { expect.withMessage("canHaveProfile() on %s (%s)", description, user) .that(user.canHaveProfile()).isFalse(); } } services/core/java/com/android/server/pm/UserManagerService.java +4 −0 Original line number Diff line number Diff line Loading @@ -7724,6 +7724,7 @@ public class UserManagerService extends IUserManager.Stub { pw.print(" Has profile owner: "); pw.println(mIsUserManaged.get(userId)); pw.println(" Restrictions:"); synchronized (mRestrictionsLock) { UserRestrictionsUtils.dumpRestrictions( Loading Loading @@ -7756,6 +7757,9 @@ public class UserManagerService extends IUserManager.Stub { } } pw.print(" Can have profile: "); pw.println(userInfo.canHaveProfile()); if (userData.userProperties != null) { userData.userProperties.println(pw, " "); } Loading services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -274,7 +274,7 @@ public class UserManagerServiceUserInfoTest { /** Test UserInfo.canHaveProfile for main user */ @Test public void testCanHaveProfile() throws Exception { UserInfo userInfo = createUser(100, FLAG_MAIN, null); UserInfo userInfo = createUser(100, FLAG_FULL | FLAG_MAIN, null); assertTrue("Main users can have profile", userInfo.canHaveProfile()); } Loading Loading
core/java/android/content/pm/UserInfo.java +6 −2 Original line number Diff line number Diff line Loading @@ -494,10 +494,14 @@ public class UserInfo implements Parcelable { // TODO(b/142482943): Make this logic more specific and customizable. (canHaveProfile(userType)) /* @hide */ public boolean canHaveProfile() { if (isProfile() || isGuest() || isRestricted()) { if (!isFull() || isProfile() || isGuest() || isRestricted() || isDemo()) { return false; } return isMain(); // NOTE: profiles used to be restricted just to the system user (and later to the main // user), but from the framework point of view there is no need for such restriction, hence // it's lifted // TODO(b/374832167): check value of config_supportProfilesOnNonMainUser return isMain() || android.multiuser.Flags.profilesForAll(); } // TODO(b/142482943): Get rid of this (after removing it from all tests) if feasible. Loading
core/java/android/content/pm/multiuser.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -646,3 +646,10 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "profiles_for_all" namespace: "multiuser" description: "Allows any regular user to have profiles" bug: "374832167" }
core/tests/coretests/src/android/content/pm/UserInfoTest.java +86 −4 Original line number Diff line number Diff line Loading @@ -16,19 +16,44 @@ package android.content.pm; import static android.content.pm.UserInfo.FLAG_DEMO; import static android.content.pm.UserInfo.FLAG_FULL; import static android.content.pm.UserInfo.FLAG_GUEST; import static android.content.pm.UserInfo.FLAG_MAIN; import static android.content.pm.UserInfo.FLAG_PROFILE; import static android.content.pm.UserInfo.FLAG_SYSTEM; import static android.os.UserManager.USER_TYPE_FULL_RESTRICTED; import static android.os.UserManager.USER_TYPE_FULL_SYSTEM; import static android.os.UserManager.USER_TYPE_SYSTEM_HEADLESS; import static com.google.common.truth.Truth.assertThat; import android.content.pm.UserInfo.UserInfoFlag; import android.os.UserHandle; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.google.common.truth.Expect; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class UserInfoTest { public final class UserInfoTest { @Rule public final SetFlagsRule flags = new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT); @Rule public final Expect expect = Expect.create(); @Test public void testSimple() throws Exception { final UserInfo ui = new UserInfo(10, "Test", UserInfo.FLAG_GUEST); Loading Loading @@ -56,9 +81,6 @@ public class UserInfoTest { assertThat(ui.isInitialized()).isEqualTo(false); assertThat(ui.isFull()).isEqualTo(false); assertThat(ui.isMain()).isEqualTo(false); // Derived dynamically assertThat(ui.canHaveProfile()).isEqualTo(false); } @Test Loading @@ -68,4 +90,64 @@ public class UserInfoTest { assertThat(ui.toString()).isNotEmpty(); assertThat(ui.toFullString()).isNotEmpty(); } @Test @DisableFlags(android.multiuser.Flags.FLAG_PROFILES_FOR_ALL) public void testCanHaveProfile_flagProfilesForAllDisabled() { expectCannotHaveProfile("non-full user", createTestUserInfo(/* flags= */ 0)); expectCannotHaveProfile("guest user", createTestUserInfo(FLAG_FULL | FLAG_GUEST)); expectCanHaveProfile("main user", createTestUserInfo(FLAG_FULL | FLAG_MAIN)); expectCannotHaveProfile("non-main user", createTestUserInfo(FLAG_FULL)); expectCannotHaveProfile("demo user", createTestUserInfo(FLAG_FULL | FLAG_DEMO)); expectCannotHaveProfile("restricted user", createTestUserInfo(USER_TYPE_FULL_RESTRICTED, FLAG_FULL)); expectCannotHaveProfile("profile user", createTestUserInfo(FLAG_PROFILE)); expectCanHaveProfile("(full) system user that's also main user", createTestUserInfo(USER_TYPE_FULL_SYSTEM, FLAG_FULL | FLAG_SYSTEM | FLAG_MAIN)); expectCannotHaveProfile("headless system user that's not main user", createTestUserInfo(USER_TYPE_SYSTEM_HEADLESS, FLAG_SYSTEM)); } @Test @EnableFlags(android.multiuser.Flags.FLAG_PROFILES_FOR_ALL) public void testCanHaveProfile_flagProfilesForAllEnabled() { expectCannotHaveProfile("non-full user", createTestUserInfo(/* flags= */ 0)); expectCannotHaveProfile("guest user", createTestUserInfo(FLAG_FULL | FLAG_GUEST)); expectCanHaveProfile("main user", createTestUserInfo(FLAG_FULL | FLAG_MAIN)); expectCanHaveProfile("non-main user", createTestUserInfo(FLAG_FULL)); expectCannotHaveProfile("demo user", createTestUserInfo(FLAG_FULL | FLAG_DEMO)); expectCannotHaveProfile("restricted user", createTestUserInfo(USER_TYPE_FULL_RESTRICTED, FLAG_FULL)); expectCannotHaveProfile("profile user", createTestUserInfo(FLAG_PROFILE)); expectCanHaveProfile("(full) system user that's also main user", createTestUserInfo(USER_TYPE_FULL_SYSTEM, FLAG_FULL | FLAG_SYSTEM | FLAG_MAIN)); expectCannotHaveProfile("headless system user that's not main user", createTestUserInfo(USER_TYPE_SYSTEM_HEADLESS, FLAG_SYSTEM)); } /** * Creates a new {@link UserInfo} with id {@code 10}, name {@code Test}, and the given * {@code flags}. */ private UserInfo createTestUserInfo(@UserInfoFlag int flags) { return new UserInfo(10, "Test", flags); } /** * Creates a new {@link UserInfo} with id {@code 10}, name {@code Test}, and the given * {@code userType} and {@code flags}. */ private UserInfo createTestUserInfo(String userType, @UserInfoFlag int flags) { return new UserInfo(10, "Test", /* iconPath= */ null, flags, userType); } private void expectCanHaveProfile(String description, UserInfo user) { expect.withMessage("canHaveProfile() on %s (%s)", description, user) .that(user.canHaveProfile()).isTrue(); } private void expectCannotHaveProfile(String description, UserInfo user) { expect.withMessage("canHaveProfile() on %s (%s)", description, user) .that(user.canHaveProfile()).isFalse(); } }
services/core/java/com/android/server/pm/UserManagerService.java +4 −0 Original line number Diff line number Diff line Loading @@ -7724,6 +7724,7 @@ public class UserManagerService extends IUserManager.Stub { pw.print(" Has profile owner: "); pw.println(mIsUserManaged.get(userId)); pw.println(" Restrictions:"); synchronized (mRestrictionsLock) { UserRestrictionsUtils.dumpRestrictions( Loading Loading @@ -7756,6 +7757,9 @@ public class UserManagerService extends IUserManager.Stub { } } pw.print(" Can have profile: "); pw.println(userInfo.canHaveProfile()); if (userData.userProperties != null) { userData.userProperties.println(pw, " "); } Loading
services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -274,7 +274,7 @@ public class UserManagerServiceUserInfoTest { /** Test UserInfo.canHaveProfile for main user */ @Test public void testCanHaveProfile() throws Exception { UserInfo userInfo = createUser(100, FLAG_MAIN, null); UserInfo userInfo = createUser(100, FLAG_FULL | FLAG_MAIN, null); assertTrue("Main users can have profile", userInfo.canHaveProfile()); } Loading