diff options
| author | 2017-11-14 11:43:40 -0800 | |
|---|---|---|
| committer | 2017-11-14 11:44:42 -0800 | |
| commit | 4c72df04b0ab32e88fb9bc7fb9f109c3d59bce5f (patch) | |
| tree | 2df1371a6225a2c8923b01ba2778cd40f632deaf | |
| parent | c8e3c7c816a4d9de42579df11d9302e117070ea1 (diff) | |
Fix StrictMode I/O violations
onBeforeUnlockUser now happens on a worker thread that allows I/O.
In addition to that STATE_RUNNING_UNLOCKING is only set after
onBeforeUnlockUser. Otherwise non-DBA processes would be able to start
before unlocking completes (causing b/68995913)
Recents are now loaded on a worker thread
Bug: 68872660
Bug: 68871386
Test: UserControllerTest
Test: Tested on marlin/walleye (+factory reset)
Test: create/start work profile. create/start guest user
Change-Id: I4694dfa0bd523de33f0e600f2db22d02610b535c
| -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); } |