diff options
| -rw-r--r-- | core/java/android/os/IUserManager.aidl | 2 | ||||
| -rw-r--r-- | core/java/android/os/UserManager.java | 28 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/UserManagerService.java | 104 |
3 files changed, 116 insertions, 18 deletions
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index f643c578ebe7..01d6b022043f 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -98,4 +98,6 @@ interface IUserManager { boolean isUserNameSet(int userHandle); boolean hasRestrictedProfiles(); boolean trySetQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userHandle, in IntentSender target); + long getUserStartRealtime(); + long getUserUnlockRealtime(); } diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 38993b71a31d..44238df108cf 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1392,6 +1392,34 @@ public class UserManager { } /** + * Return the time when the calling user started in elapsed milliseconds since boot, + * or 0 if not started. + * + * @hide + */ + public long getUserStartRealtime() { + try { + return mService.getUserStartRealtime(); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** + * Return the time when the calling user was unlocked elapsed milliseconds since boot, + * or 0 if not unlocked. + * + * @hide + */ + public long getUserUnlockRealtime() { + try { + return mService.getUserUnlockRealtime(); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** * Returns the UserInfo object describing a specific user. * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. * @param userHandle the user handle of the user whose information is being requested. diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index c3dce3133026..7d575668da94 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -63,6 +63,7 @@ import android.os.SELinux; import android.os.ServiceManager; import android.os.ShellCallback; import android.os.ShellCommand; +import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; @@ -79,6 +80,7 @@ import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; +import android.util.SparseLongArray; import android.util.TimeUtils; import android.util.Xml; @@ -241,8 +243,7 @@ public class UserManagerService extends IUserManager.Stub { private static final IBinder mUserRestriconToken = new Binder(); /** - * User-related information that is used for persisting to flash. Only UserInfo is - * directly exposed to other system apps. + * Internal non-parcelable wrapper for UserInfo that is not exposed to other system apps. */ @VisibleForTesting static class UserData { @@ -260,6 +261,12 @@ public class UserManagerService extends IUserManager.Stub { // Whether to perist the seed account information to be available after a boot boolean persistSeedData; + /** Elapsed realtime since boot when the user started. */ + long startRealtime; + + /** Elapsed realtime since boot when the user was unlocked. */ + long unlockRealtime; + void clearSeedAccountData() { seedAccountName = null; seedAccountType = null; @@ -453,6 +460,37 @@ public class UserManagerService extends IUserManager.Stub { mUms.cleanupPartialUsers(); } } + + @Override + public void onStartUser(int userHandle) { + synchronized (mUms.mUsersLock) { + final UserData user = mUms.getUserDataLU(userHandle); + if (user != null) { + user.startRealtime = SystemClock.elapsedRealtime(); + } + } + } + + @Override + public void onUnlockUser(int userHandle) { + synchronized (mUms.mUsersLock) { + final UserData user = mUms.getUserDataLU(userHandle); + if (user != null) { + user.unlockRealtime = SystemClock.elapsedRealtime(); + } + } + } + + @Override + public void onStopUser(int userHandle) { + synchronized (mUms.mUsersLock) { + final UserData user = mUms.getUserDataLU(userHandle); + if (user != null) { + user.startRealtime = 0; + user.unlockRealtime = 0; + } + } + } } // TODO b/28848102 Add support for test dependencies injection @@ -1057,6 +1095,29 @@ public class UserManagerService extends IUserManager.Stub { return mLocalService.isUserRunning(userId); } + @Override + public long getUserStartRealtime() { + final int userId = UserHandle.getUserId(Binder.getCallingUid()); + synchronized (mUsersLock) { + final UserData user = getUserDataLU(userId); + if (user != null) { + return user.startRealtime; + } + return 0; + } + } + + @Override + public long getUserUnlockRealtime() { + synchronized (mUsersLock) { + final UserData user = getUserDataLU(UserHandle.getUserId(Binder.getCallingUid())); + if (user != null) { + return user.unlockRealtime; + } + return 0; + } + } + private void checkManageOrInteractPermIfCallerInOtherProfileGroup(int userId, String name) { int callingUserId = UserHandle.getCallingUserId(); if (callingUserId == userId || isSameProfileGroupNoChecks(callingUserId, userId) || @@ -3484,6 +3545,7 @@ public class UserManagerService extends IUserManager.Stub { if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return; long now = System.currentTimeMillis(); + final long nowRealtime = SystemClock.elapsedRealtime(); StringBuilder sb = new StringBuilder(); synchronized (mPackagesLock) { synchronized (mUsersLock) { @@ -3511,25 +3573,20 @@ public class UserManagerService extends IUserManager.Stub { } pw.println(UserState.stateToString(state)); pw.print(" Created: "); - if (userInfo.creationTime == 0) { - pw.println("<unknown>"); - } else { - sb.setLength(0); - TimeUtils.formatDuration(now - userInfo.creationTime, sb); - sb.append(" ago"); - pw.println(sb); - } + dumpTimeAgo(pw, sb, now, userInfo.creationTime); + pw.print(" Last logged in: "); - if (userInfo.lastLoggedInTime == 0) { - pw.println("<unknown>"); - } else { - sb.setLength(0); - TimeUtils.formatDuration(now - userInfo.lastLoggedInTime, sb); - sb.append(" ago"); - pw.println(sb); - } + dumpTimeAgo(pw, sb, now, userInfo.lastLoggedInTime); + pw.print(" Last logged in fingerprint: "); pw.println(userInfo.lastLoggedInFingerprint); + + pw.print(" Start time: "); + dumpTimeAgo(pw, sb, nowRealtime, userData.startRealtime); + + pw.print(" Unlock time: "); + dumpTimeAgo(pw, sb, nowRealtime, userData.unlockRealtime); + pw.print(" Has profile owner: "); pw.println(mIsUserManaged.get(userId)); pw.println(" Restrictions:"); @@ -3593,6 +3650,17 @@ public class UserManagerService extends IUserManager.Stub { } } + private static void dumpTimeAgo(PrintWriter pw, StringBuilder sb, long nowTime, long time) { + if (time == 0) { + pw.println("<unknown>"); + } else { + sb.setLength(0); + TimeUtils.formatDuration(nowTime - time, sb); + sb.append(" ago"); + pw.println(sb); + } + } + final class MainHandler extends Handler { @Override |