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

This commit is contained in:
Oli Lan
2022-12-01 09:56:45 +00:00
committed by Android (Google) Code Review
4 changed files with 95 additions and 0 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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.
*

View File

@@ -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:");