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

Commit 4e19d54a authored by Oli Lan's avatar Oli Lan Committed by Android (Google) Code Review
Browse files

Merge "Add system API to get the previous user."

parents 3d0a6c17 c59305fb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10097,6 +10097,7 @@ package android.os {
    method @NonNull public java.util.List<android.os.UserHandle> getAllProfiles();
    method @NonNull public java.util.List<android.os.UserHandle> getEnabledProfiles();
    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public android.os.UserHandle getMainUser();
    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public android.os.UserHandle getPreviousForegroundUser();
    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public android.os.UserHandle getProfileParent(@NonNull android.os.UserHandle);
    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public int getRemainingCreatableProfileCount(@NonNull String);
    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public int getRemainingCreatableUserCount(@NonNull String);
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ interface IUserManager {
    ParcelFileDescriptor getUserIcon(int userId);
    UserInfo getPrimaryUser();
    int getMainUserId();
    int getPreviousFullUserToEnterForeground();
    List<UserInfo> getUsers(boolean excludePartial, boolean excludeDying, boolean excludePreCreated);
    List<UserInfo> getProfiles(int userId, boolean enabledOnly);
    int[] getProfileIds(int userId, boolean enabledOnly);
+37 −0
Original line number Diff line number Diff line
@@ -4299,6 +4299,43 @@ public class UserManager {
        }
    }

    /**
     * Returns the user who was last in the foreground, not including the current user and not
     * including profiles.
     *
     * <p>Returns {@code null} if there is no previous user, for example if there
     * is only one full user (i.e. only one user which is not a profile) on the device.
     *
     * <p>This method may be used for example to find the user to switch back to if the
     * current user is removed, or if creating a new user is aborted.
     *
     * <p>Note that reboots do not interrupt this calculation; the previous user need not have
     * used the device since it rebooted.
     *
     * <p>Note also that on devices that support multiple users on multiple displays, it is possible
     * that the returned user will be visible on a secondary display, as the foreground user is the
     * one associated with the main display.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(anyOf = {
            android.Manifest.permission.MANAGE_USERS,
            android.Manifest.permission.CREATE_USERS,
            android.Manifest.permission.QUERY_USERS
    })
    public @Nullable UserHandle getPreviousForegroundUser() {
        try {
            final int previousUser = mService.getPreviousFullUserToEnterForeground();
            if (previousUser == UserHandle.USER_NULL) {
                return null;
            }
            return UserHandle.of(previousUser);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Checks whether it's possible to add more users.
     *
+56 −0
Original line number Diff line number Diff line
@@ -191,6 +191,7 @@ public class UserManagerService extends IUserManager.Stub {
    private static final String ATTR_CREATION_TIME = "created";
    private static final String ATTR_LAST_LOGGED_IN_TIME = "lastLoggedIn";
    private static final String ATTR_LAST_LOGGED_IN_FINGERPRINT = "lastLoggedInFingerprint";
    private static final String ATTR_LAST_ENTERED_FOREGROUND_TIME = "lastEnteredForeground";
    private static final String ATTR_SERIAL_NO = "serialNumber";
    private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber";
    private static final String ATTR_PARTIAL = "partial";
@@ -341,6 +342,9 @@ public class UserManagerService extends IUserManager.Stub {
        /** Elapsed realtime since boot when the user was unlocked. */
        long unlockRealtime;

        /** Wall clock time in millis when the user last entered the foreground. */
        long mLastEnteredForegroundTimeMillis;

        private long mLastRequestQuietModeEnabledMillis;

        /**
@@ -680,6 +684,10 @@ public class UserManagerService extends IUserManager.Stub {
                final UserData user = mUms.getUserDataLU(targetUser.getUserIdentifier());
                if (user != null) {
                    user.startRealtime = SystemClock.elapsedRealtime();
                    if (targetUser.getUserIdentifier() == UserHandle.USER_SYSTEM
                            && targetUser.isFull()) {
                        mUms.setLastEnteredForegroundTimeToNow(user);
                    }
                }
            }
        }
@@ -694,6 +702,16 @@ public class UserManagerService extends IUserManager.Stub {
            }
        }

        @Override
        public void onUserSwitching(@NonNull TargetUser from, @NonNull TargetUser to) {
            synchronized (mUms.mUsersLock) {
                final UserData user = mUms.getUserDataLU(to.getUserIdentifier());
                if (user != null) {
                    mUms.setLastEnteredForegroundTimeToNow(user);
                }
            }
        }

        @Override
        public void onUserStopping(@NonNull TargetUser targetUser) {
            synchronized (mUms.mUsersLock) {
@@ -920,6 +938,30 @@ public class UserManagerService extends IUserManager.Stub {
        return UserHandle.USER_NULL;
    }

    @Override
    public int getPreviousFullUserToEnterForeground() {
        checkQueryOrCreateUsersPermission("get previous user");
        int previousUser = UserHandle.USER_NULL;
        long latestEnteredTime = 0;
        final int currentUser = getCurrentUserId();
        synchronized (mUsersLock) {
            final int userSize = mUsers.size();
            for (int i = 0; i < userSize; i++) {
                final UserData userData = mUsers.valueAt(i);
                final int userId = userData.info.id;
                if (userId != currentUser && userData.info.isFull() && !userData.info.partial
                        && !mRemovingUserIds.get(userId)) {
                    final long userEnteredTime = userData.mLastEnteredForegroundTimeMillis;
                    if (userEnteredTime > latestEnteredTime) {
                        latestEnteredTime = userEnteredTime;
                        previousUser = userId;
                    }
                }
            }
        }
        return previousUser;
    }

    public @NonNull List<UserInfo> getUsers(boolean excludeDying) {
        return getUsers(/*excludePartial= */ true, excludeDying, /* excludePreCreated= */
                true);
@@ -3973,6 +4015,8 @@ public class UserManagerService extends IUserManager.Stub {
            serializer.attribute(null, ATTR_LAST_LOGGED_IN_FINGERPRINT,
                    userInfo.lastLoggedInFingerprint);
        }
        serializer.attributeLong(
                null, ATTR_LAST_ENTERED_FOREGROUND_TIME, userData.mLastEnteredForegroundTimeMillis);
        if (userInfo.iconPath != null) {
            serializer.attribute(null,  ATTR_ICON_PATH, userInfo.iconPath);
        }
@@ -4146,6 +4190,7 @@ public class UserManagerService extends IUserManager.Stub {
        long lastLoggedInTime = 0L;
        long lastRequestQuietModeEnabledTimestamp = 0L;
        String lastLoggedInFingerprint = null;
        long lastEnteredForegroundTime = 0L;
        int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
        int profileBadge = 0;
        int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID;
@@ -4191,6 +4236,8 @@ public class UserManagerService extends IUserManager.Stub {
            lastLoggedInTime = parser.getAttributeLong(null, ATTR_LAST_LOGGED_IN_TIME, 0);
            lastLoggedInFingerprint = parser.getAttributeValue(null,
                    ATTR_LAST_LOGGED_IN_FINGERPRINT);
            lastEnteredForegroundTime =
                    parser.getAttributeLong(null, ATTR_LAST_ENTERED_FOREGROUND_TIME, 0L);
            profileGroupId = parser.getAttributeInt(null, ATTR_PROFILE_GROUP_ID,
                    UserInfo.NO_PROFILE_GROUP_ID);
            profileBadge = parser.getAttributeInt(null, ATTR_PROFILE_BADGE, 0);
@@ -4285,6 +4332,7 @@ public class UserManagerService extends IUserManager.Stub {
        userData.seedAccountOptions = seedAccountOptions;
        userData.userProperties = userProperties;
        userData.setLastRequestQuietModeEnabledMillis(lastRequestQuietModeEnabledTimestamp);
        userData.mLastEnteredForegroundTimeMillis = lastEnteredForegroundTime;
        if (ignorePrepareStorageErrors) {
            userData.setIgnorePrepareStorageErrors();
        }
@@ -6204,6 +6252,11 @@ public class UserManagerService extends IUserManager.Stub {
                        || someUserHasSeedAccountNoChecks(accountName, accountType));
    }

    private void setLastEnteredForegroundTimeToNow(@NonNull UserData userData) {
        userData.mLastEnteredForegroundTimeMillis = System.currentTimeMillis();
        scheduleWriteUser(userData);
    }

    @Override
    public void onShellCommand(FileDescriptor in, FileDescriptor out,
            FileDescriptor err, String[] args, ShellCallback callback,
@@ -6428,6 +6481,9 @@ public class UserManagerService extends IUserManager.Stub {
        pw.print("    Unlock time: ");
        dumpTimeAgo(pw, tempStringBuilder, nowRealtime, userData.unlockRealtime);

        pw.print("    Last entered foreground: ");
        dumpTimeAgo(pw, tempStringBuilder, now, userData.mLastEnteredForegroundTimeMillis);

        pw.print("    Has profile owner: ");
        pw.println(mIsUserManaged.get(userId));
        pw.println("    Restrictions:");