From cd57599273738c30cc209894d1f87731c9defb16 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 29 Mar 2016 14:12:49 -0600 Subject: [PATCH] Delay vold connectors until published, fix NPE. If they connect too quickly, PackageManager could end up trying to obtain the yet-unpublished MountService. Fix NPE in UserManagerService when trying to persist fingerprints, and fix write ordering to always write [id].xml before userlist.xml to avoid battery pull issues. Simlarly, delete [id].xml only after updating userlist.xml. Bug: 27869443 Change-Id: I43d8552e5e37b9ca4137cca3e3e76684c7dee605 --- .../core/java/com/android/server/MountService.java | 18 ++++++++++------ .../com/android/server/pm/UserManagerService.java | 24 ++++++++++++---------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index 45008dcf72a1..9e2f11670017 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -165,6 +165,7 @@ class MountService extends IMountService.Stub public void onStart() { mMountService = new MountService(getContext()); publishBinderService("mount", mMountService); + mMountService.start(); } @Override @@ -430,9 +431,13 @@ class MountService extends IMountService.Stub = { "password", "default", "pattern", "pin" }; private final Context mContext; + private final NativeDaemonConnector mConnector; private final NativeDaemonConnector mCryptConnector; + private final Thread mConnectorThread; + private final Thread mCryptConnectorThread; + private volatile boolean mSystemReady = false; private volatile boolean mBootCompleted = false; private volatile boolean mDaemonConnected = false; @@ -1494,17 +1499,13 @@ class MountService extends IMountService.Stub null); mConnector.setDebug(true); mConnector.setWarnIfHeld(mLock); - - Thread thread = new Thread(mConnector, VOLD_TAG); - thread.start(); + mConnectorThread = new Thread(mConnector, VOLD_TAG); // Reuse parameters from first connector since they are tested and safe mCryptConnector = new NativeDaemonConnector(this, "cryptd", MAX_CONTAINERS * 2, CRYPTD_TAG, 25, null); mCryptConnector.setDebug(true); - - Thread crypt_thread = new Thread(mCryptConnector, CRYPTD_TAG); - crypt_thread.start(); + mCryptConnectorThread = new Thread(mCryptConnector, CRYPTD_TAG); final IntentFilter userFilter = new IntentFilter(); userFilter.addAction(Intent.ACTION_USER_ADDED); @@ -1521,6 +1522,11 @@ class MountService extends IMountService.Stub } } + private void start() { + mConnectorThread.start(); + mCryptConnectorThread.start(); + } + private void systemReady() { mSystemReady = true; mHandler.obtainMessage(H_SYSTEM_READY).sendToTarget(); diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 6df36e4b053f..7f0da1ec669b 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -31,7 +31,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; @@ -924,12 +923,12 @@ public class UserManagerService extends IUserManager.Stub { } // Don't call them within the mRestrictionsLock. synchronized (mPackagesLock) { - if (globalChanged) { - writeUserListLP(); - } if (localChanged) { writeUserLP(getUserDataNoChecks(userId)); } + if (globalChanged) { + writeUserListLP(); + } } synchronized (mRestrictionsLock) { @@ -1491,8 +1490,8 @@ public class UserManagerService extends IUserManager.Stub { updateUserIds(); initDefaultGuestRestrictions(); - writeUserListLP(); writeUserLP(userData); + writeUserListLP(); } private String getOwnerName() { @@ -1542,8 +1541,10 @@ public class UserManagerService extends IUserManager.Stub { serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime)); serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME, Long.toString(userInfo.lastLoggedInTime)); - serializer.attribute(null, ATTR_LAST_LOGGED_IN_FINGERPRINT, - userInfo.lastLoggedInFingerprint); + if (userInfo.lastLoggedInFingerprint != null) { + serializer.attribute(null, ATTR_LAST_LOGGED_IN_FINGERPRINT, + userInfo.lastLoggedInFingerprint); + } if (userInfo.iconPath != null) { serializer.attribute(null, ATTR_ICON_PATH, userInfo.iconPath); } @@ -1599,7 +1600,7 @@ public class UserManagerService extends IUserManager.Stub { serializer.endDocument(); userFile.finishWrite(fos); } catch (Exception ioe) { - Slog.e(LOG_TAG, "Error writing user info " + userData.info.id + "\n" + ioe); + Slog.e(LOG_TAG, "Error writing user info " + userData.info.id, ioe); userFile.failWrite(fos); } } @@ -1944,6 +1945,7 @@ public class UserManagerService extends IUserManager.Stub { userData.info = userInfo; mUsers.put(userId, userData); } + writeUserLP(userData); writeUserListLP(); if (parent != null) { if (isManagedProfile) { @@ -2217,13 +2219,13 @@ public class UserManagerService extends IUserManager.Stub { mCachedEffectiveUserRestrictions.remove(userHandle); mDevicePolicyLocalUserRestrictions.remove(userHandle); } - // Remove user file - AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX)); - userFile.delete(); // Update the user list synchronized (mPackagesLock) { writeUserListLP(); } + // Remove user file + AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX)); + userFile.delete(); updateUserIds(); File userDir = Environment.getUserSystemDirectory(userHandle); File renamedUserDir = Environment.getUserSystemDirectory(UserHandle.USER_NULL - userHandle); -- 2.11.0