diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index ccbe96f30e046..c5bca6bcbfa5e 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -28,6 +28,9 @@ import static android.os.PowerManager.locationPowerSaveModeToString; import static com.android.server.location.CallerIdentity.PERMISSION_COARSE; import static com.android.server.location.CallerIdentity.PERMISSION_FINE; +import static com.android.server.location.UserInfoHelper.UserListener.CURRENT_USER_CHANGED; +import static com.android.server.location.UserInfoHelper.UserListener.USER_STARTED; +import static com.android.server.location.UserInfoHelper.UserListener.USER_STOPPED; import static java.util.concurrent.TimeUnit.NANOSECONDS; @@ -101,7 +104,7 @@ import com.android.server.location.AbstractLocationProvider.State; import com.android.server.location.CallerIdentity.PermissionLevel; import com.android.server.location.LocationRequestStatistics.PackageProviderKey; import com.android.server.location.LocationRequestStatistics.PackageStatistics; -import com.android.server.location.UserInfoHelper.UserListener; +import com.android.server.location.UserInfoHelper.UserListener.UserChange; import com.android.server.location.gnss.GnssManagerService; import com.android.server.pm.permission.PermissionManagerServiceInternal; @@ -132,11 +135,13 @@ public class LocationManagerService extends ILocationManager.Stub { */ public static class Lifecycle extends SystemService { + private final UserInfoHelper mUserInfoHelper; private final LocationManagerService mService; public Lifecycle(Context context) { super(context); - mService = new LocationManagerService(context); + mUserInfoHelper = new SystemUserInfoHelper(context); + mService = new LocationManagerService(context, mUserInfoHelper); } @Override @@ -161,6 +166,29 @@ public class LocationManagerService extends ILocationManager.Stub { mService.onSystemThirdPartyAppsCanStart(); } } + + @Override + public void onUserStarting(TargetUser user) { + mUserInfoHelper.dispatchOnUserStarted(user.getUserIdentifier()); + } + + @Override + public void onUserSwitching(TargetUser from, TargetUser to) { + mUserInfoHelper.dispatchOnCurrentUserChanged(from.getUserIdentifier(), + to.getUserIdentifier()); + } + + @Override + public void onUserStopped(TargetUser user) { + mUserInfoHelper.dispatchOnUserStopped(user.getUserIdentifier()); + } + + private static class SystemUserInfoHelper extends UserInfoHelper { + + SystemUserInfoHelper(Context context) { + super(context); + } + } } public static final String TAG = "LocationManagerService"; @@ -232,7 +260,7 @@ public class LocationManagerService extends ILocationManager.Stub { @PowerManager.LocationPowerSaveMode private int mBatterySaverMode; - private LocationManagerService(Context context) { + private LocationManagerService(Context context, UserInfoHelper userInfoHelper) { mContext = context.createAttributionContext(ATTRIBUTION_TAG); mHandler = FgThread.getHandler(); mLocalService = new LocalService(); @@ -240,7 +268,7 @@ public class LocationManagerService extends ILocationManager.Stub { LocalServices.addService(LocationManagerInternal.class, mLocalService); mAppOpsHelper = new AppOpsHelper(mContext); - mUserInfoHelper = new UserInfoHelper(mContext); + mUserInfoHelper = userInfoHelper; mSettingsHelper = new SettingsHelper(mContext, mHandler); mAppForegroundHelper = new AppForegroundHelper(mContext); mLocationUsageLogger = new LocationUsageLogger(); @@ -342,7 +370,7 @@ public class LocationManagerService extends ILocationManager.Stub { // initialize the current users. we would get the user started notifications for these // users eventually anyways, but this takes care of it as early as possible. for (int userId: mUserInfoHelper.getCurrentUserIds()) { - onUserChanged(userId, UserListener.USER_STARTED); + onUserChanged(userId, USER_STARTED); } } } @@ -596,32 +624,23 @@ public class LocationManagerService extends ILocationManager.Stub { } } - private void onUserChanged(@UserIdInt int userId, @UserListener.UserChange int change) { + private void onUserChanged(@UserIdInt int userId, @UserChange int change) { switch (change) { - case UserListener.USER_SWITCHED: - if (D) { - Log.d(TAG, "user " + userId + " current status changed"); - } + case CURRENT_USER_CHANGED: synchronized (mLock) { for (LocationProviderManager manager : mProviderManagers) { manager.onEnabledChangedLocked(userId); } } break; - case UserListener.USER_STARTED: - if (D) { - Log.d(TAG, "user " + userId + " started"); - } + case USER_STARTED: synchronized (mLock) { for (LocationProviderManager manager : mProviderManagers) { manager.onUserStarted(userId); } } break; - case UserListener.USER_STOPPED: - if (D) { - Log.d(TAG, "user " + userId + " stopped"); - } + case USER_STOPPED: synchronized (mLock) { for (LocationProviderManager manager : mProviderManagers) { manager.onUserStopped(userId); @@ -957,10 +976,22 @@ public class LocationManagerService extends ILocationManager.Stub { pw.increaseIndent(); // for now we only dump for the parent user - int userId = mUserInfoHelper.getCurrentUserIds()[0]; - pw.println("last location=" + mLastLocation.get(userId)); - pw.println("last coarse location=" + mLastCoarseLocation.get(userId)); - pw.println("enabled=" + isEnabled(userId)); + int[] userIds = mUserInfoHelper.getCurrentUserIds(); + if (userIds.length == 1) { + int userId = userIds[0]; + pw.println("last location=" + mLastLocation.get(userId)); + pw.println("last coarse location=" + mLastCoarseLocation.get(userId)); + pw.println("enabled=" + isEnabled(userId)); + } else { + for (int userId : userIds) { + pw.println("user " + userId + ":"); + pw.increaseIndent(); + pw.println("last location=" + mLastLocation.get(userId)); + pw.println("last coarse location=" + mLastCoarseLocation.get(userId)); + pw.println("enabled=" + isEnabled(userId)); + pw.decreaseIndent(); + } + } } mProvider.dump(fd, pw, args); diff --git a/services/core/java/com/android/server/location/UserInfoHelper.java b/services/core/java/com/android/server/location/UserInfoHelper.java index a3dcc40bdf2dc..53bff8eacb4c9 100644 --- a/services/core/java/com/android/server/location/UserInfoHelper.java +++ b/services/core/java/com/android/server/location/UserInfoHelper.java @@ -20,48 +20,48 @@ import static android.os.UserManager.DISALLOW_SHARE_LOCATION; import static com.android.server.location.LocationManagerService.D; import static com.android.server.location.LocationManagerService.TAG; +import static com.android.server.location.UserInfoHelper.UserListener.CURRENT_USER_CHANGED; +import static com.android.server.location.UserInfoHelper.UserListener.USER_STARTED; +import static com.android.server.location.UserInfoHelper.UserListener.USER_STOPPED; +import android.annotation.CallSuper; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.UserIdInt; -import android.app.ActivityManager; -import android.content.BroadcastReceiver; +import android.app.ActivityManagerInternal; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; import android.os.Binder; -import android.os.Build; import android.os.UserHandle; import android.os.UserManager; import android.util.Log; import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; -import com.android.server.FgThread; +import com.android.server.LocalServices; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; +import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; /** * Provides accessors and listeners for all user info. */ -public class UserInfoHelper { +public abstract class UserInfoHelper { /** * Listener for current user changes. */ public interface UserListener { - int USER_SWITCHED = 1; + int CURRENT_USER_CHANGED = 1; int USER_STARTED = 2; int USER_STOPPED = 3; - @IntDef({USER_SWITCHED, USER_STARTED, USER_STOPPED}) + @IntDef({CURRENT_USER_CHANGED, USER_STARTED, USER_STOPPED}) @Retention(RetentionPolicy.SOURCE) @interface UserChange {} @@ -74,144 +74,102 @@ public class UserInfoHelper { private final Context mContext; private final CopyOnWriteArrayList mListeners; + @GuardedBy("this") + @Nullable private ActivityManagerInternal mActivityManagerInternal; @GuardedBy("this") @Nullable private UserManager mUserManager; - @UserIdInt private volatile int mCurrentUserId; - - @GuardedBy("this") - @UserIdInt private int mCachedParentUserId; - @GuardedBy("this") - private int[] mCachedProfileUserIds; - public UserInfoHelper(Context context) { mContext = context; mListeners = new CopyOnWriteArrayList<>(); - - mCurrentUserId = UserHandle.USER_NULL; - mCachedParentUserId = UserHandle.USER_NULL; - mCachedProfileUserIds = new int[]{UserHandle.USER_NULL}; } /** Called when system is ready. */ + @CallSuper public synchronized void onSystemReady() { - if (mUserManager != null) { + if (mActivityManagerInternal != null) { return; } + mActivityManagerInternal = Objects.requireNonNull( + LocalServices.getService(ActivityManagerInternal.class)); mUserManager = mContext.getSystemService(UserManager.class); - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_USER_SWITCHED); - intentFilter.addAction(Intent.ACTION_USER_STARTED); - intentFilter.addAction(Intent.ACTION_USER_STOPPED); - intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); - intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); - - mContext.registerReceiverAsUser(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action == null) { - return; - } - int userId; - switch (action) { - case Intent.ACTION_USER_SWITCHED: - userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); - if (userId != UserHandle.USER_NULL) { - onCurrentUserChanged(userId); - } - break; - case Intent.ACTION_USER_STARTED: - userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); - if (userId != UserHandle.USER_NULL) { - onUserStarted(userId); - } - break; - case Intent.ACTION_USER_STOPPED: - userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); - if (userId != UserHandle.USER_NULL) { - onUserStopped(userId); - } - break; - case Intent.ACTION_MANAGED_PROFILE_ADDED: - case Intent.ACTION_MANAGED_PROFILE_REMOVED: - onUserProfilesChanged(); - break; - } - } - }, UserHandle.ALL, intentFilter, null, FgThread.getHandler()); - - mCurrentUserId = ActivityManager.getCurrentUser(); } /** * Adds a listener for user changed events. Callbacks occur on an unspecified thread. */ - public void addListener(UserListener listener) { + public final void addListener(UserListener listener) { mListeners.add(listener); } /** * Removes a listener for user changed events. */ - public void removeListener(UserListener listener) { + public final void removeListener(UserListener listener) { mListeners.remove(listener); } - private void onCurrentUserChanged(@UserIdInt int newUserId) { - if (newUserId == mCurrentUserId) { - return; - } - - if (D) { - Log.d(TAG, "current user switched from u" + mCurrentUserId + " to u" + newUserId); - } - - int oldUserId = mCurrentUserId; - mCurrentUserId = newUserId; - - onUserChanged(oldUserId, UserListener.USER_SWITCHED); - onUserChanged(newUserId, UserListener.USER_SWITCHED); - } - - private void onUserStarted(@UserIdInt int userId) { + protected void dispatchOnUserStarted(@UserIdInt int userId) { if (D) { Log.d(TAG, "u" + userId + " started"); } - onUserChanged(userId, UserListener.USER_STARTED); + for (UserListener listener : mListeners) { + listener.onUserChanged(userId, USER_STARTED); + } } - private void onUserStopped(@UserIdInt int userId) { + protected void dispatchOnUserStopped(@UserIdInt int userId) { if (D) { Log.d(TAG, "u" + userId + " stopped"); } - onUserChanged(userId, UserListener.USER_STOPPED); - } - - private void onUserChanged(@UserIdInt int userId, @UserListener.UserChange int change) { for (UserListener listener : mListeners) { - listener.onUserChanged(userId, change); + listener.onUserChanged(userId, USER_STOPPED); } } - private synchronized void onUserProfilesChanged() { - // this intent is only sent to the current user - if (mCachedParentUserId == mCurrentUserId) { - mCachedParentUserId = UserHandle.USER_NULL; - mCachedProfileUserIds = new int[]{UserHandle.USER_NULL}; + protected void dispatchOnCurrentUserChanged(@UserIdInt int fromUserId, + @UserIdInt int toUserId) { + int[] fromUserIds = getProfileIds(fromUserId); + int[] toUserIds = getProfileIds(toUserId); + if (D) { + Log.d(TAG, "current user changed from u" + Arrays.toString(fromUserIds) + " to u" + + Arrays.toString(toUserIds)); + } + + for (UserListener listener : mListeners) { + for (int userId : fromUserIds) { + listener.onUserChanged(userId, CURRENT_USER_CHANGED); + } + } + + for (UserListener listener : mListeners) { + for (int userId : toUserIds) { + listener.onUserChanged(userId, CURRENT_USER_CHANGED); + } } } /** * Returns an array of current user ids. This will always include the current user, and will - * also include any profiles of the current user. + * also include any profiles of the current user. The caller must never mutate the returned + * array. */ public int[] getCurrentUserIds() { - return getProfileUserIdsForParentUser(mCurrentUserId); + synchronized (this) { + if (mActivityManagerInternal == null) { + return new int[] {}; + } + } + + long identity = Binder.clearCallingIdentity(); + try { + return mActivityManagerInternal.getCurrentProfileIds(); + } finally { + Binder.restoreCallingIdentity(identity); + } } /** @@ -219,54 +177,47 @@ public class UserInfoHelper { * user. */ public boolean isCurrentUserId(@UserIdInt int userId) { - int currentUserId = mCurrentUserId; - return userId == currentUserId || ArrayUtils.contains( - getProfileUserIdsForParentUser(currentUserId), userId); - } - - @GuardedBy("this") - private synchronized int[] getProfileUserIdsForParentUser(@UserIdInt int parentUserId) { - if (parentUserId != mCachedParentUserId) { - long identity = Binder.clearCallingIdentity(); - try { - Preconditions.checkState(mUserManager != null); - - // more expensive check - check that argument really is a parent user id - if (Build.IS_DEBUGGABLE) { - Preconditions.checkArgument( - mUserManager.getProfileParent(parentUserId) == null); - } - - mCachedParentUserId = parentUserId; - mCachedProfileUserIds = mUserManager.getProfileIdsWithDisabled(parentUserId); - } finally { - Binder.restoreCallingIdentity(identity); + synchronized (this) { + if (mActivityManagerInternal == null) { + return false; } } - return mCachedProfileUserIds; + long identity = Binder.clearCallingIdentity(); + try { + return mActivityManagerInternal.isCurrentProfile(userId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + private int[] getProfileIds(@UserIdInt int userId) { + synchronized (this) { + Preconditions.checkState(mUserManager != null); + } + + long identity = Binder.clearCallingIdentity(); + try { + return mUserManager.getEnabledProfileIds(userId); + } finally { + Binder.restoreCallingIdentity(identity); + } } /** * Dump info for debugging. */ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - boolean systemRunning; - synchronized (this) { - systemRunning = mUserManager != null; - } - - if (systemRunning) { - int[] currentUserIds = getProfileUserIdsForParentUser(mCurrentUserId); - pw.println("current users: " + Arrays.toString(currentUserIds)); - for (int userId : currentUserIds) { - if (mUserManager.hasUserRestrictionForUser(DISALLOW_SHARE_LOCATION, + int[] currentUserProfiles = getCurrentUserIds(); + pw.println("current users: " + Arrays.toString(currentUserProfiles)); + UserManager userManager = mContext.getSystemService(UserManager.class); + if (userManager != null) { + for (int userId : currentUserProfiles) { + if (userManager.hasUserRestrictionForUser(DISALLOW_SHARE_LOCATION, UserHandle.of(userId))) { pw.println(" u" + userId + " restricted"); } } - } else { - pw.println("current user: " + mCurrentUserId); } } } diff --git a/services/tests/mockingservicestests/src/com/android/server/location/UserInfoHelperTest.java b/services/tests/mockingservicestests/src/com/android/server/location/UserInfoHelperTest.java index 71e79b331cae3..56727e81bda5f 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/UserInfoHelperTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/UserInfoHelperTest.java @@ -16,34 +16,23 @@ package com.android.server.location; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.isNull; -import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; -import android.app.ActivityManager; -import android.content.BroadcastReceiver; +import android.app.ActivityManagerInternal; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.UserInfo; -import android.os.Handler; -import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.dx.mockito.inline.extended.StaticMockitoSession; +import com.android.server.LocalServices; import com.android.server.location.UserInfoHelper.UserListener; import org.junit.After; @@ -51,16 +40,18 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.quality.Strictness; - -import java.util.ArrayList; -import java.util.List; @Presubmit @SmallTest @RunWith(AndroidJUnit4.class) public class UserInfoHelperTest { + private static class TestUserInfoHelper extends UserInfoHelper { + TestUserInfoHelper(Context context) { + super(context); + } + } + private static final int USER1_ID = 1; private static final int USER1_MANAGED_ID = 11; private static final int[] USER1_PROFILES = new int[]{USER1_ID, USER1_MANAGED_ID}; @@ -70,69 +61,30 @@ public class UserInfoHelperTest { @Mock private Context mContext; @Mock private UserManager mUserManager; + @Mock private ActivityManagerInternal mActivityManagerInternal; - private StaticMockitoSession mMockingSession; - private List mBroadcastReceivers = new ArrayList<>(); - - private UserInfoHelper mHelper; + private TestUserInfoHelper mHelper; @Before public void setUp() { - mMockingSession = mockitoSession() - .initMocks(this) - .spyStatic(ActivityManager.class) - .strictness(Strictness.WARN) - .startMocking(); + initMocks(this); + LocalServices.addService(ActivityManagerInternal.class, mActivityManagerInternal); doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); - doAnswer(invocation -> { - mBroadcastReceivers.add(invocation.getArgument(0)); - return null; - }).when(mContext).registerReceiverAsUser(any(BroadcastReceiver.class), any( - UserHandle.class), any(IntentFilter.class), isNull(), any(Handler.class)); - doReturn(USER1_PROFILES).when(mUserManager).getProfileIdsWithDisabled(USER1_ID); - doReturn(USER2_PROFILES).when(mUserManager).getProfileIdsWithDisabled(USER2_ID); - doReturn(new UserInfo(USER1_ID, "", 0)).when(mUserManager).getProfileParent( - USER1_MANAGED_ID); - doReturn(new UserInfo(USER2_ID, "", 0)).when(mUserManager).getProfileParent( - USER2_MANAGED_ID); - doReturn(USER1_ID).when(ActivityManager::getCurrentUser); + doReturn(USER1_PROFILES).when(mUserManager).getEnabledProfileIds(USER1_ID); + doReturn(USER2_PROFILES).when(mUserManager).getEnabledProfileIds(USER2_ID); + doReturn(true).when(mActivityManagerInternal).isCurrentProfile(USER1_ID); + doReturn(true).when(mActivityManagerInternal).isCurrentProfile(USER1_MANAGED_ID); + doReturn(USER1_PROFILES).when(mActivityManagerInternal).getCurrentProfileIds(); - mHelper = new UserInfoHelper(mContext); + mHelper = new TestUserInfoHelper(mContext); mHelper.onSystemReady(); } @After public void tearDown() { - if (mMockingSession != null) { - mMockingSession.finishMocking(); - } - } - - private void switchUser(int userId) { - doReturn(userId).when(ActivityManager::getCurrentUser); - Intent intent = new Intent(Intent.ACTION_USER_SWITCHED).putExtra(Intent.EXTRA_USER_HANDLE, - userId); - for (BroadcastReceiver broadcastReceiver : mBroadcastReceivers) { - broadcastReceiver.onReceive(mContext, intent); - } - } - - private void startUser(int userId) { - Intent intent = new Intent(Intent.ACTION_USER_STARTED).putExtra(Intent.EXTRA_USER_HANDLE, - userId); - for (BroadcastReceiver broadcastReceiver : mBroadcastReceivers) { - broadcastReceiver.onReceive(mContext, intent); - } - } - - private void stopUser(int userId) { - Intent intent = new Intent(Intent.ACTION_USER_STOPPED).putExtra(Intent.EXTRA_USER_HANDLE, - userId); - for (BroadcastReceiver broadcastReceiver : mBroadcastReceivers) { - broadcastReceiver.onReceive(mContext, intent); - } + LocalServices.removeServiceForTest(ActivityManagerInternal.class); } @Test @@ -140,16 +92,21 @@ public class UserInfoHelperTest { UserListener listener = mock(UserListener.class); mHelper.addListener(listener); - switchUser(USER1_ID); - verify(listener, never()).onUserChanged(anyInt(), anyInt()); + mHelper.dispatchOnCurrentUserChanged(USER1_ID, USER2_ID); + verify(listener, times(1)).onUserChanged(USER1_ID, UserListener.CURRENT_USER_CHANGED); + verify(listener, times(1)).onUserChanged(USER1_MANAGED_ID, + UserListener.CURRENT_USER_CHANGED); + verify(listener, times(1)).onUserChanged(USER2_ID, UserListener.CURRENT_USER_CHANGED); + verify(listener, times(1)).onUserChanged(USER2_MANAGED_ID, + UserListener.CURRENT_USER_CHANGED); - switchUser(USER2_ID); - verify(listener, times(1)).onUserChanged(USER1_ID, UserListener.USER_SWITCHED); - verify(listener, times(1)).onUserChanged(USER2_ID, UserListener.USER_SWITCHED); - - switchUser(USER1_ID); - verify(listener, times(2)).onUserChanged(USER1_ID, UserListener.USER_SWITCHED); - verify(listener, times(2)).onUserChanged(USER2_ID, UserListener.USER_SWITCHED); + mHelper.dispatchOnCurrentUserChanged(USER2_ID, USER1_ID); + verify(listener, times(2)).onUserChanged(USER2_ID, UserListener.CURRENT_USER_CHANGED); + verify(listener, times(2)).onUserChanged(USER2_MANAGED_ID, + UserListener.CURRENT_USER_CHANGED); + verify(listener, times(2)).onUserChanged(USER1_ID, UserListener.CURRENT_USER_CHANGED); + verify(listener, times(2)).onUserChanged(USER1_MANAGED_ID, + UserListener.CURRENT_USER_CHANGED); } @Test @@ -157,11 +114,11 @@ public class UserInfoHelperTest { UserListener listener = mock(UserListener.class); mHelper.addListener(listener); - startUser(USER1_ID); + mHelper.dispatchOnUserStarted(USER1_ID); verify(listener).onUserChanged(USER1_ID, UserListener.USER_STARTED); - startUser(USER2_ID); - verify(listener).onUserChanged(USER2_ID, UserListener.USER_STARTED); + mHelper.dispatchOnUserStarted(USER1_MANAGED_ID); + verify(listener).onUserChanged(USER1_MANAGED_ID, UserListener.USER_STARTED); } @Test @@ -169,24 +126,22 @@ public class UserInfoHelperTest { UserListener listener = mock(UserListener.class); mHelper.addListener(listener); - stopUser(USER1_ID); - verify(listener).onUserChanged(USER1_ID, UserListener.USER_STOPPED); - - stopUser(USER2_ID); + mHelper.dispatchOnUserStopped(USER2_ID); verify(listener).onUserChanged(USER2_ID, UserListener.USER_STOPPED); + + mHelper.dispatchOnUserStopped(USER2_MANAGED_ID); + verify(listener).onUserChanged(USER2_MANAGED_ID, UserListener.USER_STOPPED); } @Test public void testCurrentUserIds() { assertThat(mHelper.getCurrentUserIds()).isEqualTo(USER1_PROFILES); - switchUser(USER2_ID); + doReturn(true).when(mActivityManagerInternal).isCurrentProfile(USER2_ID); + doReturn(true).when(mActivityManagerInternal).isCurrentProfile(USER2_MANAGED_ID); + doReturn(USER2_PROFILES).when(mActivityManagerInternal).getCurrentProfileIds(); assertThat(mHelper.getCurrentUserIds()).isEqualTo(USER2_PROFILES); - - switchUser(USER1_ID); - - assertThat(mHelper.getCurrentUserIds()).isEqualTo(USER1_PROFILES); } @Test @@ -196,7 +151,11 @@ public class UserInfoHelperTest { assertThat(mHelper.isCurrentUserId(USER2_ID)).isFalse(); assertThat(mHelper.isCurrentUserId(USER2_MANAGED_ID)).isFalse(); - switchUser(USER2_ID); + doReturn(false).when(mActivityManagerInternal).isCurrentProfile(USER1_ID); + doReturn(false).when(mActivityManagerInternal).isCurrentProfile(USER1_MANAGED_ID); + doReturn(true).when(mActivityManagerInternal).isCurrentProfile(USER2_ID); + doReturn(true).when(mActivityManagerInternal).isCurrentProfile(USER2_MANAGED_ID); + doReturn(USER2_PROFILES).when(mActivityManagerInternal).getCurrentProfileIds(); assertThat(mHelper.isCurrentUserId(USER1_ID)).isFalse(); assertThat(mHelper.isCurrentUserId(USER2_ID)).isTrue();