From f9e7fdc38e53579d867575bed1cdb07507fbff68 Mon Sep 17 00:00:00 2001 From: Yasin Kilicdere Date: Mon, 9 Jan 2023 14:12:35 +0000 Subject: [PATCH] Prevent removing the target user during a user switch. This CL prevents removing the target user and allows removing the user that has been switched away. Let's say we're switching from userA to userB, before this CL during the switch it was possible to remove userB and it wasn't possible to remove userA. After this CL this problem is fixed. This CL also disables REMOVE_GUEST_ON_EXIT while running UserLifecycleStressTest.switchToExistingGuestAndStartOverStressTest, and restores it back after the test. Bug: 264667155 Test: atest FrameworksServicesTests:com.android.server.pm.UserLifecycleStressTest#switchToExistingGuestAndStartOverStressTest Change-Id: I802191492adc7a60c7c43ea7651a124d2a8425da --- .../android/server/pm/UserManagerService.java | 20 +++++++++++++++++-- .../server/pm/UserLifecycleStressTest.java | 15 ++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 6bac90532645b..d5095634b4a39 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -1833,6 +1833,23 @@ public class UserManagerService extends IUserManager.Stub { return activityManagerInternal.getCurrentUserId(); } + /** + * Gets the current user id, or the target user id in case there is a started user switch. + * + * @return id of current or target foreground user, or {@link UserHandle#USER_NULL} if + * {@link ActivityManagerInternal} is not available yet. + */ + @VisibleForTesting + int getCurrentOrTargetUserId() { + ActivityManagerInternal activityManagerInternal = getActivityManagerInternal(); + if (activityManagerInternal == null) { + Slog.w(LOG_TAG, "getCurrentOrTargetUserId() called too early, ActivityManagerInternal" + + " is not set yet"); + return UserHandle.USER_NULL; + } + return activityManagerInternal.getCurrentUser().id; + } + /** * Gets whether the user is the current foreground user or a started profile of that user. * @@ -5407,8 +5424,7 @@ public class UserManagerService extends IUserManager.Stub { final long ident = Binder.clearCallingIdentity(); try { final UserData userData; - int currentUser = getCurrentUserId(); - if (currentUser == userId) { + if (userId == getCurrentOrTargetUserId()) { Slog.w(LOG_TAG, "Current user cannot be removed."); return false; } diff --git a/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java b/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java index bbe89073d34da..b00fb92f9c46f 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java @@ -29,6 +29,7 @@ import android.content.pm.UserInfo; import android.os.RemoteException; import android.os.UserManager; import android.platform.test.annotations.Postsubmit; +import android.provider.Settings; import android.util.Log; import androidx.test.InstrumentationRegistry; @@ -37,6 +38,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.FunctionalUtils; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -62,12 +64,22 @@ public class UserLifecycleStressTest { private Context mContext; private UserManager mUserManager; private ActivityManager mActivityManager; + private String mRemoveGuestOnExitOriginalValue; @Before public void setup() { mContext = InstrumentationRegistry.getInstrumentation().getContext(); mUserManager = mContext.getSystemService(UserManager.class); mActivityManager = mContext.getSystemService(ActivityManager.class); + mRemoveGuestOnExitOriginalValue = Settings.Global.getString(mContext.getContentResolver(), + Settings.Global.REMOVE_GUEST_ON_EXIT); + + } + + @After + public void tearDown() { + Settings.Global.putString(mContext.getContentResolver(), + Settings.Global.REMOVE_GUEST_ON_EXIT, mRemoveGuestOnExitOriginalValue); } /** @@ -105,6 +117,9 @@ public class UserLifecycleStressTest { **/ @Test public void switchToExistingGuestAndStartOverStressTest() throws Exception { + Settings.Global.putString(mContext.getContentResolver(), + Settings.Global.REMOVE_GUEST_ON_EXIT, "0"); + if (ActivityManager.getCurrentUser() != USER_SYSTEM) { switchUser(USER_SYSTEM); }