Fix new user creation regression due to vold remount calls

When creating a new user, there's no need to call into vold when
setting up default system permissions for storage. This was otherwise
adding 2 seconds to the user creation time, causing a frozen screen
before showing "Switching to user ...".

Fix is to call the permission setup code synchronously and not
call into vold if the user hasn't been initialized yet.

Bug: 22356546
Change-Id: I4c8632813e8c0f2ac90da386691af439521bb25a
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 5e37df3..bfb803d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3458,8 +3458,12 @@
             mSettings.writeRuntimePermissionsForUserLPr(userId, false);
         }
 
-        if (READ_EXTERNAL_STORAGE.equals(name)
-                || WRITE_EXTERNAL_STORAGE.equals(name)) {
+        // Only need to do this if user is initialized. Otherwise it's a new user
+        // and there are no processes running as the user yet and there's no need
+        // to make an expensive call to remount processes for the changed permissions.
+        if ((READ_EXTERNAL_STORAGE.equals(name)
+                || WRITE_EXTERNAL_STORAGE.equals(name))
+                && sUserManager.isInitialized(userId)) {
             final long token = Binder.clearCallingIdentity();
             try {
                 final StorageManager storage = mContext.getSystemService(StorageManager.class);
@@ -15965,16 +15969,8 @@
         }
     }
 
-    void newUserCreatedLILPw(final int userHandle) {
-        // We cannot grant the default permissions with a lock held as
-        // we query providers from other components for default handlers
-        // such as enabled IMEs, etc.
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                mDefaultPermissionPolicy.grantDefaultPermissions(userHandle);
-            }
-        });
+    void newUserCreated(final int userHandle) {
+        mDefaultPermissionPolicy.grantDefaultPermissions(userHandle);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 1a79b4e..23cb767 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1220,6 +1220,7 @@
         final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
         final long ident = Binder.clearCallingIdentity();
         UserInfo userInfo = null;
+        final int userId;
         try {
             synchronized (mInstallLock) {
                 synchronized (mPackagesLock) {
@@ -1240,7 +1241,7 @@
                     if (isGuest && findCurrentGuestUserLocked() != null) {
                         return null;
                     }
-                    int userId = getNextAvailableIdLocked();
+                    userId = getNextAvailableIdLocked();
                     userInfo = new UserInfo(userId, name, null, flags);
                     userInfo.serialNumber = mNextSerialNumber++;
                     long now = System.currentTimeMillis();
@@ -1274,9 +1275,9 @@
                     updateUserIdsLocked();
                     Bundle restrictions = new Bundle();
                     mUserRestrictions.append(userId, restrictions);
-                    mPm.newUserCreatedLILPw(userId);
                 }
             }
+            mPm.newUserCreated(userId);
             if (userInfo != null) {
                 Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
                 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userInfo.id);
@@ -2015,4 +2016,12 @@
             }
         }
     }
+
+    /**
+     * @param userId
+     * @return whether the user has been initialized yet
+     */
+    boolean isInitialized(int userId) {
+        return (getUserInfo(userId).flags & UserInfo.FLAG_INITIALIZED) != 0;
+    }
 }