OSDN Git Service

Push unlocking/unlocked state to UserManager
authorFyodor Kupolov <fkupolov@google.com>
Tue, 10 May 2016 02:10:53 +0000 (19:10 -0700)
committerFyodor Kupolov <fkupolov@google.com>
Tue, 10 May 2016 18:09:02 +0000 (11:09 -0700)
Push unlocking/unlocked state to UserManagerInternal when it's changed in
UserController. Use UserManagerInternal.isUserUnlockingOrUnlocked when
updating flags for filtering in PackageManager.

Bug: 28629076
Change-Id: I8440af090f533f93870d0cff0e3871e114c37efa

core/java/android/os/UserManager.java
core/java/android/os/UserManagerInternal.java
services/core/java/com/android/server/am/UserController.java
services/core/java/com/android/server/pm/PackageManagerService.java
services/core/java/com/android/server/pm/UserManagerService.java

index d55201f..1948df9 100644 (file)
@@ -998,6 +998,7 @@ public class UserManager {
 
     /** {@hide} */
     public boolean isUserUnlockingOrUnlocked(@UserIdInt int userId) {
+        // TODO Switch to using UMS internal isUserUnlockingOrUnlocked
         try {
             return ActivityManagerNative.getDefault().isUserRunning(userId,
                     ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED);
index f399719..551ea6b 100644 (file)
@@ -126,4 +126,18 @@ public abstract class UserManagerInternal {
      * createAndManageUser is called by the device owner.
      */
     public abstract UserInfo createUserEvenWhenDisallowed(String name, int flags);
+
+    /**
+     * Return whether the given user is running in an
+     * {@link com.android.server.am.UserState#STATE_RUNNING_UNLOCKING "unlocking"} or
+     * {@link com.android.server.am.UserState#STATE_RUNNING_UNLOCKED "unlocked"} state.
+     */
+    public abstract boolean isUserUnlockingOrUnlocked(int userId);
+
+    /**
+     * Sets whether the given user is running in an
+     * {@link com.android.server.am.UserState#STATE_RUNNING_UNLOCKING "unlocking"} or
+     * {@link com.android.server.am.UserState#STATE_RUNNING_UNLOCKED "unlocked"} state.
+     */
+    public abstract void setUserUnlockingOrUnlocked(int userId, boolean unlockingOrUnlocked);
 }
index e8f4b3e..c4e39c9 100644 (file)
@@ -18,6 +18,7 @@ package com.android.server.am;
 
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.app.ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED;
 import static android.app.ActivityManager.USER_OP_ERROR_IS_SYSTEM;
 import static android.app.ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
 import static android.app.ActivityManager.USER_OP_IS_CURRENT;
@@ -157,6 +158,8 @@ final class UserController {
 
     private final LockPatternUtils mLockPatternUtils;
 
+    private UserManagerInternal mUserManagerInternal;
+
     UserController(ActivityManagerService service) {
         mService = service;
         mHandler = mService.mHandler;
@@ -273,6 +276,7 @@ final class UserController {
             if (!StorageManager.isUserKeyUnlocked(userId)) return;
 
             if (uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
+                getUserManagerInternal().setUserUnlockingOrUnlocked(userId, true);
                 uss.mUnlockProgress.start();
 
                 // Prepare app storage before we go any further
@@ -303,6 +307,7 @@ final class UserController {
             if (!StorageManager.isUserKeyUnlocked(userId)) return;
 
             if (uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
+                getUserManagerInternal().setUserUnlockingOrUnlocked(userId, true);
                 uss.mUnlockProgress.finish();
 
                 // Dispatch unlocked to external apps
@@ -476,6 +481,7 @@ final class UserController {
         if (uss.state != UserState.STATE_STOPPING
                 && uss.state != UserState.STATE_SHUTDOWN) {
             uss.setState(UserState.STATE_STOPPING);
+            getUserManagerInternal().setUserUnlockingOrUnlocked(userId, false);
             updateStartedUserArrayLocked();
 
             long ident = Binder.clearCallingIdentity();
@@ -537,6 +543,7 @@ final class UserController {
             }
             uss.setState(UserState.STATE_SHUTDOWN);
         }
+        getUserManagerInternal().setUserUnlockingOrUnlocked(userId, false);
 
         mService.mBatteryStatsService.noteEvent(
                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
@@ -806,6 +813,9 @@ final class UserController {
                     // so we can just fairly silently bring the user back from
                     // the almost-dead.
                     uss.setState(uss.lastState);
+                    if (isUserRunningLocked(userId, FLAG_AND_UNLOCKING_OR_UNLOCKED)) {
+                        getUserManagerInternal().setUserUnlockingOrUnlocked(userId, true);
+                    }
                     updateStartedUserArrayLocked();
                     needStart = true;
                 } else if (uss.state == UserState.STATE_SHUTDOWN) {
@@ -1465,6 +1475,13 @@ final class UserController {
         return mLockPatternUtils.isLockScreenDisabled(userId);
     }
 
+    private UserManagerInternal getUserManagerInternal() {
+        if (mUserManagerInternal == null) {
+            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
+        }
+        return mUserManagerInternal;
+    }
+
     void dump(PrintWriter pw, boolean dumpAll) {
         pw.println("  mStartedUsers:");
         for (int i = 0; i < mStartedUsers.size(); i++) {
index d7693b0..5c45b0f 100644 (file)
@@ -190,6 +190,7 @@ import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.UserManagerInternal;
 import android.os.storage.IMountService;
 import android.os.storage.MountServiceInternal;
 import android.os.storage.StorageEventListener;
@@ -739,6 +740,8 @@ public class PackageManagerService extends IPackageManager.Stub {
     // List of packages names to keep cached, even if they are uninstalled for all users
     private List<String> mKeepUninstalledPackages;
 
+    private UserManagerInternal mUserManagerInternal;
+
     private static class IFVerificationParams {
         PackageParser.Package pkg;
         boolean replacing;
@@ -3481,7 +3484,7 @@ public class PackageManagerService extends IPackageManager.Stub {
             // give them what they want
         } else {
             // Caller expressed no opinion, so match based on user state
-            if (StorageManager.isUserKeyUnlocked(userId)) {
+            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
             } else {
                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
@@ -3490,6 +3493,13 @@ public class PackageManagerService extends IPackageManager.Stub {
         return flags;
     }
 
+    private UserManagerInternal getUserManagerInternal() {
+        if (mUserManagerInternal == null) {
+            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
+        }
+        return mUserManagerInternal;
+    }
+
     /**
      * Update given flags when being used to request {@link PackageInfo}.
      */
index a2d859b..6b0e582 100644 (file)
@@ -320,6 +320,9 @@ public class UserManagerService extends IUserManager.Stub {
     @GuardedBy("mUsersLock")
     private boolean mForceEphemeralUsers;
 
+    @GuardedBy("mUsersLock")
+    private final SparseBooleanArray mUnlockingOrUnlockedUsers = new SparseBooleanArray();
+
     private static UserManagerService sInstance;
 
     public static UserManagerService getInstance() {
@@ -2302,6 +2305,7 @@ public class UserManagerService extends IUserManager.Stub {
         synchronized (mUsersLock) {
             mUsers.remove(userHandle);
             mIsUserManaged.delete(userHandle);
+            mUnlockingOrUnlockedUsers.delete(userHandle);
         }
         synchronized (mRestrictionsLock) {
             mBaseUserRestrictions.remove(userHandle);
@@ -3159,6 +3163,20 @@ public class UserManagerService extends IUserManager.Stub {
             }
             return user;
         }
+
+        @Override
+        public void setUserUnlockingOrUnlocked(int userId, boolean unlockingOrUnlocked) {
+            synchronized (mUsersLock) {
+                mUnlockingOrUnlockedUsers.put(userId, unlockingOrUnlocked);
+            }
+        }
+
+        @Override
+        public boolean isUserUnlockingOrUnlocked(int userId) {
+            synchronized (mUsersLock) {
+                return mUnlockingOrUnlockedUsers.get(userId);
+            }
+        }
     }
 
     /* Remove all the users except of the system one. */