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

Commit 7097ae1f authored by Yasin Kilicdere's avatar Yasin Kilicdere
Browse files

Prevent removed users to be in present in UserController.mStartedUsers

Bug: 364707441
Test: atest ActivityManagerTest#testRemovedUserShouldNotBeRunning
Flag: EXEMPT bugfix
Change-Id: I931ef14aa4b451b17d559fea0a7c3e33687966d5
parent 6b27ad03
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -141,6 +141,15 @@ public abstract class ActivityManagerInternal {
    public abstract boolean startIsolatedProcess(String entryPoint, String[] mainArgs,
            String processName, String abiOverride, int uid, Runnable crashHandler);

    /**
     * Called when a user is being deleted. This can happen during normal device usage
     * or just at startup, when partially removed users are purged. Any state persisted by the
     * ActivityManager should be purged now.
     *
     * @param userId The user being cleaned up.
     */
    public abstract void onUserRemoving(@UserIdInt int userId);

    /**
     * Called when a user has been deleted. This can happen during normal device usage
     * or just at startup, when partially removed users are purged. Any state persisted by the
+7 −1
Original line number Diff line number Diff line
@@ -16608,7 +16608,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
        @Override
        public void onUserRemoved(@UserIdInt int userId) {
        public void onUserRemoving(@UserIdInt int userId) {
            // Clean up any ActivityTaskManager state (by telling it the user is stopped)
            mAtmInternal.onUserStopped(userId);
            // Clean up various services by removing the user
@@ -16621,6 +16621,12 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
        }
        @Override
        public void onUserRemoved(int userId) {
            // Clean up UserController state
            mUserController.onUserRemoved(userId);
        }
        @Override
        public boolean startUserInBackground(final int userId) {
            return ActivityManagerService.this.startUserInBackground(userId);
+3 −6
Original line number Diff line number Diff line
@@ -454,11 +454,6 @@ class UserController implements Handler.Callback {
        public void onUserCreated(UserInfo user, Object token) {
            onUserAdded(user);
        }

        @Override
        public void onUserRemoved(UserInfo user) {
            UserController.this.onUserRemoved(user.id);
        }
    };

    UserController(ActivityManagerService service) {
@@ -3352,10 +3347,12 @@ class UserController implements Handler.Callback {
                if (mUserProfileGroupIds.keyAt(i) == userId
                        || mUserProfileGroupIds.valueAt(i) == userId) {
                    mUserProfileGroupIds.removeAt(i);

                }
            }
            mCurrentProfileIds = ArrayUtils.removeInt(mCurrentProfileIds, userId);
            mUserLru.remove((Integer) userId);
            mStartedUsers.remove(userId);
            updateStartedUserArrayLU();
        }
    }

+2 −1
Original line number Diff line number Diff line
@@ -6660,7 +6660,7 @@ public class UserManagerService extends IUserManager.Stub {
                                                + userId);
                            }
                            new Thread(() -> {
                                getActivityManagerInternal().onUserRemoved(userId);
                                getActivityManagerInternal().onUserRemoving(userId);
                                removeUserState(userId);
                            }).start();
                        }
@@ -6700,6 +6700,7 @@ public class UserManagerService extends IUserManager.Stub {
        synchronized (mUsersLock) {
            removeUserDataLU(userId);
            mIsUserManaged.delete(userId);
            getActivityManagerInternal().onUserRemoved(userId);
        }
        synchronized (mUserStates) {
            mUserStates.delete(userId);
+23 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

@@ -35,6 +36,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.DropBoxManager;
@@ -48,6 +50,7 @@ import android.os.Parcel;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
import android.provider.Settings;
@@ -68,6 +71,7 @@ import org.junit.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -149,6 +153,25 @@ public class ActivityManagerTest {
        }
    }

    @Test
    public void testRemovedUserShouldNotBeRunning() throws Exception {
        final UserManager userManager = mContext.getSystemService(UserManager.class);
        assertNotNull("UserManager should not be null", userManager);
        final UserInfo user = userManager.createUser(
                "TestUser", UserManager.USER_TYPE_FULL_SECONDARY, 0);

        mService.startUserInBackground(user.id);
        assertTrue("User should be running", mService.isUserRunning(user.id, 0));
        assertTrue("User should be in running users",
                Arrays.stream(mService.getRunningUserIds()).anyMatch(x -> x == user.id));

        userManager.removeUser(user.id);
        mService.startUserInBackground(user.id);
        assertFalse("Removed user should not be running", mService.isUserRunning(user.id, 0));
        assertFalse("Removed user should not be in running users",
                Arrays.stream(mService.getRunningUserIds()).anyMatch(x -> x == user.id));
    }

    @Test
    public void testServiceUnbindAndKilling() {
        for (int i = TEST_LOOPS; i > 0; i--) {