diff --git a/res/xml/storage_category_fragment.xml b/res/xml/storage_category_fragment.xml index 973183614c4..2c9588938a2 100644 --- a/res/xml/storage_category_fragment.xml +++ b/res/xml/storage_category_fragment.xml @@ -73,7 +73,7 @@ android:order="108"/> diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml index e234cadd591..7c0f3a6d195 100644 --- a/res/xml/storage_dashboard_fragment.xml +++ b/res/xml/storage_dashboard_fragment.xml @@ -92,7 +92,7 @@ android:order="108"/> diff --git a/src/com/android/settings/deviceinfo/StorageCategoryFragment.java b/src/com/android/settings/deviceinfo/StorageCategoryFragment.java index fe545b592e4..31b73bc156d 100644 --- a/src/com/android/settings/deviceinfo/StorageCategoryFragment.java +++ b/src/com/android/settings/deviceinfo/StorageCategoryFragment.java @@ -16,6 +16,8 @@ package com.android.settings.deviceinfo; +import static java.util.Collections.EMPTY_LIST; + import android.app.settings.SettingsEnums; import android.app.usage.StorageStatsManager; import android.content.Context; @@ -29,13 +31,15 @@ import android.view.View; import androidx.annotation.VisibleForTesting; import androidx.loader.app.LoaderManager; import androidx.loader.content.Loader; +import androidx.preference.PreferenceGroup; +import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.profileselector.ProfileSelectFragment; import com.android.settings.deviceinfo.storage.ManageStoragePreferenceController; -import com.android.settings.deviceinfo.storage.SecondaryUserController; +import com.android.settings.deviceinfo.storage.NonCurrentUserController; import com.android.settings.deviceinfo.storage.StorageAsyncLoader; import com.android.settings.deviceinfo.storage.StorageCacheHelper; import com.android.settings.deviceinfo.storage.StorageEntry; @@ -49,7 +53,6 @@ import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider; import java.util.ArrayList; import java.util.List; -import java.util.Optional; /** * Storage Settings main UI is composed by 3 fragments: @@ -70,6 +73,7 @@ public class StorageCategoryFragment extends DashboardFragment private static final String TAG = "StorageCategoryFrag"; private static final String SELECTED_STORAGE_ENTRY_KEY = "selected_storage_entry_key"; private static final String SUMMARY_PREF_KEY = "storage_summary"; + private static final String TARGET_PREFERENCE_GROUP_KEY = "pref_non_current_users"; private static final int STORAGE_JOB_ID = 0; private static final int ICON_JOB_ID = 1; private static final int VOLUME_SIZE_JOB_ID = 2; @@ -81,7 +85,7 @@ public class StorageCategoryFragment extends DashboardFragment private SparseArray mAppsResult; private StorageItemPreferenceController mPreferenceController; - private List mSecondaryUsers; + private List mNonCurrentUsers; private boolean mIsWorkProfile; private int mUserId; private boolean mIsLoadedFromCache; @@ -98,9 +102,9 @@ public class StorageCategoryFragment extends DashboardFragment return; } - // To prevent flicker, hides secondary users preference. + // To prevent flicker, hides non-current users preference. // onReceivedSizes will set it visible for private storage. - setSecondaryUsersVisible(false); + setNonCurrentUsersVisible(false); if (!mSelectedStorageEntry.isMounted()) { // Set null volume to hide category stats. @@ -150,8 +154,8 @@ public class StorageCategoryFragment extends DashboardFragment if (mSelectedStorageEntry != null) { refreshUi(mSelectedStorageEntry); } - updateSecondaryUserControllers(mSecondaryUsers, mAppsResult); - setSecondaryUsersVisible(true); + updateNonCurrentUserControllers(mNonCurrentUsers, mAppsResult); + setNonCurrentUsersVisible(true); } } @@ -217,17 +221,13 @@ public class StorageCategoryFragment extends DashboardFragment // Cache total size infor and used size info mStorageCacheHelper .cacheTotalSizeAndTotalUsedSize(mStorageInfo.totalBytes, privateUsedBytes); - for (int i = 0, size = mSecondaryUsers.size(); i < size; i++) { - final AbstractPreferenceController controller = mSecondaryUsers.get(i); - if (controller instanceof SecondaryUserController) { - SecondaryUserController userController = (SecondaryUserController) controller; - userController.setTotalSize(mStorageInfo.totalBytes); - } + for (NonCurrentUserController userController : mNonCurrentUsers) { + userController.setTotalSize(mStorageInfo.totalBytes); } mPreferenceController.onLoadFinished(mAppsResult, mUserId); - updateSecondaryUserControllers(mSecondaryUsers, mAppsResult); - setSecondaryUsersVisible(true); + updateNonCurrentUserControllers(mNonCurrentUsers, mAppsResult); + setNonCurrentUsersVisible(true); } @Override @@ -253,20 +253,18 @@ public class StorageCategoryFragment extends DashboardFragment null /* volume */, new StorageManagerVolumeProvider(sm), mIsWorkProfile); controllers.add(mPreferenceController); - mSecondaryUsers = SecondaryUserController.getSecondaryUserControllers(context, - mUserManager, mIsWorkProfile /* isWorkProfileOnly */); - controllers.addAll(mSecondaryUsers); - + mNonCurrentUsers = mIsWorkProfile ? EMPTY_LIST : + NonCurrentUserController.getNonCurrentUserControllers(context, mUserManager); + controllers.addAll(mNonCurrentUsers); return controllers; } /** - * Updates the secondary user controller sizes. + * Updates the non-current user controller sizes. */ - private void updateSecondaryUserControllers(List controllers, + private void updateNonCurrentUserControllers(List controllers, SparseArray stats) { - for (int i = 0, size = controllers.size(); i < size; i++) { - final AbstractPreferenceController controller = controllers.get(i); + for (AbstractPreferenceController controller : controllers) { if (controller instanceof StorageAsyncLoader.ResultHandler) { StorageAsyncLoader.ResultHandler userController = (StorageAsyncLoader.ResultHandler) controller; @@ -296,6 +294,15 @@ public class StorageCategoryFragment extends DashboardFragment public void onLoaderReset(Loader> loader) { } + @Override + public void displayResourceTilesToScreen(PreferenceScreen screen) { + final PreferenceGroup group = screen.findPreference(TARGET_PREFERENCE_GROUP_KEY); + if (mNonCurrentUsers.isEmpty()) { + screen.removePreference(group); + } + super.displayResourceTilesToScreen(screen); + } + @VisibleForTesting public PrivateStorageInfo getPrivateStorageInfo() { return mStorageInfo; @@ -335,13 +342,9 @@ public class StorageCategoryFragment extends DashboardFragment .isQuotaSupported(mSelectedStorageEntry.getFsUuid()); } - private void setSecondaryUsersVisible(boolean visible) { - final Optional secondaryUserController = mSecondaryUsers.stream() - .filter(controller -> controller instanceof SecondaryUserController) - .map(controller -> (SecondaryUserController) controller) - .findAny(); - if (secondaryUserController.isPresent()) { - secondaryUserController.get().setPreferenceGroupVisible(visible); + private void setNonCurrentUsersVisible(boolean visible) { + if (!mNonCurrentUsers.isEmpty()) { + mNonCurrentUsers.get(0).setPreferenceGroupVisible(visible); } } @@ -361,7 +364,7 @@ public class StorageCategoryFragment extends DashboardFragment @Override public void onLoadFinished( Loader> loader, SparseArray data) { - mSecondaryUsers + mNonCurrentUsers .stream() .filter(controller -> controller instanceof UserIconLoader.UserIconHandler) .forEach( diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java index 1b382981784..368ba9157f3 100644 --- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java +++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java @@ -32,11 +32,12 @@ import android.os.storage.VolumeRecord; import android.provider.SearchIndexableResource; import android.text.TextUtils; import android.util.SparseArray; -import android.view.View; import androidx.annotation.VisibleForTesting; import androidx.loader.app.LoaderManager; import androidx.loader.content.Loader; +import androidx.preference.PreferenceGroup; +import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.Utils; @@ -44,7 +45,7 @@ import com.android.settings.dashboard.DashboardFragment; import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController; import com.android.settings.deviceinfo.storage.DiskInitFragment; import com.android.settings.deviceinfo.storage.ManageStoragePreferenceController; -import com.android.settings.deviceinfo.storage.SecondaryUserController; +import com.android.settings.deviceinfo.storage.NonCurrentUserController; import com.android.settings.deviceinfo.storage.StorageAsyncLoader; import com.android.settings.deviceinfo.storage.StorageCacheHelper; import com.android.settings.deviceinfo.storage.StorageEntry; @@ -64,7 +65,6 @@ import com.android.settingslib.search.SearchIndexable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Optional; /** * Storage Settings main UI is composed by 3 fragments: @@ -86,6 +86,7 @@ public class StorageDashboardFragment extends DashboardFragment private static final String TAG = "StorageDashboardFrag"; private static final String SUMMARY_PREF_KEY = "storage_summary"; private static final String SELECTED_STORAGE_ENTRY_KEY = "selected_storage_entry_key"; + private static final String TARGET_PREFERENCE_GROUP_KEY = "pref_non_current_users"; private static final int STORAGE_JOB_ID = 0; private static final int ICON_JOB_ID = 1; private static final int VOLUME_SIZE_JOB_ID = 2; @@ -101,7 +102,7 @@ public class StorageDashboardFragment extends DashboardFragment private VolumeOptionMenuController mOptionMenuController; private StorageSelectionPreferenceController mStorageSelectionController; private StorageUsageProgressBarPreferenceController mStorageUsageProgressBarController; - private List mSecondaryUsers; + private List mNonCurrentUsers; private boolean mIsWorkProfile; private int mUserId; private boolean mIsLoadedFromCache; @@ -232,9 +233,9 @@ public class StorageDashboardFragment extends DashboardFragment mOptionMenuController.setSelectedStorageEntry(mSelectedStorageEntry); getActivity().invalidateOptionsMenu(); - // To prevent flicker, hides secondary users preference. + // To prevent flicker, hides non-current users preference. // onReceivedSizes will set it visible for private storage. - setSecondaryUsersVisible(false); + setNonCurrentUsersVisible(false); if (!mSelectedStorageEntry.isMounted()) { // Set null volume to hide category stats. @@ -254,7 +255,7 @@ public class StorageDashboardFragment extends DashboardFragment mAppsResult = null; // Hide the loading spinner if there is cached data. if (mStorageCacheHelper.hasCachedSizeInfo()) { - //TODO(b/220259287): apply cache mechanism to secondary user + //TODO(b/220259287): apply cache mechanism to non-current user mPreferenceController.onLoadFinished(mAppsResult, mUserId); } else { maybeSetLoading(isQuotaSupported()); @@ -297,8 +298,8 @@ public class StorageDashboardFragment extends DashboardFragment mStorageEntries.addAll( StorageUtils.getAllStorageEntries(getContext(), mStorageManager)); refreshUi(); - updateSecondaryUserControllers(mSecondaryUsers, mAppsResult); - setSecondaryUsersVisible(true); + updateNonCurrentUserControllers(mNonCurrentUsers, mAppsResult); + setNonCurrentUsersVisible(true); } } @@ -393,17 +394,13 @@ public class StorageDashboardFragment extends DashboardFragment // Cache total size and used size mStorageCacheHelper .cacheTotalSizeAndTotalUsedSize(mStorageInfo.totalBytes, privateUsedBytes); - for (int i = 0, size = mSecondaryUsers.size(); i < size; i++) { - final AbstractPreferenceController controller = mSecondaryUsers.get(i); - if (controller instanceof SecondaryUserController) { - SecondaryUserController userController = (SecondaryUserController) controller; - userController.setTotalSize(mStorageInfo.totalBytes); - } + for (NonCurrentUserController userController : mNonCurrentUsers) { + userController.setTotalSize(mStorageInfo.totalBytes); } mPreferenceController.onLoadFinished(mAppsResult, mUserId); - updateSecondaryUserControllers(mSecondaryUsers, mAppsResult); - setSecondaryUsersVisible(true); + updateNonCurrentUserControllers(mNonCurrentUsers, mAppsResult); + setNonCurrentUsersVisible(true); } @Override @@ -429,20 +426,19 @@ public class StorageDashboardFragment extends DashboardFragment null /* volume */, new StorageManagerVolumeProvider(sm), mIsWorkProfile); controllers.add(mPreferenceController); - mSecondaryUsers = SecondaryUserController.getSecondaryUserControllers(context, - mUserManager, mIsWorkProfile /* isWorkProfileOnly */); - controllers.addAll(mSecondaryUsers); + mNonCurrentUsers = NonCurrentUserController.getNonCurrentUserControllers(context, + mUserManager); + controllers.addAll(mNonCurrentUsers); return controllers; } /** - * Updates the secondary user controller sizes. + * Updates the non-current user controller sizes. */ - private void updateSecondaryUserControllers(List controllers, + private void updateNonCurrentUserControllers(List controllers, SparseArray stats) { - for (int i = 0, size = controllers.size(); i < size; i++) { - final AbstractPreferenceController controller = controllers.get(i); + for (AbstractPreferenceController controller : controllers) { if (controller instanceof StorageAsyncLoader.ResultHandler) { StorageAsyncLoader.ResultHandler userController = (StorageAsyncLoader.ResultHandler) controller; @@ -473,8 +469,8 @@ public class StorageDashboardFragment extends DashboardFragment controllers.add(new StorageItemPreferenceController(context, null /* host */, null /* volume */, new StorageManagerVolumeProvider(sm), false /* isWorkProfile */)); - controllers.addAll(SecondaryUserController.getSecondaryUserControllers( - context, userManager, false /* isWorkProfileOnly */)); + controllers.addAll(NonCurrentUserController.getNonCurrentUserControllers( + context, userManager)); return controllers; } @@ -501,6 +497,16 @@ public class StorageDashboardFragment extends DashboardFragment public void onLoaderReset(Loader> loader) { } + + @Override + public void displayResourceTilesToScreen(PreferenceScreen screen) { + final PreferenceGroup group = screen.findPreference(TARGET_PREFERENCE_GROUP_KEY); + if (mNonCurrentUsers.isEmpty()) { + screen.removePreference(group); + } + super.displayResourceTilesToScreen(screen); + } + @VisibleForTesting public PrivateStorageInfo getPrivateStorageInfo() { return mStorageInfo; @@ -540,13 +546,9 @@ public class StorageDashboardFragment extends DashboardFragment .isQuotaSupported(mSelectedStorageEntry.getFsUuid()); } - private void setSecondaryUsersVisible(boolean visible) { - final Optional secondaryUserController = mSecondaryUsers.stream() - .filter(controller -> controller instanceof SecondaryUserController) - .map(controller -> (SecondaryUserController) controller) - .findAny(); - if (secondaryUserController.isPresent()) { - secondaryUserController.get().setPreferenceGroupVisible(visible); + private void setNonCurrentUsersVisible(boolean visible) { + if (!mNonCurrentUsers.isEmpty()) { + mNonCurrentUsers.get(0).setPreferenceGroupVisible(visible); } } @@ -566,7 +568,7 @@ public class StorageDashboardFragment extends DashboardFragment @Override public void onLoadFinished( Loader> loader, SparseArray data) { - mSecondaryUsers + mNonCurrentUsers .stream() .filter(controller -> controller instanceof UserIconLoader.UserIconHandler) .forEach( diff --git a/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java b/src/com/android/settings/deviceinfo/storage/NonCurrentUserController.java similarity index 65% rename from src/com/android/settings/deviceinfo/storage/SecondaryUserController.java rename to src/com/android/settings/deviceinfo/storage/NonCurrentUserController.java index 9a280bfa4e2..fe7fa7c5d71 100644 --- a/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java +++ b/src/com/android/settings/deviceinfo/storage/NonCurrentUserController.java @@ -16,6 +16,7 @@ package com.android.settings.deviceinfo.storage; +import android.app.ActivityManager; import android.content.Context; import android.content.pm.UserInfo; import android.graphics.drawable.Drawable; @@ -28,7 +29,6 @@ import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; -import com.android.settings.Utils; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.deviceinfo.StorageItemPreference; import com.android.settingslib.core.AbstractPreferenceController; @@ -37,14 +37,14 @@ import java.util.ArrayList; import java.util.List; /** - * SecondaryUserController controls the preferences on the Storage screen which had to do with - * secondary users. + * NonCurrentUserController controls the preferences on the Storage screen which had to do with + * other users. */ -public class SecondaryUserController extends AbstractPreferenceController implements +public class NonCurrentUserController extends AbstractPreferenceController implements PreferenceControllerMixin, StorageAsyncLoader.ResultHandler, UserIconLoader.UserIconHandler { // PreferenceGroupKey to try to add our preference onto. - private static final String TARGET_PREFERENCE_GROUP_KEY = "pref_secondary_users"; + private static final String TARGET_PREFERENCE_GROUP_KEY = "pref_non_current_users"; private static final String PREFERENCE_KEY_BASE = "pref_user_"; private static final int SIZE_NOT_SET = -1; @@ -57,60 +57,60 @@ public class SecondaryUserController extends AbstractPreferenceController implem private long mSize; private long mTotalSizeBytes; private boolean mIsVisible; + private int[] mProfiles; private StorageCacheHelper mStorageCacheHelper; /** - * Adds the appropriate controllers to a controller list for handling all secondary users on - * a device. + * Adds the appropriate controllers to a controller list for handling all full non current + * users on a device. * - * @param context Context for initializing the preference controllers. - * @param userManager UserManagerWrapper for figuring out which controllers to add. - * @param isWorkProfileOnly only shows secondary users of work profile. - * (e.g., it should be true in work profile tab) + * @param context Context for initializing the preference controllers. + * @param userManager UserManagerWrapper for figuring out which controllers to add. */ - public static List getSecondaryUserControllers( - Context context, UserManager userManager, boolean isWorkProfileOnly) { - - List controllers = new ArrayList<>(); - UserInfo primaryUser = userManager.getPrimaryUser(); - boolean addedUser = false; + public static List getNonCurrentUserControllers( + Context context, UserManager userManager) { + int currentUserId = ActivityManager.getCurrentUser(); + List controllers = new ArrayList<>(); List infos = userManager.getUsers(); - for (int i = 0, size = infos.size(); i < size; i++) { - UserInfo info = infos.get(i); - if (info.isPrimary()) { + for (UserInfo info : infos) { + if (info.id == currentUserId || info.isProfile()) { continue; } - - if (Utils.isProfileOf(primaryUser, info)) { - continue; - } - - if (isWorkProfileOnly && !info.isManagedProfile()) { - continue; - } - - controllers.add(new SecondaryUserController(context, info)); - addedUser = true; - } - - if (!addedUser) { - controllers.add(new NoSecondaryUserController(context)); + int[] profiles = userManager.getProfileIds(info.id, false /* enabledOnly */); + controllers.add(new NonCurrentUserController(context, info, profiles)); } return controllers; } /** - * Constructor for a given secondary user. + * Constructor for a given non-current user. * * @param context Context to initialize the underlying {@link AbstractPreferenceController}. - * @param info {@link UserInfo} for the secondary user which this controllers covers. + * @param info {@link UserInfo} for the non-current user which these controllers cover. + * @param profiles list of IDs or user and its profiles */ @VisibleForTesting - SecondaryUserController(Context context, @NonNull UserInfo info) { + NonCurrentUserController(Context context, @NonNull UserInfo info, @NonNull int[] profiles) { super(context); mUser = info; mSize = SIZE_NOT_SET; mStorageCacheHelper = new StorageCacheHelper(context, info.id); + mProfiles = profiles; + } + + /** + * Constructor for a given non-current user. + * + * @param context Context to initialize the underlying {@link AbstractPreferenceController}. + * @param info {@link UserInfo} for the non-current user which these controllers cover. + */ + @VisibleForTesting + NonCurrentUserController(Context context, @NonNull UserInfo info) { + super(context); + mUser = info; + mSize = SIZE_NOT_SET; + mStorageCacheHelper = new StorageCacheHelper(context, info.id); + mProfiles = new int[]{info.id}; } @Override @@ -140,7 +140,7 @@ public class SecondaryUserController extends AbstractPreferenceController implem } /** - * Returns the user for which this is the secondary user controller. + * Returns the user for which this is the non-current user controller. */ @NonNull public UserInfo getUser() { @@ -169,7 +169,7 @@ public class SecondaryUserController extends AbstractPreferenceController implem } /** - * Sets visibility of the PreferenceGroup of secondary user. + * Sets visibility of the PreferenceGroup of non-current user. * * @param visible Visibility of the PreferenceGroup. */ @@ -187,10 +187,15 @@ public class SecondaryUserController extends AbstractPreferenceController implem return; } final StorageAsyncLoader.StorageResult result = stats.get(getUser().id); + if (result != null) { - setSize(result.externalStats.totalBytes, true /* animate */); + long totalSize = 0; + for (int id : mProfiles) { + totalSize += stats.get(id).externalStats.totalBytes; + } + setSize(totalSize, true /* animate */); // TODO(b/171758224): Update the source of size info - mStorageCacheHelper.cacheUsedSize(result.externalStats.totalBytes); + mStorageCacheHelper.cacheUsedSize(totalSize); } } @@ -205,31 +210,4 @@ public class SecondaryUserController extends AbstractPreferenceController implem mStoragePreference.setIcon(mUserIcon); } } - - @VisibleForTesting - static class NoSecondaryUserController extends AbstractPreferenceController implements - PreferenceControllerMixin { - public NoSecondaryUserController(Context context) { - super(context); - } - - @Override - public void displayPreference(PreferenceScreen screen) { - final PreferenceGroup group = screen.findPreference(TARGET_PREFERENCE_GROUP_KEY); - if (group == null) { - return; - } - screen.removePreference(group); - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public String getPreferenceKey() { - return null; - } - } } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/NonCurrentUserControllerTest.java similarity index 72% rename from tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java rename to tests/robotests/src/com/android/settings/deviceinfo/storage/NonCurrentUserControllerTest.java index eb8f5f40535..684128c436f 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/NonCurrentUserControllerTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.IActivityManager; import android.content.Context; import android.content.pm.UserInfo; import android.graphics.drawable.Drawable; @@ -36,10 +37,11 @@ import androidx.preference.Preference; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; +import com.android.settings.testutils.shadow.ShadowActivityManager; import com.android.settingslib.applications.StorageStatsSource; -import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.drawable.UserIconDrawable; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -48,12 +50,14 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) -public class SecondaryUserControllerTest { +@Config(shadows = {ShadowActivityManager.class}) +public class NonCurrentUserControllerTest { private static final String TEST_NAME = "Fred"; private static final String TARGET_PREFERENCE_GROUP_KEY = "pref_secondary_users"; @@ -63,18 +67,22 @@ public class SecondaryUserControllerTest { private PreferenceScreen mScreen; @Mock private PreferenceGroup mGroup; + @Mock + private IActivityManager mActivityService; private Context mContext; - private SecondaryUserController mController; + private NonCurrentUserController mController; private UserInfo mPrimaryUser; + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; mPrimaryUser = new UserInfo(); mPrimaryUser.flags = UserInfo.FLAG_PRIMARY; - mController = new SecondaryUserController(mContext, mPrimaryUser); + mController = new NonCurrentUserController(mContext, mPrimaryUser); + ShadowActivityManager.setService(mActivityService); when(mScreen.getContext()).thenReturn(mContext); when(mScreen.findPreference(anyString())).thenReturn(mGroup); @@ -82,6 +90,11 @@ public class SecondaryUserControllerTest { } + @After + public void tearDown() { + ShadowActivityManager.setCurrentUser(mPrimaryUser.id); + } + @Test public void controllerAddsSecondaryUser() { mPrimaryUser.name = TEST_NAME; @@ -107,22 +120,18 @@ public class SecondaryUserControllerTest { } @Test - public void noSecondaryUserAddedIfNoneExist() { + public void noNonCurrentUserAddedIfNoneExist() { final ArrayList userInfos = new ArrayList<>(); userInfos.add(mPrimaryUser); when(mUserManager.getPrimaryUser()).thenReturn(mPrimaryUser); when(mUserManager.getUsers()).thenReturn(userInfos); - final List controllers = - SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager, - false /* isWorkProfileOnly */); - - assertThat(controllers).hasSize(1); - // We should have the NoSecondaryUserController. - assertThat(controllers.get(0) instanceof SecondaryUserController).isFalse(); + final List controllers = + NonCurrentUserController.getNonCurrentUserControllers(mContext, mUserManager); + assertThat(controllers).hasSize(0); } @Test - public void getSecondaryUserControllers_notWorkProfile_addSecondaryUserController() { + public void getNonCurrentUserControllers_notWorkProfile_addNonCurrentUserController() { final ArrayList userInfos = new ArrayList<>(); final UserInfo secondaryUser = spy(new UserInfo()); secondaryUser.id = 10; @@ -131,17 +140,16 @@ public class SecondaryUserControllerTest { userInfos.add(mPrimaryUser); userInfos.add(secondaryUser); when(mUserManager.getPrimaryUser()).thenReturn(mPrimaryUser); + ShadowActivityManager.setCurrentUser(secondaryUser.id); when(mUserManager.getUsers()).thenReturn(userInfos); - final List controllers = - SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager, - false /* isWorkProfileOnly */); + final List controllers = + NonCurrentUserController.getNonCurrentUserControllers(mContext, mUserManager); assertThat(controllers).hasSize(1); - assertThat(controllers.get(0) instanceof SecondaryUserController).isTrue(); } @Test - public void getSecondaryUserControllers_workProfile_addNoSecondaryUserController() { + public void getNonCurrentUserControllers_workProfileOfNonCurrentUser() { final ArrayList userInfos = new ArrayList<>(); final UserInfo secondaryUser = spy(new UserInfo()); secondaryUser.id = 10; @@ -150,56 +158,37 @@ public class SecondaryUserControllerTest { userInfos.add(mPrimaryUser); userInfos.add(secondaryUser); when(mUserManager.getPrimaryUser()).thenReturn(mPrimaryUser); + when(secondaryUser.isProfile()).thenReturn(true); when(mUserManager.getUsers()).thenReturn(userInfos); - final List controllers = - SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager, - false /* isWorkProfileOnly */); + final List controllers = + NonCurrentUserController.getNonCurrentUserControllers(mContext, mUserManager); - assertThat(controllers).hasSize(1); - assertThat(controllers.get(0) instanceof SecondaryUserController).isTrue(); + assertThat(controllers).hasSize(0); } @Test - public void getSecondaryUserControllers_notWorkProfileWorkProfileOnly_addNoSecondController() { - final ArrayList userInfos = new ArrayList<>(); - final UserInfo secondaryUser = spy(new UserInfo()); - secondaryUser.id = 10; - secondaryUser.profileGroupId = 101010; // this just has to be something not 0 - when(secondaryUser.isManagedProfile()).thenReturn(false); - userInfos.add(mPrimaryUser); - userInfos.add(secondaryUser); - when(mUserManager.getPrimaryUser()).thenReturn(mPrimaryUser); - when(mUserManager.getUsers()).thenReturn(userInfos); - final List controllers = - SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager, - true /* isWorkProfileOnly */); - - assertThat(controllers).hasSize(1); - assertThat(controllers.get(0) instanceof SecondaryUserController).isFalse(); - } - - @Test - public void profilesOfPrimaryUserAreIgnored() { + public void profilesOfCurrentUserAreIgnored() { final ArrayList userInfos = new ArrayList<>(); final UserInfo secondaryUser = new UserInfo(); secondaryUser.id = mPrimaryUser.id; userInfos.add(mPrimaryUser); userInfos.add(secondaryUser); + userInfos.add(secondaryUser); when(mUserManager.getPrimaryUser()).thenReturn(mPrimaryUser); when(mUserManager.getUsers()).thenReturn(userInfos); - final List controllers = - SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager, - false /* isWorkProfileOnly */); + final List controllers = + NonCurrentUserController.getNonCurrentUserControllers(mContext, mUserManager); - assertThat(controllers).hasSize(1); - assertThat(controllers.get(0) instanceof SecondaryUserController).isFalse(); + assertThat(controllers).hasSize(0); } @Test public void handleResult_noStatsResult_shouldShowCachedData() { mPrimaryUser.name = TEST_NAME; mPrimaryUser.id = 10; + int[] profiles = {mPrimaryUser.id}; + mController = new NonCurrentUserController(mContext, mPrimaryUser, profiles); mController.displayPreference(mScreen); final StorageAsyncLoader.StorageResult userResult = new StorageAsyncLoader.StorageResult(); @@ -232,15 +221,12 @@ public class SecondaryUserControllerTest { primaryUserRenamed.name = "Owner"; primaryUserRenamed.flags = UserInfo.FLAG_PRIMARY; userInfos.add(primaryUserRenamed); - when(mUserManager.getPrimaryUser()).thenReturn(mPrimaryUser); + ShadowActivityManager.setCurrentUser(primaryUserRenamed.id); when(mUserManager.getUsers()).thenReturn(userInfos); - final List controllers = - SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager, - false /* isWorkProfileOnly */); + final List controllers = + NonCurrentUserController.getNonCurrentUserControllers(mContext, mUserManager); - assertThat(controllers).hasSize(1); - // We should have the NoSecondaryUserController. - assertThat(controllers.get(0) instanceof SecondaryUserController).isFalse(); + assertThat(controllers).hasSize(0); } @Test @@ -273,4 +259,31 @@ public class SecondaryUserControllerTest { // Doesn't crash } + + @Test + public void getNonCurrentUserControllers_switchUsers() { + final ArrayList userInfo = new ArrayList<>(); + final UserInfo secondaryUser = spy(new UserInfo()); + secondaryUser.id = 10; + final UserInfo secondaryUser1 = spy(new UserInfo()); + secondaryUser1.id = 11; + userInfo.add(mPrimaryUser); + userInfo.add(secondaryUser); + userInfo.add(secondaryUser1); + when(mUserManager.getPrimaryUser()).thenReturn(mPrimaryUser); + when(mUserManager.getUsers()).thenReturn(userInfo); + List controllers = + NonCurrentUserController.getNonCurrentUserControllers(mContext, mUserManager); + + assertThat(controllers).hasSize(2); + assertThat(controllers.get(0).getUser().id == secondaryUser.id).isTrue(); + + ShadowActivityManager.setCurrentUser(secondaryUser.id); + when(mUserManager.getUsers()).thenReturn(userInfo); + controllers = + NonCurrentUserController.getNonCurrentUserControllers(mContext, mUserManager); + + assertThat(controllers).hasSize(2); + assertThat(controllers.get(0).getUser().id == mPrimaryUser.id).isTrue(); + } }