In the stopping/shutdown state return unlock state of the user key
UserManager.isUserUnlocked should return true when user is stopping,
but encryption key is unlocked. Otherwise it causes issues in
non-cryptoaware apps that can can run while user is in STATE_STOPPING
Test: create/start/remove managed profiles in a loop and verify there
are no app or system crashes
Bug: 38212686
Change-Id: I47aa520269aafe3d3c967b6841ff46e765c446bd
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index a64ab43..553e3c6 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -949,7 +949,7 @@
@Override
public boolean isUserUnlocked(int userId) {
checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isUserUnlocked");
- return mLocalService.isUserUnlockingOrUnlocked(userId);
+ return mLocalService.isUserUnlocked(userId);
}
@Override
@@ -3692,19 +3692,29 @@
@Override
public boolean isUserUnlockingOrUnlocked(int userId) {
+ int state;
synchronized (mUserStates) {
- int state = mUserStates.get(userId, -1);
- return (state == UserState.STATE_RUNNING_UNLOCKING)
- || (state == UserState.STATE_RUNNING_UNLOCKED);
+ state = mUserStates.get(userId, -1);
}
+ // Special case, in the stopping/shutdown state user key can still be unlocked
+ if (state == UserState.STATE_STOPPING || state == UserState.STATE_SHUTDOWN) {
+ return StorageManager.isUserKeyUnlocked(userId);
+ }
+ return (state == UserState.STATE_RUNNING_UNLOCKING)
+ || (state == UserState.STATE_RUNNING_UNLOCKED);
}
@Override
public boolean isUserUnlocked(int userId) {
+ int state;
synchronized (mUserStates) {
- int state = mUserStates.get(userId, -1);
- return state == UserState.STATE_RUNNING_UNLOCKED;
+ state = mUserStates.get(userId, -1);
}
+ // Special case, in the stopping/shutdown state user key can still be unlocked
+ if (state == UserState.STATE_STOPPING || state == UserState.STATE_SHUTDOWN) {
+ return StorageManager.isUserKeyUnlocked(userId);
+ }
+ return state == UserState.STATE_RUNNING_UNLOCKED;
}
}