From fa6e82b8799829f7502e72061dd06ecaa3cce74c Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Thu, 29 Apr 2021 18:54:10 +0800 Subject: [PATCH] Implements profile selection tab in Storage Settings - StorageDashboardFragment and StorageItemPreferenceController works only for one profile per instance. - StorageAsyncLoader loads for all users(profiles) and regards each user independent. - SecondaryUserController will not load personal profile user in work profile tab. - Cleanup some unused profile related files. Bug: 174964885 Test: atest com.android.settings.deviceinfo atest com.android.settings.deviceinfo.storage make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.deviceinfo make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.deviceinfo.storage Change-Id: I8361c29bc240c519c7261b19522c41439479c1c2 --- src/com/android/settings/Utils.java | 13 ++ .../ProfileFragmentBridge.java | 3 + .../ProfileSelectStorageFragment.java | 47 ++++++ .../deviceinfo/StorageDashboardFragment.java | 43 +++--- .../deviceinfo/StorageProfileFragment.java | 138 ------------------ .../storage/SecondaryUserController.java | 10 +- .../storage/StorageAsyncLoader.java | 28 ++-- .../StorageItemPreferenceController.java | 130 ++++++----------- .../storage/UserProfileController.java | 138 ------------------ .../exempt_not_implementing_index_provider | 2 - .../storage/SecondaryUserControllerTest.java | 41 +++++- .../StorageItemPreferenceControllerTest.java | 44 ++++-- .../storage/UserProfileControllerTest.java | 138 ------------------ .../StorageProfileFragmentTest.java | 79 ---------- 14 files changed, 214 insertions(+), 640 deletions(-) create mode 100644 src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java delete mode 100644 src/com/android/settings/deviceinfo/StorageProfileFragment.java delete mode 100644 src/com/android/settings/deviceinfo/storage/UserProfileController.java delete mode 100644 tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java delete mode 100644 tests/unit/src/com/android/settings/deviceinfo/StorageProfileFragmentTest.java diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index fd67aa813b7..7614070981f 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -469,6 +469,19 @@ public final class Utils extends com.android.settingslib.Utils { return UserHandle.USER_NULL; } + /** Returns user ID of current user, throws IllegalStateException if it's not available. */ + public static int getCurrentUserId(UserManager userManager, boolean isWorkProfile) + throws IllegalStateException { + if (isWorkProfile) { + final UserHandle managedUserHandle = getManagedProfile(userManager); + if (managedUserHandle == null) { + throw new IllegalStateException("Work profile user ID is not available."); + } + return managedUserHandle.getIdentifier(); + } + return UserHandle.myUserId(); + } + /** * Returns the target user for a Settings activity. *

diff --git a/src/com/android/settings/dashboard/profileselector/ProfileFragmentBridge.java b/src/com/android/settings/dashboard/profileselector/ProfileFragmentBridge.java index c324acaf54a..704d00b4b2c 100644 --- a/src/com/android/settings/dashboard/profileselector/ProfileFragmentBridge.java +++ b/src/com/android/settings/dashboard/profileselector/ProfileFragmentBridge.java @@ -20,6 +20,7 @@ import android.util.ArrayMap; import com.android.settings.accounts.AccountDashboardFragment; import com.android.settings.applications.manageapplications.ManageApplications; +import com.android.settings.deviceinfo.StorageDashboardFragment; import com.android.settings.location.LocationServices; import com.android.settings.location.RecentLocationAccessSeeAllFragment; @@ -46,5 +47,7 @@ public class ProfileFragmentBridge { ProfileSelectRecentLocationAccessFragment.class.getName()); FRAGMENT_MAP.put(LocationServices.class.getName(), ProfileSelectLocationServicesFragment.class.getName()); + FRAGMENT_MAP.put(StorageDashboardFragment.class.getName(), + ProfileSelectStorageFragment.class.getName()); } } diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java new file mode 100644 index 00000000000..9e505e3607f --- /dev/null +++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.dashboard.profileselector; + +import android.os.Bundle; + +import androidx.fragment.app.Fragment; + +import com.android.settings.deviceinfo.StorageDashboardFragment; + +/** + * Storage Settings page for personal/managed profile. + */ +public class ProfileSelectStorageFragment extends ProfileSelectFragment { + + @Override + public Fragment[] getFragments() { + final Bundle workBundle = new Bundle(); + workBundle.putInt(EXTRA_PROFILE, ProfileType.WORK); + final Fragment workFragment = new StorageDashboardFragment(); + workFragment.setArguments(workBundle); + + final Bundle personalBundle = new Bundle(); + personalBundle.putInt(EXTRA_PROFILE, ProfileType.PERSONAL); + final Fragment personalFragment = new StorageDashboardFragment(); + personalFragment.setArguments(personalBundle); + + return new Fragment[] { + personalFragment, + workFragment + }; + } +} diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java index e7f5ba6e8b3..6a3bb515e81 100644 --- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java +++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java @@ -85,6 +85,7 @@ public class StorageDashboardFragment extends DashboardFragment private static final int VOLUME_SIZE_JOB_ID = 2; private StorageManager mStorageManager; + private UserManager mUserManager; private final List mStorageEntries = new ArrayList<>(); private StorageEntry mSelectedStorageEntry; private PrivateStorageInfo mStorageInfo; @@ -96,7 +97,8 @@ public class StorageDashboardFragment extends DashboardFragment private StorageSelectionPreferenceController mStorageSelectionController; private StorageUsageProgressBarPreferenceController mStorageUsageProgressBarController; private List mSecondaryUsers; - private boolean mPersonalOnly; + private boolean mIsWorkProfile; + private int mUserId; private Preference mFreeUpSpacePreference; private final StorageEventListener mStorageEventListener = new StorageEventListener() { @@ -270,8 +272,6 @@ public class StorageDashboardFragment extends DashboardFragment final Activity activity = getActivity(); mStorageManager = activity.getSystemService(StorageManager.class); - mPersonalOnly = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE) - == ProfileSelectFragment.ProfileType.PERSONAL; if (icicle == null) { final VolumeInfo specifiedVolumeInfo = @@ -288,18 +288,19 @@ public class StorageDashboardFragment extends DashboardFragment } private void initializePreference() { - if (mPersonalOnly) { - final Preference summary = getPreferenceScreen().findPreference(SUMMARY_PREF_KEY); - if (summary != null) { - summary.setVisible(false); - } - } mFreeUpSpacePreference = getPreferenceScreen().findPreference(FREE_UP_SPACE_PREF_KEY); mFreeUpSpacePreference.setOnPreferenceClickListener(this); } @Override public void onAttach(Context context) { + // These member variables are initialized befoer super.onAttach for + // createPreferenceControllers to work correctly. + mUserManager = context.getSystemService(UserManager.class); + mIsWorkProfile = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE) + == ProfileSelectFragment.ProfileType.WORK; + mUserId = Utils.getCurrentUserId(mUserManager, mIsWorkProfile); + super.onAttach(context); use(AutomaticStorageManagementSwitchPreferenceController.class).setFragmentManager( getFragmentManager()); @@ -396,7 +397,7 @@ public class StorageDashboardFragment extends DashboardFragment } if (mAppsResult != null) { - mPreferenceController.onLoadFinished(mAppsResult, UserHandle.myUserId()); + mPreferenceController.onLoadFinished(mAppsResult, mUserId); updateSecondaryUserControllers(mSecondaryUsers, mAppsResult); stopLoading = true; } @@ -427,14 +428,13 @@ public class StorageDashboardFragment extends DashboardFragment @Override protected List createPreferenceControllers(Context context) { final List controllers = new ArrayList<>(); - StorageManager sm = context.getSystemService(StorageManager.class); mPreferenceController = new StorageItemPreferenceController(context, this, - null /* volume */, new StorageManagerVolumeProvider(sm)); + null /* volume */, new StorageManagerVolumeProvider(sm), mIsWorkProfile); controllers.add(mPreferenceController); - final UserManager userManager = context.getSystemService(UserManager.class); - mSecondaryUsers = SecondaryUserController.getSecondaryUserControllers(context, userManager); + mSecondaryUsers = SecondaryUserController.getSecondaryUserControllers(context, + mUserManager, mIsWorkProfile /* isWorkProfileOnly */); controllers.addAll(mSecondaryUsers); return controllers; @@ -480,9 +480,10 @@ public class StorageDashboardFragment extends DashboardFragment final UserManager userManager = context.getSystemService(UserManager.class); final List controllers = new ArrayList<>(); controllers.add(new StorageItemPreferenceController(context, null /* host */, - null /* volume */, new StorageManagerVolumeProvider(sm))); + null /* volume */, new StorageManagerVolumeProvider(sm), + false /* isWorkProfile */)); controllers.addAll(SecondaryUserController.getSecondaryUserControllers( - context, userManager)); + context, userManager, false /* isWorkProfileOnly */)); return controllers; } @@ -492,7 +493,7 @@ public class StorageDashboardFragment extends DashboardFragment public Loader> onCreateLoader(int id, Bundle args) { final Context context = getContext(); - return new StorageAsyncLoader(context, context.getSystemService(UserManager.class), + return new StorageAsyncLoader(context, mUserManager, mSelectedStorageEntry.getFsUuid(), new StorageStatsSource(context), context.getPackageManager()); @@ -519,7 +520,7 @@ public class StorageDashboardFragment extends DashboardFragment metricsFeatureProvider.logClickedPreference(preference, getMetricsCategory()); metricsFeatureProvider.action(context, SettingsEnums.STORAGE_FREE_UP_SPACE_NOW); final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); - context.startActivity(intent); + context.startActivityAsUser(intent, new UserHandle(mUserId)); return true; } return false; @@ -574,16 +575,14 @@ public class StorageDashboardFragment extends DashboardFragment } private void initializeCacheProvider() { - mCachedStorageValuesHelper = - new CachedStorageValuesHelper(getContext(), UserHandle.myUserId()); + mCachedStorageValuesHelper = new CachedStorageValuesHelper(getContext(), mUserId); initializeCachedValues(); onReceivedSizes(); } private void maybeCacheFreshValues() { if (mStorageInfo != null && mAppsResult != null) { - mCachedStorageValuesHelper.cacheResult( - mStorageInfo, mAppsResult.get(UserHandle.myUserId())); + mCachedStorageValuesHelper.cacheResult(mStorageInfo, mAppsResult.get(mUserId)); } } diff --git a/src/com/android/settings/deviceinfo/StorageProfileFragment.java b/src/com/android/settings/deviceinfo/StorageProfileFragment.java deleted file mode 100644 index 360265cfbbd..00000000000 --- a/src/com/android/settings/deviceinfo/StorageProfileFragment.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo; - -import android.app.settings.SettingsEnums; -import android.content.Context; -import android.os.Bundle; -import android.os.UserHandle; -import android.os.UserManager; -import android.os.storage.StorageManager; -import android.os.storage.VolumeInfo; -import android.util.SparseArray; - -import androidx.annotation.VisibleForTesting; -import androidx.loader.app.LoaderManager; -import androidx.loader.content.Loader; - -import com.android.settings.R; -import com.android.settings.Utils; -import com.android.settings.dashboard.DashboardFragment; -import com.android.settings.deviceinfo.storage.StorageAsyncLoader; -import com.android.settings.deviceinfo.storage.StorageAsyncLoader.AppsStorageResult; -import com.android.settings.deviceinfo.storage.StorageItemPreferenceController; -import com.android.settingslib.applications.StorageStatsSource; -import com.android.settingslib.core.AbstractPreferenceController; -import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider; - -import java.util.ArrayList; -import java.util.List; - -/** - * StorageProfileFragment is a fragment which shows the storage results for a profile of the - * primary user. - */ -public class StorageProfileFragment extends DashboardFragment - implements LoaderManager.LoaderCallbacks> { - private static final String TAG = "StorageProfileFragment"; - public static final String USER_ID_EXTRA = "userId"; - private static final int APPS_JOB_ID = 0; - - private VolumeInfo mVolume; - private int mUserId; - private StorageItemPreferenceController mPreferenceController; - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - final Bundle args = getArguments(); - - // Initialize the storage sizes that we can quickly calc. - final Context context = getActivity(); - final StorageManager sm = context.getSystemService(StorageManager.class); - mVolume = Utils.maybeInitializeVolume(sm, args); - if (mVolume == null) { - getActivity().finish(); - return; - } - - mPreferenceController.setVolume(mVolume); - mUserId = args.getInt(USER_ID_EXTRA, UserHandle.myUserId()); - mPreferenceController.setUserId(UserHandle.of(mUserId)); - } - - @Override - public void onResume() { - super.onResume(); - getLoaderManager().initLoader(APPS_JOB_ID, Bundle.EMPTY, this); - } - - @Override - public int getMetricsCategory() { - return SettingsEnums.SETTINGS_STORAGE_PROFILE; - } - - @Override - protected String getLogTag() { - return TAG; - } - - @Override - protected int getPreferenceScreenResId() { - return R.xml.storage_profile_fragment; - } - - @Override - protected List createPreferenceControllers(Context context) { - final List controllers = new ArrayList<>(); - final StorageManager sm = context.getSystemService(StorageManager.class); - mPreferenceController = - new StorageItemPreferenceController( - context, - this, - mVolume, - new StorageManagerVolumeProvider(sm), - /* isWorkProfile */ true); - controllers.add(mPreferenceController); - return controllers; - } - - @Override - public Loader> onCreateLoader(int id, Bundle args) { - final Context context = getContext(); - return new StorageAsyncLoader(context, - context.getSystemService(UserManager.class), - mVolume.fsUuid, - new StorageStatsSource(context), - context.getPackageManager()); - } - - @Override - public void onLoadFinished(Loader> loader, - SparseArray result) { - mPreferenceController.onLoadFinished(result, mUserId); - } - - @Override - public void onLoaderReset(Loader> loader) { - } - - @VisibleForTesting - void setPreferenceController(StorageItemPreferenceController controller) { - mPreferenceController = controller; - } -} diff --git a/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java b/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java index 5d5854749e6..99b67526730 100644 --- a/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java +++ b/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java @@ -63,9 +63,11 @@ public class SecondaryUserController extends AbstractPreferenceController implem * * @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) */ public static List getSecondaryUserControllers( - Context context, UserManager userManager) { + Context context, UserManager userManager, boolean isWorkProfileOnly) { List controllers = new ArrayList<>(); UserInfo primaryUser = userManager.getPrimaryUser(); @@ -77,7 +79,11 @@ public class SecondaryUserController extends AbstractPreferenceController implem continue; } - if (info == null || Utils.isProfileOf(primaryUser, info)) { + if (Utils.isProfileOf(primaryUser, info)) { + continue; + } + + if (isWorkProfileOnly && !info.isManagedProfile()) { continue; } diff --git a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java index f53b68fd1af..3d8a822f3cb 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java +++ b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java @@ -82,7 +82,7 @@ public class StorageAsyncLoader } }); for (int i = 0, userCount = infos.size(); i < userCount; i++) { - UserInfo info = infos.get(i); + final UserInfo info = infos.get(i); result.put(info.id, getStorageResultForUser(info.id)); } return result; @@ -109,7 +109,7 @@ public class StorageAsyncLoader final long dataSize = stats.getDataBytes(); final long cacheQuota = mStatsManager.getCacheQuotaBytes(mUuid, app.uid); final long cacheBytes = stats.getCacheBytes(); - long blamedSize = dataSize; + long blamedSize = dataSize + stats.getCodeBytes(); // Technically, we could overages as freeable on the storage settings screen. // If the app is using more cache than its quota, we would accidentally subtract the // overage from the system size (because it shows up as unused) during our attribution. @@ -118,12 +118,11 @@ public class StorageAsyncLoader blamedSize = blamedSize - cacheBytes + cacheQuota; } - // This isn't quite right because it slams the first user by user id with the whole code - // size, but this ensures that we count all apps seen once. - boolean isAddCodeBytesForFirstUserId = false; - if (!mSeenPackages.contains(app.packageName)) { - isAddCodeBytesForFirstUserId = true; - blamedSize += stats.getCodeBytes(); + // Code bytes may share between different profiles. To know all the duplicate code size + // and we can get a reasonable system size in StorageItemPreferenceController. + if (mSeenPackages.contains(app.packageName)) { + result.duplicateCodeSize += stats.getCodeBytes(); + } else { mSeenPackages.add(app.packageName); } @@ -135,9 +134,7 @@ public class StorageAsyncLoader // TODO(b/170918505): Should revamp audio size calculation with the data // from media provider. result.musicAppsSize += blamedSize; - if (isAddCodeBytesForFirstUserId) { - result.musicAppsSize -= stats.getCodeBytes(); - } + result.musicAppsSize -= stats.getCodeBytes(); result.otherAppsSize += blamedSize; break; @@ -145,9 +142,7 @@ public class StorageAsyncLoader // TODO(b/170918505): Should revamp video size calculation with the data // from media provider. result.videoAppsSize += blamedSize; - if (isAddCodeBytesForFirstUserId) { - result.videoAppsSize -= stats.getCodeBytes(); - } + result.videoAppsSize -= stats.getCodeBytes(); result.otherAppsSize += blamedSize; break; @@ -155,9 +150,7 @@ public class StorageAsyncLoader // TODO(b/170918505): Should revamp image size calculation with the data // from media provider. result.photosAppsSize += blamedSize; - if (isAddCodeBytesForFirstUserId) { - result.photosAppsSize -= stats.getCodeBytes(); - } + result.photosAppsSize -= stats.getCodeBytes(); result.otherAppsSize += blamedSize; break; @@ -194,6 +187,7 @@ public class StorageAsyncLoader public long videoAppsSize; public long otherAppsSize; public long cacheSize; + public long duplicateCodeSize; public StorageStatsSource.ExternalStorageStats externalStats; } diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java index bc4611089d3..656f337ebda 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java @@ -101,6 +101,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle private static final int LAST_STORAGE_CATEGORY_PREFERENCE_ORDER = 200; private PackageManager mPackageManager; + private UserManager mUserManager; private final Fragment mFragment; private final MetricsFeatureProvider mMetricsFeatureProvider; private final StorageVolumeProvider mSvp; @@ -134,15 +135,17 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents"; - public StorageItemPreferenceController( - Context context, Fragment hostFragment, VolumeInfo volume, StorageVolumeProvider svp) { + public StorageItemPreferenceController(Context context, Fragment hostFragment, + VolumeInfo volume, StorageVolumeProvider svp, boolean isWorkProfile) { super(context); mPackageManager = context.getPackageManager(); + mUserManager = context.getSystemService(UserManager.class); mFragment = hostFragment; mVolume = volume; mSvp = svp; + mIsWorkProfile = isWorkProfile; mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); - mUserId = UserHandle.myUserId(); + mUserId = getCurrentUserId(); mImagesUri = Uri.parse(context.getResources() .getString(R.string.config_images_storage_category_uri)); @@ -154,14 +157,9 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle .getString(R.string.config_documents_and_other_storage_category_uri)); } - public StorageItemPreferenceController( - Context context, - Fragment hostFragment, - VolumeInfo volume, - StorageVolumeProvider svp, - boolean isWorkProfile) { - this(context, hostFragment, volume, svp); - mIsWorkProfile = isWorkProfile; + @VisibleForTesting + int getCurrentUserId() { + return Utils.getCurrentUserId(mUserManager, mIsWorkProfile); } @Override @@ -311,6 +309,9 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle * Sets the user id for which this preference controller is handling. */ public void setUserId(UserHandle userHandle) { + if (mIsWorkProfile && !mUserManager.isManagedProfile(userHandle.getIdentifier())) { + throw new IllegalArgumentException("Only accept work profile userHandle"); + } mUserId = userHandle.getIdentifier(); tintPreference(mPublicStoragePreference); @@ -359,21 +360,21 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle public void onLoadFinished(SparseArray result, int userId) { final StorageAsyncLoader.AppsStorageResult data = result.get(userId); - final StorageAsyncLoader.AppsStorageResult profileData = result.get( - Utils.getManagedProfileId(mContext.getSystemService(UserManager.class), userId)); - mImagesPreference.setStorageSize(getImagesSize(data, profileData), mTotalSize); - mVideosPreference.setStorageSize(getVideosSize(data, profileData), mTotalSize); - mAudiosPreference.setStorageSize(getAudiosSize(data, profileData), mTotalSize); - mAppsPreference.setStorageSize(getAppsSize(data, profileData), mTotalSize); - mGamesPreference.setStorageSize(getGamesSize(data, profileData), mTotalSize); - mDocumentsAndOtherPreference.setStorageSize(getDocumentsAndOtherSize(data, profileData), + mImagesPreference.setStorageSize(getImagesSize(data), mTotalSize); + mVideosPreference.setStorageSize(getVideosSize(data), mTotalSize); + mAudiosPreference.setStorageSize(getAudiosSize(data), mTotalSize); + mAppsPreference.setStorageSize(getAppsSize(data), mTotalSize); + mGamesPreference.setStorageSize(getGamesSize(data), mTotalSize); + mDocumentsAndOtherPreference.setStorageSize(getDocumentsAndOtherSize(data), mTotalSize); - mTrashPreference.setStorageSize(getTrashSize(data, profileData), mTotalSize); + mTrashPreference.setStorageSize(getTrashSize(data), mTotalSize); if (mSystemPreference != null) { // Everything else that hasn't already been attributed is tracked as // belonging to system. + // TODO(b/170918505): Should revamp system size calculation with the data + // from media provider. long attributedSize = 0; for (int i = 0; i < result.size(); i++) { final StorageAsyncLoader.AppsStorageResult otherData = result.valueAt(i); @@ -385,6 +386,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle + otherData.otherAppsSize; attributedSize += otherData.externalStats.totalBytes - otherData.externalStats.appBytes; + attributedSize -= otherData.duplicateCodeSize; } final long systemSize = Math.max(TrafficStats.GB_IN_BYTES, mUsedBytes - attributedSize); @@ -404,47 +406,28 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle private void launchPublicStorageIntent() { final Intent intent = mVolume.buildBrowseIntent(); - if (intent != null) { - mContext.startActivity(intent); + if (intent == null) { + return; } + mContext.startActivityAsUser(intent, new UserHandle(mUserId)); } private void launchActivityWithUri(Uri dataUri) { final Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(dataUri); - mContext.startActivity(intent); + mContext.startActivityAsUser(intent, new UserHandle(mUserId)); } - private long getImagesSize(StorageAsyncLoader.AppsStorageResult data, - StorageAsyncLoader.AppsStorageResult profileData) { - if (profileData != null) { - return data.photosAppsSize + data.externalStats.imageBytes - + data.externalStats.videoBytes - + profileData.photosAppsSize + profileData.externalStats.imageBytes - + profileData.externalStats.videoBytes; - } else { - return data.photosAppsSize + data.externalStats.imageBytes - + data.externalStats.videoBytes; - } + private long getImagesSize(StorageAsyncLoader.AppsStorageResult data) { + return data.photosAppsSize + data.externalStats.imageBytes + data.externalStats.videoBytes; } - private long getVideosSize(StorageAsyncLoader.AppsStorageResult data, - StorageAsyncLoader.AppsStorageResult profileData) { - if (profileData != null) { - return data.videoAppsSize + profileData.videoAppsSize; - } else { - return data.videoAppsSize; - } + private long getVideosSize(StorageAsyncLoader.AppsStorageResult data) { + return data.videoAppsSize; } - private long getAudiosSize(StorageAsyncLoader.AppsStorageResult data, - StorageAsyncLoader.AppsStorageResult profileData) { - if (profileData != null) { - return data.musicAppsSize + data.externalStats.audioBytes - + profileData.musicAppsSize + profileData.externalStats.audioBytes; - } else { - return data.musicAppsSize + data.externalStats.audioBytes; - } + private long getAudiosSize(StorageAsyncLoader.AppsStorageResult data) { + return data.musicAppsSize + data.externalStats.audioBytes; } private void launchAppsIntent() { @@ -463,13 +446,8 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle Utils.launchIntent(mFragment, intent); } - private long getAppsSize(StorageAsyncLoader.AppsStorageResult data, - StorageAsyncLoader.AppsStorageResult profileData) { - if (profileData != null) { - return data.otherAppsSize + profileData.otherAppsSize; - } else { - return data.otherAppsSize; - } + private long getAppsSize(StorageAsyncLoader.AppsStorageResult data) { + return data.otherAppsSize; } private void launchGamesIntent() { @@ -486,13 +464,8 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle Utils.launchIntent(mFragment, intent); } - private long getGamesSize(StorageAsyncLoader.AppsStorageResult data, - StorageAsyncLoader.AppsStorageResult profileData) { - if (profileData != null) { - return data.gamesSize + profileData.gamesSize; - } else { - return data.gamesSize; - } + private long getGamesSize(StorageAsyncLoader.AppsStorageResult data) { + return data.gamesSize; } private Bundle getWorkAnnotatedBundle(int additionalCapacity) { @@ -502,26 +475,12 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle return args; } - private long getDocumentsAndOtherSize(StorageAsyncLoader.AppsStorageResult data, - StorageAsyncLoader.AppsStorageResult profileData) { - if (profileData != null) { - return data.externalStats.totalBytes - - data.externalStats.audioBytes - - data.externalStats.videoBytes - - data.externalStats.imageBytes - - data.externalStats.appBytes - + profileData.externalStats.totalBytes - - profileData.externalStats.audioBytes - - profileData.externalStats.videoBytes - - profileData.externalStats.imageBytes - - profileData.externalStats.appBytes; - } else { - return data.externalStats.totalBytes - - data.externalStats.audioBytes - - data.externalStats.videoBytes - - data.externalStats.imageBytes - - data.externalStats.appBytes; - } + private long getDocumentsAndOtherSize(StorageAsyncLoader.AppsStorageResult data) { + return data.externalStats.totalBytes + - data.externalStats.audioBytes + - data.externalStats.videoBytes + - data.externalStats.imageBytes + - data.externalStats.appBytes; } private void launchTrashIntent() { @@ -530,12 +489,11 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle if (intent.resolveActivity(mPackageManager) == null) { EmptyTrashFragment.show(mFragment); } else { - mContext.startActivity(intent); + mContext.startActivityAsUser(intent, new UserHandle(mUserId)); } } - private long getTrashSize(StorageAsyncLoader.AppsStorageResult data, - StorageAsyncLoader.AppsStorageResult profileData) { + private long getTrashSize(StorageAsyncLoader.AppsStorageResult data) { // TODO(170918505): Implement it. return 0L; } diff --git a/src/com/android/settings/deviceinfo/storage/UserProfileController.java b/src/com/android/settings/deviceinfo/storage/UserProfileController.java deleted file mode 100644 index a2e19db235e..00000000000 --- a/src/com/android/settings/deviceinfo/storage/UserProfileController.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo.storage; - -import android.app.settings.SettingsEnums; -import android.content.Context; -import android.content.pm.UserInfo; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.storage.VolumeInfo; -import android.util.SparseArray; - -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.internal.util.Preconditions; -import com.android.settings.Utils; -import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.SubSettingLauncher; -import com.android.settings.deviceinfo.StorageItemPreference; -import com.android.settings.deviceinfo.StorageProfileFragment; -import com.android.settingslib.core.AbstractPreferenceController; - -/** - * Defines a {@link AbstractPreferenceController} which handles a single profile of the primary - * user. - */ -public class UserProfileController extends AbstractPreferenceController implements - PreferenceControllerMixin, StorageAsyncLoader.ResultHandler, - UserIconLoader.UserIconHandler { - private static final String PREFERENCE_KEY_BASE = "pref_profile_"; - private StorageItemPreference mStoragePreference; - private UserInfo mUser; - private long mTotalSizeBytes; - private final int mPreferenceOrder; - - public UserProfileController(Context context, UserInfo info, int preferenceOrder) { - super(context); - mUser = Preconditions.checkNotNull(info); - mPreferenceOrder = preferenceOrder; - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public String getPreferenceKey() { - return PREFERENCE_KEY_BASE + mUser.id; - } - - @Override - public void displayPreference(PreferenceScreen screen) { - mStoragePreference = new StorageItemPreference(screen.getContext()); - mStoragePreference.setOrder(mPreferenceOrder); - mStoragePreference.setKey(PREFERENCE_KEY_BASE + mUser.id); - mStoragePreference.setTitle(mUser.name); - screen.addPreference(mStoragePreference); - } - - @Override - public boolean handlePreferenceTreeClick(Preference preference) { - if (preference != null && mStoragePreference == preference) { - final Bundle args = new Bundle(); - args.putInt(StorageProfileFragment.USER_ID_EXTRA, mUser.id); - args.putString(VolumeInfo.EXTRA_VOLUME_ID, VolumeInfo.ID_PRIVATE_INTERNAL); - - new SubSettingLauncher(mContext) - .setDestination(StorageProfileFragment.class.getName()) - .setArguments(args) - .setTitleText(mUser.name) - .setSourceMetricsCategory(SettingsEnums.DEVICEINFO_STORAGE) - .launch(); - return true; - } - - return false; - } - - @Override - public void handleResult(SparseArray stats) { - Preconditions.checkNotNull(stats); - - int userId = mUser.id; - StorageAsyncLoader.AppsStorageResult result = stats.get(userId); - if (result != null) { - setSize(result.externalStats.totalBytes - + result.otherAppsSize - + result.videoAppsSize - + result.musicAppsSize - + result.gamesSize, - mTotalSizeBytes); - } - } - - /** - * Sets the size for the preference using a byte count. - */ - public void setSize(long size, long totalSize) { - if (mStoragePreference != null) { - mStoragePreference.setStorageSize(size, totalSize); - } - } - - public void setTotalSize(long totalSize) { - mTotalSizeBytes = totalSize; - } - - @Override - public void handleUserIcons(SparseArray fetchedIcons) { - Drawable userIcon = fetchedIcons.get(mUser.id); - if (userIcon != null) { - mStoragePreference.setIcon(applyTint(mContext, userIcon)); - } - } - - private static Drawable applyTint(Context context, Drawable icon) { - icon = icon.mutate(); - icon.setTintList(Utils.getColorAttr(context, android.R.attr.colorControlNormal)); - return icon; - } - -} diff --git a/tests/robotests/assets/exempt_not_implementing_index_provider b/tests/robotests/assets/exempt_not_implementing_index_provider index 97fe120d884..7815a486dac 100644 --- a/tests/robotests/assets/exempt_not_implementing_index_provider +++ b/tests/robotests/assets/exempt_not_implementing_index_provider @@ -36,9 +36,7 @@ com.android.settings.datausage.DataUsageList com.android.settings.datausage.DataUsageSummary com.android.settings.datetime.timezone.TimeZoneSettings com.android.settings.development.compat.PlatformCompatDashboard -com.android.settings.deviceinfo.PrivateVolumeSettings com.android.settings.deviceinfo.PublicVolumeSettings -com.android.settings.deviceinfo.StorageProfileFragment com.android.settings.deviceinfo.legal.ModuleLicensesDashboard com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionCamera com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionLocation diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java index 824f6b4a946..ec0f4d06b82 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java @@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -112,7 +113,8 @@ public class SecondaryUserControllerTest { when(mUserManager.getPrimaryUser()).thenReturn(mPrimaryUser); when(mUserManager.getUsers()).thenReturn(userInfos); final List controllers = - SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager); + SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager, + false /* isWorkProfileOnly */); assertThat(controllers).hasSize(1); // We should have the NoSecondaryUserController. @@ -122,15 +124,17 @@ public class SecondaryUserControllerTest { @Test public void getSecondaryUserControllers_notWorkProfile_addSecondaryUserController() { final ArrayList userInfos = new ArrayList<>(); - final UserInfo secondaryUser = new UserInfo(); + 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); + SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager, + false /* isWorkProfileOnly */); assertThat(controllers).hasSize(1); assertThat(controllers.get(0) instanceof SecondaryUserController).isTrue(); @@ -139,20 +143,41 @@ public class SecondaryUserControllerTest { @Test public void getSecondaryUserControllers_workProfile_addNoSecondaryUserController() { final ArrayList userInfos = new ArrayList<>(); - final UserInfo secondaryUser = new UserInfo(); + final UserInfo secondaryUser = spy(new UserInfo()); secondaryUser.id = 10; secondaryUser.profileGroupId = 101010; // this just has to be something not 0 + when(secondaryUser.isManagedProfile()).thenReturn(true); userInfos.add(mPrimaryUser); userInfos.add(secondaryUser); when(mUserManager.getPrimaryUser()).thenReturn(mPrimaryUser); when(mUserManager.getUsers()).thenReturn(userInfos); final List controllers = - SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager); + SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager, + false /* isWorkProfileOnly */); assertThat(controllers).hasSize(1); assertThat(controllers.get(0) instanceof SecondaryUserController).isTrue(); } + @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() { final ArrayList userInfos = new ArrayList<>(); @@ -164,7 +189,8 @@ public class SecondaryUserControllerTest { when(mUserManager.getUsers()).thenReturn(userInfos); final List controllers = - SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager); + SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager, + false /* isWorkProfileOnly */); assertThat(controllers).hasSize(1); assertThat(controllers.get(0) instanceof SecondaryUserController).isFalse(); @@ -206,7 +232,8 @@ public class SecondaryUserControllerTest { when(mUserManager.getPrimaryUser()).thenReturn(mPrimaryUser); when(mUserManager.getUsers()).thenReturn(userInfos); final List controllers = - SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager); + SecondaryUserController.getSecondaryUserControllers(mContext, mUserManager, + false /* isWorkProfileOnly */); assertThat(controllers).hasSize(1); // We should have the NoSecondaryUserController. diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java index 188274160c3..3fd12185945 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java @@ -94,7 +94,8 @@ public class StorageItemPreferenceControllerTest { mVolume = spy(new VolumeInfo("id", 0, null, "id")); // Note: null is passed as the Lifecycle because we are handling it outside of the normal // Settings fragment lifecycle for test purposes. - mController = new StorageItemPreferenceController(mContext, mFragment, mVolume, mSvp); + mController = new StorageItemPreferenceController(mContext, mFragment, mVolume, mSvp, + false /* isWorkProfile */); mPreference = new StorageItemPreference(mContext); // Inflate the preference and the widget. @@ -165,7 +166,7 @@ public class StorageItemPreferenceControllerTest { mController.handlePreferenceTreeClick(mPreference); final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Intent.class); - verify(mContext).startActivity(argumentCaptor.capture()); + verify(mContext).startActivityAsUser(argumentCaptor.capture(), nullable(UserHandle.class)); final Intent intent = argumentCaptor.getValue(); assertThat(intent.getAction()).isEqualTo(fakeBrowseAction); @@ -176,11 +177,12 @@ public class StorageItemPreferenceControllerTest { mPreference.setKey(StorageItemPreferenceController.IMAGES_KEY); final Context mockContext = getMockContext(); mController = new StorageItemPreferenceController(mockContext, mFragment, mVolume, - mSvp); + mSvp, false /* isWorkProfile */); mController.handlePreferenceTreeClick(mPreference); final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Intent.class); - verify(mockContext).startActivity(argumentCaptor.capture()); + verify(mockContext).startActivityAsUser(argumentCaptor.capture(), + nullable(UserHandle.class)); final Intent intent = argumentCaptor.getValue(); assertThat(intent.getAction()).isEqualTo(Intent.ACTION_VIEW); @@ -192,11 +194,12 @@ public class StorageItemPreferenceControllerTest { mPreference.setKey(StorageItemPreferenceController.AUDIOS_KEY); final Context mockContext = getMockContext(); mController = new StorageItemPreferenceController(mockContext, mFragment, mVolume, - mSvp); + mSvp, false /* isWorkProfile */); mController.handlePreferenceTreeClick(mPreference); final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Intent.class); - verify(mockContext).startActivity(argumentCaptor.capture()); + verify(mockContext).startActivityAsUser(argumentCaptor.capture(), + nullable(UserHandle.class)); final Intent intent = argumentCaptor.getValue(); assertThat(intent.getAction()).isEqualTo(Intent.ACTION_VIEW); @@ -240,7 +243,8 @@ public class StorageItemPreferenceControllerTest { @Test public void launchAppsIntent_forWork_settingsIntent() { - mController = new StorageItemPreferenceController(mContext, mFragment, mVolume, mSvp, true); + mController = new FakeStorageItemPreferenceController(mContext, mFragment, mVolume, mSvp, + true /* isWorkProfile */); mPreference.setKey(StorageItemPreferenceController.APPS_KEY); mController.handlePreferenceTreeClick(mPreference); @@ -270,11 +274,12 @@ public class StorageItemPreferenceControllerTest { mPreference.setKey(StorageItemPreferenceController.DOCUMENTS_AND_OTHER_KEY); final Context mockContext = getMockContext(); mController = new StorageItemPreferenceController(mockContext, mFragment, mVolume, - mSvp); + mSvp, false /* isWorkProfile */); mController.handlePreferenceTreeClick(mPreference); final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Intent.class); - verify(mockContext).startActivity(argumentCaptor.capture()); + verify(mockContext).startActivityAsUser(argumentCaptor.capture(), + nullable(UserHandle.class)); Intent intent = argumentCaptor.getValue(); assertThat(intent.getAction()).isEqualTo(Intent.ACTION_VIEW); @@ -304,11 +309,12 @@ public class StorageItemPreferenceControllerTest { mPreference.setKey(StorageItemPreferenceController.VIDEOS_KEY); final Context mockContext = getMockContext(); mController = new StorageItemPreferenceController(mockContext, mFragment, mVolume, - mSvp); + mSvp, false /* isWorkProfile */); mController.handlePreferenceTreeClick(mPreference); final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Intent.class); - verify(mockContext).startActivity(argumentCaptor.capture()); + verify(mockContext).startActivityAsUser(argumentCaptor.capture(), + nullable(UserHandle.class)); Intent intent = argumentCaptor.getValue(); assertThat(intent.getAction()).isEqualTo(Intent.ACTION_VIEW); @@ -468,4 +474,20 @@ public class StorageItemPreferenceControllerTest { when(resources.getString(anyInt())).thenReturn(""); return context; } + + private static class FakeStorageItemPreferenceController + extends StorageItemPreferenceController { + + private static final int CURRENT_USER_ID = 10; + + FakeStorageItemPreferenceController(Context context, Fragment hostFragment, + VolumeInfo volume, StorageVolumeProvider svp, boolean isWorkProfile) { + super(context, hostFragment, volume, svp, isWorkProfile); + } + + @Override + int getCurrentUserId() { + return CURRENT_USER_ID; + } + } } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java deleted file mode 100644 index 9e2b45d05a1..00000000000 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo.storage; - -import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.pm.UserInfo; -import android.graphics.drawable.Drawable; -import android.util.SparseArray; - -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.SettingsActivity; -import com.android.settings.SubSettings; -import com.android.settings.deviceinfo.StorageProfileFragment; -import com.android.settingslib.applications.StorageStatsSource; -import com.android.settingslib.drawable.UserIconDrawable; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; - -@RunWith(RobolectricTestRunner.class) -public class UserProfileControllerTest { - - private static final String TEST_NAME = "Fred"; - - @Mock - private PreferenceScreen mScreen; - - private Context mContext; - private UserProfileController mController; - private UserInfo mPrimaryProfile; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mContext = spy(Robolectric.setupActivity(Activity.class)); - mPrimaryProfile = new UserInfo(); - mController = new UserProfileController(mContext, mPrimaryProfile, 0); - when(mScreen.getContext()).thenReturn(mContext); - mPrimaryProfile.name = TEST_NAME; - mPrimaryProfile.id = 10; - mController.displayPreference(mScreen); - } - - @Test - public void controllerAddsPrimaryProfilePreference() { - final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Preference.class); - verify(mScreen).addPreference(argumentCaptor.capture()); - final Preference preference = argumentCaptor.getValue(); - - assertThat(preference.getTitle()).isEqualTo(TEST_NAME); - assertThat(preference.getKey()).isEqualTo("pref_profile_10"); - } - - @Test - public void tappingProfilePreferenceSendsToStorageProfileFragment() { - - final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Preference.class); - verify(mScreen).addPreference(argumentCaptor.capture()); - final Preference preference = argumentCaptor.getValue(); - assertThat(mController.handlePreferenceTreeClick(preference)).isTrue(); - final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); - verify(mContext).startActivity(intentCaptor.capture()); - - final Intent intent = intentCaptor.getValue(); - assertThat(intent.getComponent().getClassName()).isEqualTo(SubSettings.class.getName()); - assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)) - .isEqualTo(StorageProfileFragment.class.getName()); - } - - @Test - public void acceptingResultUpdatesPreferenceSize() { - final SparseArray result = new SparseArray<>(); - final StorageAsyncLoader.AppsStorageResult userResult = - new StorageAsyncLoader.AppsStorageResult(); - userResult.externalStats = - new StorageStatsSource.ExternalStorageStats( - 99 * MEGABYTE_IN_BYTES, - 33 * MEGABYTE_IN_BYTES, - 33 * MEGABYTE_IN_BYTES, - 33 * MEGABYTE_IN_BYTES, 0); - result.put(10, userResult); - - mController.handleResult(result); - final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Preference.class); - verify(mScreen).addPreference(argumentCaptor.capture()); - final Preference preference = argumentCaptor.getValue(); - - assertThat(preference.getSummary()).isEqualTo("0.10 GB"); - } - - @Test - public void iconCallbackChangesPreferenceIcon() { - final SparseArray icons = new SparseArray<>(); - final UserIconDrawable drawable = mock(UserIconDrawable.class); - when(drawable.mutate()).thenReturn(drawable); - icons.put(mPrimaryProfile.id, drawable); - - mController.handleUserIcons(icons); - - final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Preference.class); - verify(mScreen).addPreference(argumentCaptor.capture()); - final Preference preference = argumentCaptor.getValue(); - assertThat(preference.getIcon()).isEqualTo(drawable); - } -} diff --git a/tests/unit/src/com/android/settings/deviceinfo/StorageProfileFragmentTest.java b/tests/unit/src/com/android/settings/deviceinfo/StorageProfileFragmentTest.java deleted file mode 100644 index ca124fd28ab..00000000000 --- a/tests/unit/src/com/android/settings/deviceinfo/StorageProfileFragmentTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.settings.deviceinfo; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import android.os.Looper; -import android.util.SparseArray; - -import androidx.test.annotation.UiThreadTest; -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import com.android.settings.deviceinfo.storage.StorageAsyncLoader; -import com.android.settings.deviceinfo.storage.StorageItemPreferenceController; -import com.android.settingslib.applications.StorageStatsSource; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidJUnit4.class) -public class StorageProfileFragmentTest { - - @Captor - private ArgumentCaptor> mCaptor; - - @Test - @UiThreadTest - public void verifyAppSizesAreNotZeroedOut() { - if (Looper.myLooper() == null) { - Looper.prepare(); - } - StorageItemPreferenceController controller = mock(StorageItemPreferenceController.class); - StorageProfileFragment fragment = new StorageProfileFragment(); - StorageAsyncLoader.AppsStorageResult result = new StorageAsyncLoader.AppsStorageResult(); - result.musicAppsSize = 100; - result.otherAppsSize = 200; - result.gamesSize = 300; - result.videoAppsSize = 400; - result.externalStats = new StorageStatsSource.ExternalStorageStats(6, 1, 2, 3, 0); - SparseArray resultsArray = new SparseArray<>(); - resultsArray.put(0, result); - fragment.setPreferenceController(controller); - - fragment.onLoadFinished(null, resultsArray); - - MockitoAnnotations.initMocks(this); - verify(controller).onLoadFinished(mCaptor.capture(), anyInt()); - - StorageAsyncLoader.AppsStorageResult extractedResult = mCaptor.getValue().get(0); - assertThat(extractedResult.musicAppsSize).isEqualTo(100); - assertThat(extractedResult.videoAppsSize).isEqualTo(400); - assertThat(extractedResult.otherAppsSize).isEqualTo(200); - assertThat(extractedResult.gamesSize).isEqualTo(300); - assertThat(extractedResult.externalStats.audioBytes).isEqualTo(1); - assertThat(extractedResult.externalStats.videoBytes).isEqualTo(2); - assertThat(extractedResult.externalStats.imageBytes).isEqualTo(3); - assertThat(extractedResult.externalStats.totalBytes).isEqualTo(6); - } -}