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

Commit 81299d54 authored by Oli Lan's avatar Oli Lan
Browse files

Headless: Switch to supplied user or previous user after boot.

This adds a system API to specify which user should be switched to
after boot on headless, for use by Automotive devices (for example).

On headless, after boot, the foreground user will be the specified user,
if there is one, or the previous foreground user otherwise.

Bug: 242195409
Test: atest UserManagerServiceTest
Change-Id: I16971511a1303ca718051917c6618655ef0c87b1
parent 7cc40702
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10411,6 +10411,7 @@ package android.os {
    method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.MANAGE_USERS"}) public boolean isUserVisible();
    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean removeUser(@NonNull android.os.UserHandle);
    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public int removeUserWhenPossible(@NonNull android.os.UserHandle, boolean);
    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public void setBootUser(@NonNull android.os.UserHandle);
    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(@NonNull android.graphics.Bitmap) throws android.os.UserManager.UserOperationException;
    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserName(@Nullable String);
    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean someUserHasAccount(@NonNull String, @NonNull String);
+1 −0
Original line number Diff line number Diff line
@@ -2025,6 +2025,7 @@ package android.os {
    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createProfileForUser(@Nullable String, @NonNull String, int, int, @Nullable String[]);
    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createRestrictedProfile(@Nullable String);
    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createUser(@Nullable String, @NonNull String, int);
    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.os.UserHandle getBootUser();
    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.Set<java.lang.String> getPreInstallableSystemPackages(@NonNull String);
    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public String getUserType();
    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List<android.content.pm.UserInfo> getUsers(boolean, boolean, boolean);
+4 −0
Original line number Diff line number Diff line
@@ -142,4 +142,8 @@ interface IUserManager {
    long getUserStartRealtime();
    long getUserUnlockRealtime();
    boolean setUserEphemeral(int userId, boolean enableEphemeral);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS})")
    void setBootUser(int userId);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS})")
    int getBootUser();
}
+34 −0
Original line number Diff line number Diff line
@@ -5656,6 +5656,40 @@ public class UserManager {
        }
    }

    /**
     * Sets the user who should be in the foreground when boot completes. This should be called
     * during boot, and the provided user must be a full user (i.e. not a profile).
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
            Manifest.permission.CREATE_USERS})
    public void setBootUser(@NonNull UserHandle bootUser) {
        try {
            mService.setBootUser(bootUser.getIdentifier());
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Returns the user who should be in the foreground when boot completes.
     *
     * @hide
     */
    @TestApi
    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
            Manifest.permission.CREATE_USERS})
    @SuppressWarnings("[AndroidFrameworkContextUserId]")
    public @NonNull UserHandle getBootUser() {
        try {
            return UserHandle.of(mService.getBootUser());
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /* Cache key for anything that assumes that userIds cannot be re-used without rebooting. */
    private static final String CACHE_KEY_STATIC_USER_PROPERTIES = "cache_key.static_user_props";

+16 −0
Original line number Diff line number Diff line
@@ -485,4 +485,20 @@ public abstract class UserManagerInternal {
     * @see UserManager#isMainUser()
     */
    public abstract @UserIdInt int getMainUserId();

    /**
     * Returns the id of the user which should be in the foreground after boot completes.
     *
     * <p>If a boot user has been provided by calling {@link UserManager#setBootUser}, the
     * returned value will be whatever was specified, as long as that user exists and can be
     * switched to.
     *
     * <p>Otherwise, in {@link UserManager#isHeadlessSystemUserMode() headless system user mode},
     * this will be the user who was last in the foreground on this device. If there is no
     * switchable user on the device, a new user will be created and its id will be returned.
     *
     * <p>In non-headless system user mode, the return value will be {@link UserHandle#USER_SYSTEM}.
     */
    public abstract @UserIdInt int getBootUser()
            throws UserManager.CheckedUserOperationException;
}
Loading