Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 201ab6dc authored by Jovana Knezevic's avatar Jovana Knezevic Committed by Android (Google) Code Review
Browse files

Merge "Fix several issues with precreated users."

parents 6c0d5990 8508f2f5
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -2453,6 +2453,13 @@ public class UserManager {
     * by {@link #createUser(String, String, int)} or {@link #createGuest(Context, String)}), it
     * takes 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.
     *
     * @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_GUEST}.
@@ -2464,6 +2471,7 @@ public class UserManager {
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
    public @Nullable UserInfo preCreateUser(@NonNull String userType) {
        try {
            return mService.preCreateUser(userType);
+7 −0
Original line number Diff line number Diff line
@@ -22290,6 +22290,13 @@ public class PackageManagerService extends IPackageManager.Stub
        mPermissionManager.onNewUserCreated(userId);
    }
    boolean readPermissionStateForUser(@UserIdInt int userId) {
        synchronized (mPackages) {
            mSettings.readPermissionStateForUserSyncLPr(userId);
            return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
        }
    }
    @Override
    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
        mContext.enforceCallingOrSelfPermission(
+4 −0
Original line number Diff line number Diff line
@@ -3125,6 +3125,10 @@ public final class Settings {
        return true;
    }

    void readPermissionStateForUserSyncLPr(@UserIdInt int userId) {
        mRuntimePermissionsPersistence.readStateForUserSyncLPr(userId);
    }

    void applyDefaultPreferredAppsLPw(int userId) {
        // First pull data from any pre-installed apps.
        final PackageManagerInternal pmInternal =
+47 −7
Original line number Diff line number Diff line
@@ -492,6 +492,10 @@ public class UserManagerService extends IUserManager.Stub {
        public void onBootPhase(int phase) {
            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
                mUms.cleanupPartialUsers();

                if (mUms.mPm.isDeviceUpgrading()) {
                    mUms.cleanupPreCreatedUsers();
                }
            }
        }

@@ -617,6 +621,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
    public String getUserAccount(@UserIdInt int userId) {
        checkManageUserAndAcrossUsersFullPermission("get user account");
@@ -3078,7 +3109,6 @@ public class UserManagerService extends IUserManager.Stub {
            @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
            boolean preCreate, @Nullable String[] disallowedPackages,
            @NonNull TimingsTraceAndSlog t) {

        final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
        if (userTypeDetails == null) {
            Slog.e(LOG_TAG, "Cannot create user of invalid user type: " + userType);
@@ -3254,9 +3284,9 @@ public class UserManagerService extends IUserManager.Stub {
                mBaseUserRestrictions.append(userId, restrictions);
            }

            t.traceBegin("PM.onNewUserCreated");
            t.traceBegin("PM.onNewUserCreated-" + userId);
            mPm.onNewUserCreated(userId);

            t.traceEnd();
            if (preCreate) {
                // Must start user (which will be stopped right away, through
                // UserController.finishUserUnlockedCompleted) so services can properly
@@ -3323,11 +3353,16 @@ public class UserManagerService extends IUserManager.Stub {
        preCreatedUser.preCreated = false;
        preCreatedUser.creationTime = getCreationTime();

        dispatchUserAddedIntent(preCreatedUser);
        synchronized (mPackagesLock) {
            writeUserLP(preCreatedUserData);
            writeUserListLP();
        }
        updateUserIds();
        if (!mPm.readPermissionStateForUser(preCreatedUser.id)) {
            // Could not read the existing permissions, re-grant them.
            mPm.onNewUserCreated(preCreatedUser.id);
        }
        dispatchUserAddedIntent(preCreatedUser);
        return preCreatedUser;
    }

@@ -4027,14 +4062,16 @@ public class UserManagerService extends IUserManager.Stub {
        synchronized (mUsersLock) {
            final int userSize = mUsers.size();
            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++;
                }
            }
            final int[] newUsers = new int[num];
            int n = 0;
            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);
                }
            }
@@ -4095,7 +4132,10 @@ public class UserManagerService extends IUserManager.Stub {
     * recycled.
     */
    void reconcileUsers(String volumeUuid) {
        mUserDataPreparer.reconcileUsers(volumeUuid, getUsers(true /* excludeDying */));
        mUserDataPreparer.reconcileUsers(volumeUuid, getUsers(
                /* excludePartial= */ true,
                /* excludeDying= */ true,
                /* excludePreCreated= */ false));
    }

    /**