Merge "DO NOT MERGE: Fix several issues with precreated users." into qt-qpr1-dev

This commit is contained in:
Jovana Knezevic
2019-11-11 23:13:57 +00:00
committed by Android (Google) Code Review
4 changed files with 71 additions and 7 deletions

View File

@@ -2042,6 +2042,13 @@ public class UserManager {
* by {@link #createUser(String, int)} or {@link #createGuest(Context, String)}), it takes * by {@link #createUser(String, int)} or {@link #createGuest(Context, String)}), it takes
* less time. * less time.
* *
* <p>This method completes the majority of work necessary for user creation: it
* creates user data, CE and DE encryption keys, app data directories, initializes the user and
* grants default permissions. When pre-created users become "real" users, only then are
* components notified of new user creation by firing user creation broadcasts.
*
* <p>All pre-created users are removed during system upgrade.
*
* <p>Requires {@link android.Manifest.permission#MANAGE_USERS} permission. * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
* *
* @param flags UserInfo flags that identify the type of user and other properties. * @param flags UserInfo flags that identify the type of user and other properties.
@@ -2055,6 +2062,7 @@ public class UserManager {
* *
* @hide * @hide
*/ */
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
public @Nullable UserInfo preCreateUser(@UserInfoFlag int flags) { public @Nullable UserInfo preCreateUser(@UserInfoFlag int flags) {
try { try {
return mService.preCreateUser(flags); return mService.preCreateUser(flags);

View File

@@ -23714,6 +23714,13 @@ public class PackageManagerService extends IPackageManager.Stub
} }
} }
boolean readPermissionStateForUser(@UserIdInt int userId) {
synchronized (mPackages) {
mSettings.readPermissionStateForUserSyncLPr(userId);
return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
}
}
@Override @Override
public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
mContext.enforceCallingOrSelfPermission( mContext.enforceCallingOrSelfPermission(

View File

@@ -3140,6 +3140,10 @@ public final class Settings {
return true; return true;
} }
void readPermissionStateForUserSyncLPr(@UserIdInt int userId) {
mRuntimePermissionsPersistence.readStateForUserSyncLPr(userId);
}
void applyDefaultPreferredAppsLPw(int userId) { void applyDefaultPreferredAppsLPw(int userId) {
// First pull data from any pre-installed apps. // First pull data from any pre-installed apps.
final PackageManagerInternal pmInternal = final PackageManagerInternal pmInternal =

View File

@@ -479,6 +479,10 @@ public class UserManagerService extends IUserManager.Stub {
public void onBootPhase(int phase) { public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mUms.cleanupPartialUsers(); mUms.cleanupPartialUsers();
if (mUms.mPm.isDeviceUpgrading()) {
mUms.cleanupPreCreatedUsers();
}
} }
} }
@@ -603,6 +607,33 @@ public class UserManagerService extends IUserManager.Stub {
} }
} }
/**
* Removes any pre-created users from the system. Should be invoked after OTAs, to ensure
* pre-created users are not stale. New pre-created pool can be re-created after the update.
*/
void cleanupPreCreatedUsers() {
final ArrayList<UserInfo> preCreatedUsers;
synchronized (mUsersLock) {
final int userSize = mUsers.size();
preCreatedUsers = new ArrayList<>(userSize);
for (int i = 0; i < userSize; i++) {
UserInfo ui = mUsers.valueAt(i).info;
if (ui.preCreated) {
preCreatedUsers.add(ui);
addRemovingUserIdLocked(ui.id);
ui.flags |= UserInfo.FLAG_DISABLED;
ui.partial = true;
}
}
}
final int preCreatedSize = preCreatedUsers.size();
for (int i = 0; i < preCreatedSize; i++) {
UserInfo ui = preCreatedUsers.get(i);
Slog.i(LOG_TAG, "Removing pre-created user " + ui.id);
removeUserState(ui.id);
}
}
@Override @Override
public String getUserAccount(int userId) { public String getUserAccount(int userId) {
checkManageUserAndAcrossUsersFullPermission("get user account"); checkManageUserAndAcrossUsersFullPermission("get user account");
@@ -2762,11 +2793,17 @@ public class UserManagerService extends IUserManager.Stub {
preCreatedUser.preCreated = false; preCreatedUser.preCreated = false;
preCreatedUser.creationTime = getCreationTime(); preCreatedUser.creationTime = getCreationTime();
dispatchUserAddedIntent(preCreatedUser); synchronized (mPackagesLock) {
writeUserLP(preCreatedUserData); writeUserLP(preCreatedUserData);
writeUserListLP(); writeUserListLP();
}
updateUserIds();
if (!mPm.readPermissionStateForUser(preCreatedUser.id)) {
// Could not read the existing permissions, re-grant them.
mPm.onNewUserCreated(preCreatedUser.id);
}
dispatchUserAddedIntent(preCreatedUser);
return preCreatedUser; return preCreatedUser;
} }
} }
@@ -2900,7 +2937,10 @@ public class UserManagerService extends IUserManager.Stub {
synchronized (mRestrictionsLock) { synchronized (mRestrictionsLock) {
mBaseUserRestrictions.append(userId, restrictions); mBaseUserRestrictions.append(userId, restrictions);
} }
t.traceBegin("PM.onNewUserCreated-" + userId);
mPm.onNewUserCreated(userId); mPm.onNewUserCreated(userId);
t.traceEnd();
if (preCreate) { if (preCreate) {
// Must start user (which will be stopped right away, through // Must start user (which will be stopped right away, through
// UserController.finishUserUnlockedCompleted) so services can properly // UserController.finishUserUnlockedCompleted) so services can properly
@@ -3599,14 +3639,16 @@ public class UserManagerService extends IUserManager.Stub {
synchronized (mUsersLock) { synchronized (mUsersLock) {
final int userSize = mUsers.size(); final int userSize = mUsers.size();
for (int i = 0; i < userSize; i++) { for (int i = 0; i < userSize; i++) {
if (!mUsers.valueAt(i).info.partial) { UserInfo userInfo = mUsers.valueAt(i).info;
if (!userInfo.partial && !userInfo.preCreated) {
num++; num++;
} }
} }
final int[] newUsers = new int[num]; final int[] newUsers = new int[num];
int n = 0; int n = 0;
for (int i = 0; i < userSize; i++) { for (int i = 0; i < userSize; i++) {
if (!mUsers.valueAt(i).info.partial) { UserInfo userInfo = mUsers.valueAt(i).info;
if (!userInfo.partial && !userInfo.preCreated) {
newUsers[n++] = mUsers.keyAt(i); newUsers[n++] = mUsers.keyAt(i);
} }
} }
@@ -3658,7 +3700,10 @@ public class UserManagerService extends IUserManager.Stub {
* recycled. * recycled.
*/ */
void reconcileUsers(String volumeUuid) { void reconcileUsers(String volumeUuid) {
mUserDataPreparer.reconcileUsers(volumeUuid, getUsers(true /* excludeDying */)); mUserDataPreparer.reconcileUsers(volumeUuid, getUsers(
/* excludePartial= */ true,
/* excludeDying= */ true,
/* excludePreCreated= */ false));
} }
/** /**