From b286462f6859ee4fd5f890e37cd614361d1696b1 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Tue, 29 Oct 2019 18:03:18 -0700 Subject: [PATCH] DO NOT MERGE - Removed FLAG_EPHEMERAL from pre-created users. When a User is pre-created with that flag, its CE & DE keys are not persisted on storage. Hence, when that pre-creatd user is converted to full-user, the expected keys don't exist and the user doesn't boot properly. This change fix the issue by making the pre-created user non-ephemeral, and changing it to ephemeral when it's converted to a "real" user. Test: manual verification on Automotive by creating a new user than deleting it using the UI - that creates and switches to a new guest user (which was pre-created); without this change, that user would be hanging with a "Android is starting..." message Bug: 143092698 Fixes: 143553590 Change-Id: If595b29356b5b50c812f2888cda6e636f18a0d4b --- .../android/server/pm/UserManagerService.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 338811efd4ea1..1972232ca6d2e 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -2751,8 +2751,18 @@ public class UserManagerService extends IUserManager.Stub { } if (preCreatedUserData != null) { final UserInfo preCreatedUser = preCreatedUserData.info; - Log.i(LOG_TAG, "Reusing pre-created user " + preCreatedUser.id + " for flags + " - + UserInfo.flagsToString(flags)); + if (UserInfo.isGuest(flags) && areGuestUsersEphemeral()) { + // TODO(b/143092698): this pre-created user has (persisted) storage keys + // that will be removed when the user is stopped and ideally we should + // remove them from storage right now, but that's not possible with the + // current StorageManager APIs (there are just a + // createUserKey(userId, serial, isEphemeral) and destroyUserKey(userId) + // methods; we would need a makeUserKeyEphemeral(userId) method) + preCreatedUserData.info.flags |= UserInfo.FLAG_EPHEMERAL; + } + Log.i(LOG_TAG, "Reusing pre-created user " + preCreatedUser.id + " for flags " + + UserInfo.flagsToString(flags) + "; new flags: " + + UserInfo.flagsToString(preCreatedUserData.info.flags)); if (DBG) { Log.d(LOG_TAG, "pre-created user flags: " + UserInfo.flagsToString(preCreatedUser.flags) @@ -2845,8 +2855,9 @@ public class UserManagerService extends IUserManager.Stub { synchronized (mUsersLock) { // Add ephemeral flag to guests/users if required. Also inherit it from parent. - if ((isGuest && ephemeralGuests) || mForceEphemeralUsers - || (parent != null && parent.info.isEphemeral())) { + if (!preCreate && ((isGuest && ephemeralGuests) + || mForceEphemeralUsers + || (parent != null && parent.info.isEphemeral()))) { flags |= UserInfo.FLAG_EPHEMERAL; } @@ -2966,13 +2977,7 @@ public class UserManagerService extends IUserManager.Stub { @GuardedBy("mUsersLock") private @Nullable UserData getPreCreatedUserLU(@UserInfoFlag int flags) { if (DBG) { - Slog.d(LOG_TAG, "getPreCreatedUser(): initialFlags= " + UserInfo.flagsToString(flags)); - } - if (UserInfo.isGuest(flags) && areGuestUsersEphemeral()) { - flags |= UserInfo.FLAG_EPHEMERAL; - } - if (DBG) { - Slog.d(LOG_TAG, "getPreCreatedUser(): targetFlags= " + UserInfo.flagsToString(flags)); + Slog.d(LOG_TAG, "getPreCreatedUser(): flags= " + UserInfo.flagsToString(flags)); } final int userSize = mUsers.size(); for (int i = 0; i < userSize; i++) {