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

Commit ef4023a3 authored by Adam Bookatz's avatar Adam Bookatz
Browse files

Slate ephemeral user deletion in systemReady()

After a reboot,
ephemeral users are currently slated for deletion upon
UserManager.onBootPhase(PHASE_ACTIVITY_MANAGER_READY).
However, ephemeral users are already somewhat removed prior
to this, without it being reported, which can cause severe
problems.

Here, we slate ephemeral users for deletion slightly earlier,
in UserManager.systemReady().

Bug: 181291095

Test: atest android.host.multiuser.EphemeralTest#testRebootAndRemoveEphemeralUser_withAccount

Test: manual:
adb shell pm create-user --ephemeral Ephy
switch to the user, connect to the internet, and set up an account
reboot the device (from within that ephemeral user)
observe no boot-loop

Change-Id: I0f60785a1e67945f42d8332ca4d09d06145a3347
parent 87d4c9a9
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -23578,7 +23578,13 @@ public class PackageManagerService extends IPackageManager.Stub
        mPermissionManager.onSystemReady();
        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
        for (int userId : UserManagerService.getInstance().getUserIds()) {
        final List<UserInfo> livingUsers = mInjector.getUserManagerInternal().getUsers(
                /* excludePartial= */ true,
                /* excludeDying= */ true,
                /* excludePreCreated= */ false);
        final int livingUserCount = livingUsers.size();
        for (int i = 0; i < livingUserCount; i++) {
            final int userId = livingUsers.get(i).id;
            if (mPmInternal.isPermissionUpgradeNeeded(userId)) {
                grantPermissionsUserIds = ArrayUtils.appendInt(
                        grantPermissionsUserIds, userId);
+22 −4
Original line number Diff line number Diff line
@@ -699,6 +699,8 @@ public class UserManagerService extends IUserManager.Stub {
        mContext.registerReceiver(mConfigurationChangeReceiver,
                new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED),
                null, mHandler);

        markEphemeralUsersForRemoval();
    }

    /**
@@ -709,17 +711,33 @@ public class UserManagerService extends IUserManager.Stub {
        return mLocalService;
    }

    /** Marks all ephemeral users as slated for deletion. **/
    private void markEphemeralUsersForRemoval() {
        synchronized (mUsersLock) {
            final int userSize = mUsers.size();
            for (int i = 0; i < userSize; i++) {
                final UserInfo ui = mUsers.valueAt(i).info;
                if (ui.isEphemeral() && !ui.preCreated && ui.id != UserHandle.USER_SYSTEM) {
                    addRemovingUserIdLocked(ui.id);
                    ui.partial = true;
                    ui.flags |= UserInfo.FLAG_DISABLED;
                }
            }
        }
    }

    /* Prunes out any partially created or partially removed users. */
    void cleanupPartialUsers() {
        // Prune out any partially created, partially removed and ephemeral users.
        ArrayList<UserInfo> partials = new ArrayList<>();
        synchronized (mUsersLock) {
            final int userSize = mUsers.size();
            for (int i = 0; i < userSize; i++) {
                UserInfo ui = mUsers.valueAt(i).info;
                if ((ui.partial || ui.guestToRemove || (ui.isEphemeral() && !ui.preCreated))
                        && i != 0) {
                if ((ui.partial || ui.guestToRemove) && ui.id != UserHandle.USER_SYSTEM) {
                    partials.add(ui);
                    if (!mRemovingUserIds.get(ui.id)) {
                        addRemovingUserIdLocked(ui.id);
                    }
                    ui.partial = true;
                }
            }