Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a1bddc1 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Allow profiles on any full user." into main

parents 54e1fd1f f2170ca5
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -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.
+7 −0
Original line number Diff line number Diff line
@@ -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"
}
+86 −4
Original line number Diff line number Diff line
@@ -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);
@@ -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
@@ -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();
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -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(
@@ -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, "    ");
        }
+1 −1
Original line number Diff line number Diff line
@@ -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());
    }