diff options
| -rw-r--r-- | services/core/java/com/android/server/am/UserController.java | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 2df5dc93768c..4e3d8d27e0f9 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -89,6 +89,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; import com.android.internal.widget.LockPatternUtils; +import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.SystemServiceManager; import com.android.server.pm.UserManagerService; @@ -355,27 +356,35 @@ class UserController implements Handler.Callback { // Only keep marching forward if user is actually unlocked if (!StorageManager.isUserKeyUnlocked(userId)) return; synchronized (mLock) { - // Bail if we ended up with a stale user - if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return; - - // Do not proceed if unexpected state - if (!uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) { + // Do not proceed if unexpected state or a stale user + if (mStartedUsers.get(userId) != uss || uss.state != STATE_RUNNING_LOCKED) { return; } } - mInjector.getUserManagerInternal().setUserState(userId, uss.state); uss.mUnlockProgress.start(); // Prepare app storage before we go any further uss.mUnlockProgress.setProgress(5, mInjector.getContext().getString(R.string.android_start_title)); - mInjector.getUserManager().onBeforeUnlockUser(userId); - uss.mUnlockProgress.setProgress(20); - // Dispatch unlocked to system services; when fully dispatched, - // that calls through to the next "unlocked" phase - mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss) - .sendToTarget(); + // Call onBeforeUnlockUser on a worker thread that allows disk I/O + FgThread.getHandler().post(() -> { + mInjector.getUserManager().onBeforeUnlockUser(userId); + synchronized (mLock) { + // Do not proceed if unexpected state + if (!uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) { + return; + } + } + mInjector.getUserManagerInternal().setUserState(userId, uss.state); + + uss.mUnlockProgress.setProgress(20); + + // Dispatch unlocked to system services; when fully dispatched, + // that calls through to the next "unlocked" phase + mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss) + .sendToTarget(); + }); } /** @@ -1819,7 +1828,10 @@ class UserController implements Handler.Callback { case SYSTEM_USER_UNLOCK_MSG: final int userId = msg.arg1; mInjector.getSystemServiceManager().unlockUser(userId); - mInjector.loadUserRecents(userId); + // Loads recents on a worker thread that allows disk I/O + FgThread.getHandler().post(() -> { + mInjector.loadUserRecents(userId); + }); if (userId == UserHandle.USER_SYSTEM) { mInjector.startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE); } |