Storage category UX changes in Storage Settings

- Change category types.
- Use Intent.ACTION_VIEW to show content of each category.
- Sort order of each category by storage size.

Bug: 170918505
Test: make RunSettingsRoboTests ROBOTEST_FILTER=StorageItemPreferenceTest
      make RunSettingsRoboTests ROBOTEST_FILTER=StorageItemPreferenceControllerTest
      manual
      Click each category in Storage Settings.
Change-Id: Ib7beb1779a0fcbfd7b8ec52446707b105fcebff5
This commit is contained in:
Arc Wang
2021-03-23 15:20:56 +08:00
parent 11ad3be029
commit 2b00ecdda9
8 changed files with 531 additions and 434 deletions

View File

@@ -0,0 +1,26 @@
<!--
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.
-->
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M15,3V4H20V6H19V19C19,20.1 18.1,21 17,21H7C5.9,21 5,20.1 5,19V6H4V4H9V3H15ZM7,19H17V6H7V19ZM9,8H11V17H9V8ZM15,8H13V17H15V8Z"
android:fillColor="#5F6368"
android:fillType="evenOdd"/>
</vector>

View File

@@ -509,4 +509,17 @@
<!-- Cell broacast receiver package name --> <!-- Cell broacast receiver package name -->
<string name="config_cell_broadcast_receiver_package" translatable="false">com.android.cellbroadcastreceiver.module</string> <string name="config_cell_broadcast_receiver_package" translatable="false">com.android.cellbroadcastreceiver.module</string>
<!-- TODO(b/174964885): These media Uri are not defined in framework yet. Replace with framework defined variables once it's available. -->
<!-- Media Uri to view images storage category. -->
<string name="config_images_storage_category_uri" translatable="false">content://com.android.providers.media.documents/root/images_root</string>
<!-- Media Uri to view videos storage category. -->
<string name="config_videos_storage_category_uri" translatable="false">content://com.android.providers.media.documents/root/videos_root</string>
<!-- Media Uri to view audios storage category. -->
<string name="config_audios_storage_category_uri" translatable="false">content://com.android.providers.media.documents/root/audio_root</string>
<!-- Media Uri to view documents & other storage category. -->
<string name="config_documents_and_other_storage_category_uri" translatable="false">content://com.android.providers.media.documents/root/documents_root</string>
</resources> </resources>

View File

@@ -21,68 +21,64 @@
android:orderingFromXml="false"> android:orderingFromXml="false">
<com.android.settingslib.widget.SettingsSpinnerPreference <com.android.settingslib.widget.SettingsSpinnerPreference
android:key="storage_spinner" android:key="storage_spinner"
android:order="-2" android:order="1"
settings:searchable="false" settings:searchable="false"
settings:controller="com.android.settings.deviceinfo.storage.StorageSelectionPreferenceController"/> settings:controller="com.android.settings.deviceinfo.storage.StorageSelectionPreferenceController"/>
<com.android.settingslib.widget.UsageProgressBarPreference <com.android.settingslib.widget.UsageProgressBarPreference
android:key="storage_summary" android:key="storage_summary"
android:order="-1" android:order="2"
settings:searchable="false" settings:searchable="false"
settings:controller="com.android.settings.deviceinfo.storage.StorageUsageProgressBarPreferenceController"/> settings:controller="com.android.settings.deviceinfo.storage.StorageUsageProgressBarPreferenceController"
<Preference settings:allowDividerBelow="true"/>
android:key="free_up_space"
android:order="0"
android:title="@string/storage_free_up_space_title"
android:summary="@string/storage_free_up_space_summary"
settings:allowDividerAbove="true"/>
<com.android.settings.widget.PrimarySwitchPreference <com.android.settings.widget.PrimarySwitchPreference
android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings" android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings"
android:key="toggle_asm" android:key="toggle_asm"
android:title="@string/automatic_storage_manager_preference_title" android:title="@string/automatic_storage_manager_preference_title"
android:icon="@drawable/ic_storage" android:icon="@drawable/ic_storage"
android:order="1" android:order="3"
settings:allowDividerAbove="true" settings:allowDividerAbove="true"
settings:allowDividerBelow="true" settings:controller="com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController"/>
settings:controller="com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController" /> <Preference
android:key="free_up_space"
android:order="4"
android:title="@string/storage_free_up_space_title"
android:summary="@string/storage_free_up_space_summary"/>
<!-- Preference order 100~200 are 'ONLY' for storage category preferences below. -->
<com.android.settings.deviceinfo.StorageItemPreference <com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_photos_videos" android:key="pref_images"
android:title="@string/storage_photos_videos" android:title="@string/storage_images"
android:icon="@drawable/ic_photo_library" android:icon="@drawable/ic_photo_library"/>
settings:allowDividerAbove="true"
android:order="2" />
<com.android.settings.deviceinfo.StorageItemPreference <com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_music_audio" android:key="pref_videos"
android:title="@string/storage_music_audio" android:title="@string/storage_videos"
android:icon="@drawable/ic_media_stream" android:icon="@drawable/ic_local_movies"/>
android:order="3" /> <com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_audios"
android:title="@string/storage_audios"
android:icon="@drawable/ic_media_stream"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_apps"
android:title="@string/storage_apps"
android:icon="@drawable/ic_storage_apps"/>
<com.android.settings.deviceinfo.StorageItemPreference <com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_games" android:key="pref_games"
android:title="@string/storage_games" android:title="@string/storage_games"
android:icon="@drawable/ic_videogame_vd_theme_24" android:icon="@drawable/ic_videogame_vd_theme_24"/>
android:order="4" />
<com.android.settings.deviceinfo.StorageItemPreference <com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_movies" android:key="pref_documents_and_other"
android:title="@string/storage_movies_tv" android:title="@string/storage_documents_and_other"
android:icon="@drawable/ic_local_movies" android:icon="@drawable/ic_folder_vd_theme_24"/>
android:order="5" />
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_other_apps"
android:title="@string/storage_other_apps"
android:icon="@drawable/ic_storage_apps"
android:order="6" />
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_files"
android:title="@string/storage_files"
android:icon="@drawable/ic_folder_vd_theme_24"
android:order="7"
settings:keywords="@string/keywords_storage_files"/>
<com.android.settings.deviceinfo.StorageItemPreference <com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_system" android:key="pref_system"
android:title="@string/storage_detail_system" android:title="@string/storage_system"
android:icon="@drawable/ic_system_update" android:icon="@drawable/ic_system_update"/>
android:order="100" /> <com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_trash"
android:title="@string/storage_trash"
android:icon="@drawable/ic_trash_can"/>
<!-- Preference order 100~200 are 'ONLY' for storage category preferences above. -->
<PreferenceCategory <PreferenceCategory
android:key="pref_secondary_users" android:key="pref_secondary_users"
android:title="@string/storage_other_users" android:title="@string/storage_other_users"
android:order="200" /> android:order="201" />
</PreferenceScreen> </PreferenceScreen>

View File

@@ -35,6 +35,7 @@ public class StorageItemPreference extends Preference {
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
private static final int PROGRESS_MAX = 100; private static final int PROGRESS_MAX = 100;
private int mProgressPercent = UNINITIALIZED; private int mProgressPercent = UNINITIALIZED;
private long mStorageSize;
public StorageItemPreference(Context context) { public StorageItemPreference(Context context) {
this(context, null); this(context, null);
@@ -47,6 +48,7 @@ public class StorageItemPreference extends Preference {
} }
public void setStorageSize(long size, long total) { public void setStorageSize(long size, long total) {
mStorageSize = size;
setSummary( setSummary(
FileSizeFormatter.formatFileSize( FileSizeFormatter.formatFileSize(
getContext(), getContext(),
@@ -61,6 +63,10 @@ public class StorageItemPreference extends Preference {
updateProgressBar(); updateProgressBar();
} }
public long getStorageSize() {
return mStorageSize;
}
protected void updateProgressBar() { protected void updateProgressBar() {
if (mProgressBar == null || mProgressPercent == UNINITIALIZED) if (mProgressBar == null || mProgressPercent == UNINITIALIZED)
return; return;

View File

@@ -0,0 +1,57 @@
/*
* 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.deviceinfo.storage;
import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
/**
* Dialog asks if users want to empty trash files.
*/
public class EmptyTrashFragment extends InstrumentedDialogFragment {
private static final String TAG_EMPTY_TRASH = "empty_trash";
/** Shows the empty trash dialog. */
public static void show(Fragment parent) {
final EmptyTrashFragment dialog = new EmptyTrashFragment();
dialog.setTargetFragment(parent, 0 /* requestCode */);
dialog.show(parent.getFragmentManager(), TAG_EMPTY_TRASH);
}
@Override
public int getMetricsCategory() {
return SettingsEnums.DIALOG_EMPTY_TRASH;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
return builder.setTitle(R.string.storage_trash_dialog_title)
.setMessage(R.string.storage_trash_dialog_ask_message)
.setPositiveButton(R.string.storage_trash_dialog_confirm, (dialog, which) -> {
// TODO(170918505): Implement the logic in worker thread.
}).setNegativeButton(android.R.string.cancel, null)
.create();
}
}

View File

@@ -19,12 +19,13 @@ package com.android.settings.deviceinfo.storage;
import static com.android.settings.dashboard.profileselector.ProfileSelectFragment.PERSONAL_TAB; import static com.android.settings.dashboard.profileselector.ProfileSelectFragment.PERSONAL_TAB;
import static com.android.settings.dashboard.profileselector.ProfileSelectFragment.WORK_TAB; import static com.android.settings.dashboard.profileselector.ProfileSelectFragment.WORK_TAB;
import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.TrafficStats; import android.net.TrafficStats;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
@@ -53,6 +54,8 @@ import com.android.settingslib.deviceinfo.StorageMeasurement;
import com.android.settingslib.deviceinfo.StorageVolumeProvider; import com.android.settingslib.deviceinfo.StorageVolumeProvider;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -67,20 +70,31 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
private static final String SYSTEM_FRAGMENT_TAG = "SystemInfo"; private static final String SYSTEM_FRAGMENT_TAG = "SystemInfo";
@VisibleForTesting @VisibleForTesting
static final String PHOTO_KEY = "pref_photos_videos"; static final String IMAGES_KEY = "pref_images";
@VisibleForTesting @VisibleForTesting
static final String AUDIO_KEY = "pref_music_audio"; static final String VIDEOS_KEY = "pref_videos";
@VisibleForTesting @VisibleForTesting
static final String GAME_KEY = "pref_games"; static final String AUDIOS_KEY = "pref_audios";
@VisibleForTesting @VisibleForTesting
static final String MOVIES_KEY = "pref_movies"; static final String APPS_KEY = "pref_apps";
@VisibleForTesting @VisibleForTesting
static final String OTHER_APPS_KEY = "pref_other_apps"; static final String GAMES_KEY = "pref_games";
@VisibleForTesting
static final String DOCUMENTS_AND_OTHER_KEY = "pref_documents_and_other";
@VisibleForTesting @VisibleForTesting
static final String SYSTEM_KEY = "pref_system"; static final String SYSTEM_KEY = "pref_system";
@VisibleForTesting @VisibleForTesting
static final String FILES_KEY = "pref_files"; static final String TRASH_KEY = "pref_trash";
private final Uri mImagesUri;
private final Uri mVideosUri;
private final Uri mAudiosUri;
private final Uri mDocumentsAndOtherUri;
// This value should align with the design of storage_dashboard_fragment.xml
private static final int LAST_STORAGE_CATEGORY_PREFERENCE_ORDER = 200;
private PackageManager mPackageManager;
private final Fragment mFragment; private final Fragment mFragment;
private final MetricsFeatureProvider mMetricsFeatureProvider; private final MetricsFeatureProvider mMetricsFeatureProvider;
private final StorageVolumeProvider mSvp; private final StorageVolumeProvider mSvp;
@@ -89,14 +103,25 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
private long mUsedBytes; private long mUsedBytes;
private long mTotalSize; private long mTotalSize;
private List<StorageItemPreference> mStorageItemPreferences;
private PreferenceScreen mScreen; private PreferenceScreen mScreen;
private StorageItemPreference mPhotoPreference; @VisibleForTesting
private StorageItemPreference mAudioPreference; StorageItemPreference mImagesPreference;
private StorageItemPreference mGamePreference; @VisibleForTesting
private StorageItemPreference mMoviesPreference; StorageItemPreference mVideosPreference;
private StorageItemPreference mAppPreference; @VisibleForTesting
private StorageItemPreference mFilePreference; StorageItemPreference mAudiosPreference;
private StorageItemPreference mSystemPreference; @VisibleForTesting
StorageItemPreference mAppsPreference;
@VisibleForTesting
StorageItemPreference mGamesPreference;
@VisibleForTesting
StorageItemPreference mDocumentsAndOtherPreference;
@VisibleForTesting
StorageItemPreference mSystemPreference;
@VisibleForTesting
StorageItemPreference mTrashPreference;
private boolean mIsWorkProfile; private boolean mIsWorkProfile;
private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents"; private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents";
@@ -104,11 +129,21 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
public StorageItemPreferenceController( public StorageItemPreferenceController(
Context context, Fragment hostFragment, VolumeInfo volume, StorageVolumeProvider svp) { Context context, Fragment hostFragment, VolumeInfo volume, StorageVolumeProvider svp) {
super(context); super(context);
mPackageManager = context.getPackageManager();
mFragment = hostFragment; mFragment = hostFragment;
mVolume = volume; mVolume = volume;
mSvp = svp; mSvp = svp;
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
mUserId = UserHandle.myUserId(); mUserId = UserHandle.myUserId();
mImagesUri = Uri.parse(context.getResources()
.getString(R.string.config_images_storage_category_uri));
mVideosUri = Uri.parse(context.getResources()
.getString(R.string.config_videos_storage_category_uri));
mAudiosUri = Uri.parse(context.getResources()
.getString(R.string.config_audios_storage_category_uri));
mDocumentsAndOtherUri = Uri.parse(context.getResources()
.getString(R.string.config_documents_and_other_storage_category_uri));
} }
public StorageItemPreferenceController( public StorageItemPreferenceController(
@@ -128,57 +163,39 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
@Override @Override
public boolean handlePreferenceTreeClick(Preference preference) { public boolean handlePreferenceTreeClick(Preference preference) {
if (preference == null) {
return false;
}
Intent intent = null;
if (preference.getKey() == null) { if (preference.getKey() == null) {
return false; return false;
} }
switch (preference.getKey()) { switch (preference.getKey()) {
case PHOTO_KEY: case IMAGES_KEY:
intent = getPhotosIntent(); launchImagesIntent();
break; return true;
case AUDIO_KEY: case VIDEOS_KEY:
intent = getAudioIntent(); launchVideosIntent();
break; return true;
case GAME_KEY: case AUDIOS_KEY:
intent = getGamesIntent(); launchAudiosIntent();
break; return true;
case MOVIES_KEY: case APPS_KEY:
intent = getMoviesIntent(); launchAppsIntent();
break; return true;
case OTHER_APPS_KEY: case GAMES_KEY:
// Because we are likely constructed with a null volume, this is theoretically launchGamesIntent();
// possible. return true;
if (mVolume == null) { case DOCUMENTS_AND_OTHER_KEY:
break; launchDocumentsAndOtherIntent();
} return true;
intent = getAppsIntent();
break;
case FILES_KEY:
if (mVolume == null) {
break;
}
intent = getFilesIntent();
FeatureFactory.getFactory(mContext).getMetricsFeatureProvider().action(
mContext, SettingsEnums.STORAGE_FILES);
break;
case SYSTEM_KEY: case SYSTEM_KEY:
final SystemInfoFragment dialog = new SystemInfoFragment(); final SystemInfoFragment dialog = new SystemInfoFragment();
dialog.setTargetFragment(mFragment, 0); dialog.setTargetFragment(mFragment, 0);
dialog.show(mFragment.getFragmentManager(), SYSTEM_FRAGMENT_TAG); dialog.show(mFragment.getFragmentManager(), SYSTEM_FRAGMENT_TAG);
return true; return true;
case TRASH_KEY:
launchTrashIntent();
return true;
default:
// Do nothing.
} }
if (intent != null) {
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
Utils.launchIntent(mFragment, intent);
return true;
}
return super.handlePreferenceTreeClick(preference); return super.handlePreferenceTreeClick(preference);
} }
@@ -192,57 +209,97 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
*/ */
public void setVolume(VolumeInfo volume) { public void setVolume(VolumeInfo volume) {
mVolume = volume; mVolume = volume;
updateCategoryPreferencesVisibility();
}
private void updateCategoryPreferencesVisibility() {
// Stats data is only available on private volumes.
final boolean isValidVolume = mVolume != null
&& mVolume.getType() == VolumeInfo.TYPE_PRIVATE
&& (mVolume.getState() == VolumeInfo.STATE_MOUNTED
|| mVolume.getState() == VolumeInfo.STATE_MOUNTED_READ_ONLY);
mPhotoPreference.setVisible(isValidVolume);
mAudioPreference.setVisible(isValidVolume);
mGamePreference.setVisible(isValidVolume);
mMoviesPreference.setVisible(isValidVolume);
mAppPreference.setVisible(isValidVolume);
mFilePreference.setVisible(isValidVolume);
mSystemPreference.setVisible(isValidVolume);
final boolean isValidVolume = isValidVolume();
setCategoryPreferencesVisibility(isValidVolume);
if (isValidVolume) { if (isValidVolume) {
setFilesPreferenceVisibility(); updateCategoryPreferencesOrder();
} }
} }
private void setFilesPreferenceVisibility() { // Stats data is only available on private volumes.
if (mScreen != null) { private boolean isValidVolume() {
return mVolume != null
&& mVolume.getType() == VolumeInfo.TYPE_PRIVATE
&& (mVolume.getState() == VolumeInfo.STATE_MOUNTED
|| mVolume.getState() == VolumeInfo.STATE_MOUNTED_READ_ONLY);
}
private void setCategoryPreferencesVisibility(boolean visible) {
if (mScreen == null) {
return;
}
mImagesPreference.setVisible(visible);
mVideosPreference.setVisible(visible);
mAudiosPreference.setVisible(visible);
mAppsPreference.setVisible(visible);
mGamesPreference.setVisible(visible);
mDocumentsAndOtherPreference.setVisible(visible);
mSystemPreference.setVisible(visible);
// TODO(b/170918505): Shows trash category after trash category feature complete.
mTrashPreference.setVisible(false);
if (visible) {
final VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume); final VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume);
// If we don't have a shared volume for our internal storage (or the shared volume isn't // If we don't have a shared volume for our internal storage (or the shared volume isn't
// mounted as readable for whatever reason), we should hide the File preference. // mounted as readable for whatever reason), we should hide the File preference.
final boolean hideFilePreference = if (sharedVolume == null || !sharedVolume.isMountedReadable()) {
(sharedVolume == null) || !sharedVolume.isMountedReadable(); mDocumentsAndOtherPreference.setVisible(false);
if (hideFilePreference) {
mScreen.removePreference(mFilePreference);
} else {
mScreen.addPreference(mFilePreference);
} }
} }
} }
private void updateCategoryPreferencesOrder() {
if (mScreen == null) {
return;
}
if (mStorageItemPreferences == null) {
mStorageItemPreferences = new ArrayList<>();
mStorageItemPreferences.add(mImagesPreference);
mStorageItemPreferences.add(mVideosPreference);
mStorageItemPreferences.add(mAudiosPreference);
mStorageItemPreferences.add(mAppsPreference);
mStorageItemPreferences.add(mGamesPreference);
mStorageItemPreferences.add(mDocumentsAndOtherPreference);
mStorageItemPreferences.add(mSystemPreference);
mStorageItemPreferences.add(mTrashPreference);
}
mScreen.removePreference(mImagesPreference);
mScreen.removePreference(mVideosPreference);
mScreen.removePreference(mAudiosPreference);
mScreen.removePreference(mAppsPreference);
mScreen.removePreference(mGamesPreference);
mScreen.removePreference(mDocumentsAndOtherPreference);
mScreen.removePreference(mSystemPreference);
mScreen.removePreference(mTrashPreference);
// Sort display order by size.
Collections.sort(mStorageItemPreferences,
Comparator.comparingLong(StorageItemPreference::getStorageSize));
int orderIndex = LAST_STORAGE_CATEGORY_PREFERENCE_ORDER;
for (StorageItemPreference preference : mStorageItemPreferences) {
preference.setOrder(orderIndex--);
mScreen.addPreference(preference);
}
}
/** /**
* Sets the user id for which this preference controller is handling. * Sets the user id for which this preference controller is handling.
*/ */
public void setUserId(UserHandle userHandle) { public void setUserId(UserHandle userHandle) {
mUserId = userHandle.getIdentifier(); mUserId = userHandle.getIdentifier();
tintPreference(mPhotoPreference); tintPreference(mImagesPreference);
tintPreference(mMoviesPreference); tintPreference(mVideosPreference);
tintPreference(mAudioPreference); tintPreference(mAudiosPreference);
tintPreference(mGamePreference); tintPreference(mAppsPreference);
tintPreference(mAppPreference); tintPreference(mGamesPreference);
tintPreference(mDocumentsAndOtherPreference);
tintPreference(mSystemPreference); tintPreference(mSystemPreference);
tintPreference(mFilePreference); tintPreference(mTrashPreference);
} }
private void tintPreference(Preference preference) { private void tintPreference(Preference preference) {
@@ -263,15 +320,20 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
@Override @Override
public void displayPreference(PreferenceScreen screen) { public void displayPreference(PreferenceScreen screen) {
mScreen = screen; mScreen = screen;
mPhotoPreference = screen.findPreference(PHOTO_KEY); mImagesPreference = screen.findPreference(IMAGES_KEY);
mAudioPreference = screen.findPreference(AUDIO_KEY); mVideosPreference = screen.findPreference(VIDEOS_KEY);
mGamePreference = screen.findPreference(GAME_KEY); mAudiosPreference = screen.findPreference(AUDIOS_KEY);
mMoviesPreference = screen.findPreference(MOVIES_KEY); mAppsPreference = screen.findPreference(APPS_KEY);
mAppPreference = screen.findPreference(OTHER_APPS_KEY); mGamesPreference = screen.findPreference(GAMES_KEY);
mDocumentsAndOtherPreference = screen.findPreference(DOCUMENTS_AND_OTHER_KEY);
mSystemPreference = screen.findPreference(SYSTEM_KEY); mSystemPreference = screen.findPreference(SYSTEM_KEY);
mFilePreference = screen.findPreference(FILES_KEY); mTrashPreference = screen.findPreference(TRASH_KEY);
updateCategoryPreferencesVisibility(); final boolean isValidVolume = isValidVolume();
setCategoryPreferencesVisibility(isValidVolume);
if (isValidVolume) {
updateCategoryPreferencesOrder();
}
} }
public void onLoadFinished(SparseArray<StorageAsyncLoader.AppsStorageResult> result, public void onLoadFinished(SparseArray<StorageAsyncLoader.AppsStorageResult> result,
@@ -280,12 +342,14 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
final StorageAsyncLoader.AppsStorageResult profileData = result.get( final StorageAsyncLoader.AppsStorageResult profileData = result.get(
Utils.getManagedProfileId(mContext.getSystemService(UserManager.class), userId)); Utils.getManagedProfileId(mContext.getSystemService(UserManager.class), userId));
mPhotoPreference.setStorageSize(getPhotosSize(data, profileData), mTotalSize); mImagesPreference.setStorageSize(getImagesSize(data, profileData), mTotalSize);
mAudioPreference.setStorageSize(getAudioSize(data, profileData), mTotalSize); mVideosPreference.setStorageSize(getVideosSize(data, profileData), mTotalSize);
mGamePreference.setStorageSize(getGamesSize(data, profileData), mTotalSize); mAudiosPreference.setStorageSize(getAudiosSize(data, profileData), mTotalSize);
mMoviesPreference.setStorageSize(getMoviesSize(data, profileData), mTotalSize); mAppsPreference.setStorageSize(getAppsSize(data, profileData), mTotalSize);
mAppPreference.setStorageSize(getAppsSize(data, profileData), mTotalSize); mGamesPreference.setStorageSize(getGamesSize(data, profileData), mTotalSize);
mFilePreference.setStorageSize(getFilesSize(data, profileData), mTotalSize); mDocumentsAndOtherPreference.setStorageSize(getDocumentsAndOtherSize(data, profileData),
mTotalSize);
mTrashPreference.setStorageSize(getTrashSize(data, profileData), mTotalSize);
if (mSystemPreference != null) { if (mSystemPreference != null) {
// Everything else that hasn't already been attributed is tracked as // Everything else that hasn't already been attributed is tracked as
@@ -306,6 +370,8 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
final long systemSize = Math.max(TrafficStats.GB_IN_BYTES, mUsedBytes - attributedSize); final long systemSize = Math.max(TrafficStats.GB_IN_BYTES, mUsedBytes - attributedSize);
mSystemPreference.setStorageSize(systemSize, mTotalSize); mSystemPreference.setStorageSize(systemSize, mTotalSize);
} }
updateCategoryPreferencesOrder();
} }
public void setUsedSize(long usedSizeBytes) { public void setUsedSize(long usedSizeBytes) {
@@ -316,37 +382,32 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mTotalSize = totalSizeBytes; mTotalSize = totalSizeBytes;
} }
/** // TODO(b/183078080): To simplify StorageItemPreferenceController, move launchxxxIntent to a
* Returns a list of keys used by this preference controller. // utility object.
*/ private void launchImagesIntent() {
public static List<String> getUsedKeys() { Intent intent = new Intent(Intent.ACTION_VIEW);
List<String> list = new ArrayList<>(); intent.setData(mImagesUri);
list.add(PHOTO_KEY);
list.add(AUDIO_KEY); if (intent.resolveActivity(mPackageManager) == null) {
list.add(GAME_KEY); final Bundle args = getWorkAnnotatedBundle(2);
list.add(MOVIES_KEY); args.putString(ManageApplications.EXTRA_CLASSNAME,
list.add(OTHER_APPS_KEY); Settings.PhotosStorageActivity.class.getName());
list.add(SYSTEM_KEY); args.putInt(ManageApplications.EXTRA_STORAGE_TYPE,
list.add(FILES_KEY); ManageApplications.STORAGE_TYPE_PHOTOS_VIDEOS);
return list; intent = new SubSettingLauncher(mContext)
.setDestination(ManageApplications.class.getName())
.setTitleRes(R.string.storage_photos_videos)
.setArguments(args)
.setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
.toIntent();
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
Utils.launchIntent(mFragment, intent);
} else {
mContext.startActivity(intent);
}
} }
private Intent getPhotosIntent() { private long getImagesSize(StorageAsyncLoader.AppsStorageResult data,
Bundle args = getWorkAnnotatedBundle(2);
args.putString(
ManageApplications.EXTRA_CLASSNAME, Settings.PhotosStorageActivity.class.getName());
args.putInt(
ManageApplications.EXTRA_STORAGE_TYPE,
ManageApplications.STORAGE_TYPE_PHOTOS_VIDEOS);
return new SubSettingLauncher(mContext)
.setDestination(ManageApplications.class.getName())
.setTitleRes(R.string.storage_photos_videos)
.setArguments(args)
.setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
.toIntent();
}
private long getPhotosSize(StorageAsyncLoader.AppsStorageResult data,
StorageAsyncLoader.AppsStorageResult profileData) { StorageAsyncLoader.AppsStorageResult profileData) {
if (profileData != null) { if (profileData != null) {
return data.photosAppsSize + data.externalStats.imageBytes return data.photosAppsSize + data.externalStats.imageBytes
@@ -359,26 +420,62 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
} }
} }
private Intent getAudioIntent() { private void launchVideosIntent() {
if (mVolume == null) { Intent intent = new Intent(Intent.ACTION_VIEW);
return null; intent.setData(mVideosUri);
}
Bundle args = getWorkAnnotatedBundle(4); if (intent.resolveActivity(mPackageManager) == null) {
args.putString(ManageApplications.EXTRA_CLASSNAME, final Bundle args = getWorkAnnotatedBundle(1);
Settings.StorageUseActivity.class.getName()); args.putString(ManageApplications.EXTRA_CLASSNAME,
args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid()); Settings.MoviesStorageActivity.class.getName());
args.putString(ManageApplications.EXTRA_VOLUME_NAME, mVolume.getDescription()); intent = new SubSettingLauncher(mContext)
args.putInt(ManageApplications.EXTRA_STORAGE_TYPE, ManageApplications.STORAGE_TYPE_MUSIC); .setDestination(ManageApplications.class.getName())
return new SubSettingLauncher(mContext) .setTitleRes(R.string.storage_movies_tv)
.setDestination(ManageApplications.class.getName()) .setArguments(args)
.setTitleRes(R.string.storage_music_audio) .setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
.setArguments(args) .toIntent();
.setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment)) intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
.toIntent(); Utils.launchIntent(mFragment, intent);
} else {
mContext.startActivity(intent);
}
} }
private long getAudioSize(StorageAsyncLoader.AppsStorageResult data, private long getVideosSize(StorageAsyncLoader.AppsStorageResult data,
StorageAsyncLoader.AppsStorageResult profileData) {
if (profileData != null) {
return data.videoAppsSize + profileData.videoAppsSize;
} else {
return data.videoAppsSize;
}
}
private void launchAudiosIntent() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(mAudiosUri);
if (intent.resolveActivity(mPackageManager) == null) {
final Bundle args = getWorkAnnotatedBundle(4);
args.putString(ManageApplications.EXTRA_CLASSNAME,
Settings.StorageUseActivity.class.getName());
args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid());
args.putString(ManageApplications.EXTRA_VOLUME_NAME, mVolume.getDescription());
args.putInt(ManageApplications.EXTRA_STORAGE_TYPE,
ManageApplications.STORAGE_TYPE_MUSIC);
intent = new SubSettingLauncher(mContext)
.setDestination(ManageApplications.class.getName())
.setTitleRes(R.string.storage_music_audio)
.setArguments(args)
.setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
.toIntent();
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
Utils.launchIntent(mFragment, intent);
} else {
mContext.startActivity(intent);
}
}
private long getAudiosSize(StorageAsyncLoader.AppsStorageResult data,
StorageAsyncLoader.AppsStorageResult profileData) { StorageAsyncLoader.AppsStorageResult profileData) {
if (profileData != null) { if (profileData != null) {
return data.musicAppsSize + data.externalStats.audioBytes return data.musicAppsSize + data.externalStats.audioBytes
@@ -388,21 +485,20 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
} }
} }
private Intent getAppsIntent() { private void launchAppsIntent() {
if (mVolume == null) {
return null;
}
final Bundle args = getWorkAnnotatedBundle(3); final Bundle args = getWorkAnnotatedBundle(3);
args.putString(ManageApplications.EXTRA_CLASSNAME, args.putString(ManageApplications.EXTRA_CLASSNAME,
Settings.StorageUseActivity.class.getName()); Settings.StorageUseActivity.class.getName());
args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid()); args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid());
args.putString(ManageApplications.EXTRA_VOLUME_NAME, mVolume.getDescription()); args.putString(ManageApplications.EXTRA_VOLUME_NAME, mVolume.getDescription());
return new SubSettingLauncher(mContext) final Intent intent = new SubSettingLauncher(mContext)
.setDestination(ManageApplications.class.getName()) .setDestination(ManageApplications.class.getName())
.setTitleRes(R.string.apps_storage) .setTitleRes(R.string.apps_storage)
.setArguments(args) .setArguments(args)
.setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment)) .setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
.toIntent(); .toIntent();
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
Utils.launchIntent(mFragment, intent);
} }
private long getAppsSize(StorageAsyncLoader.AppsStorageResult data, private long getAppsSize(StorageAsyncLoader.AppsStorageResult data,
@@ -414,16 +510,18 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
} }
} }
private Intent getGamesIntent() { private void launchGamesIntent() {
final Bundle args = getWorkAnnotatedBundle(1); final Bundle args = getWorkAnnotatedBundle(1);
args.putString(ManageApplications.EXTRA_CLASSNAME, args.putString(ManageApplications.EXTRA_CLASSNAME,
Settings.GamesStorageActivity.class.getName()); Settings.GamesStorageActivity.class.getName());
return new SubSettingLauncher(mContext) final Intent intent = new SubSettingLauncher(mContext)
.setDestination(ManageApplications.class.getName()) .setDestination(ManageApplications.class.getName())
.setTitleRes(R.string.game_storage_settings) .setTitleRes(R.string.game_storage_settings)
.setArguments(args) .setArguments(args)
.setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment)) .setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
.toIntent(); .toIntent();
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
Utils.launchIntent(mFragment, intent);
} }
private long getGamesSize(StorageAsyncLoader.AppsStorageResult data, private long getGamesSize(StorageAsyncLoader.AppsStorageResult data,
@@ -435,27 +533,6 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
} }
} }
private Intent getMoviesIntent() {
final Bundle args = getWorkAnnotatedBundle(1);
args.putString(ManageApplications.EXTRA_CLASSNAME,
Settings.MoviesStorageActivity.class.getName());
return new SubSettingLauncher(mContext)
.setDestination(ManageApplications.class.getName())
.setTitleRes(R.string.storage_movies_tv)
.setArguments(args)
.setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
.toIntent();
}
private long getMoviesSize(StorageAsyncLoader.AppsStorageResult data,
StorageAsyncLoader.AppsStorageResult profileData) {
if (profileData != null) {
return data.videoAppsSize + profileData.videoAppsSize;
} else {
return data.videoAppsSize;
}
}
private Bundle getWorkAnnotatedBundle(int additionalCapacity) { private Bundle getWorkAnnotatedBundle(int additionalCapacity) {
final Bundle args = new Bundle(1 + additionalCapacity); final Bundle args = new Bundle(1 + additionalCapacity);
args.putInt(SettingsActivity.EXTRA_SHOW_FRAGMENT_TAB, args.putInt(SettingsActivity.EXTRA_SHOW_FRAGMENT_TAB,
@@ -463,11 +540,20 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
return args; return args;
} }
private Intent getFilesIntent() { private void launchDocumentsAndOtherIntent() {
return mSvp.findEmulatedForPrivate(mVolume).buildBrowseIntent(); Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(mDocumentsAndOtherUri);
if (intent.resolveActivity(mPackageManager) == null) {
intent = mSvp.findEmulatedForPrivate(mVolume).buildBrowseIntent();
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
Utils.launchIntent(mFragment, intent);
} else {
mContext.startActivity(intent);
}
} }
private long getFilesSize(StorageAsyncLoader.AppsStorageResult data, private long getDocumentsAndOtherSize(StorageAsyncLoader.AppsStorageResult data,
StorageAsyncLoader.AppsStorageResult profileData) { StorageAsyncLoader.AppsStorageResult profileData) {
if (profileData != null) { if (profileData != null) {
return data.externalStats.totalBytes return data.externalStats.totalBytes
@@ -489,6 +575,22 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
} }
} }
private void launchTrashIntent() {
final Intent intent = new Intent("android.settings.VIEW_TRASH");
if (intent.resolveActivity(mPackageManager) == null) {
EmptyTrashFragment.show(mFragment);
} else {
mContext.startActivity(intent);
}
}
private long getTrashSize(StorageAsyncLoader.AppsStorageResult data,
StorageAsyncLoader.AppsStorageResult profileData) {
// TODO(170918505): Implement it.
return 0L;
}
private static long totalValues(StorageMeasurement.MeasurementDetails details, int userId, private static long totalValues(StorageMeasurement.MeasurementDetails details, int userId,
String... keys) { String... keys) {
long total = 0; long total = 0;

View File

@@ -69,4 +69,11 @@ public class StorageItemPreferenceTest {
assertThat(progressBar).isNotNull(); assertThat(progressBar).isNotNull();
assertThat(progressBar.getProgress()).isEqualTo(10); assertThat(progressBar.getProgress()).isEqualTo(10);
} }
@Test
public void getStorageSize_setStorageSize_getCorrectStorageSize() {
mPreference.setStorageSize(MEGABYTE_IN_BYTES, MEGABYTE_IN_BYTES * 10);
assertThat(mPreference.getStorageSize()).isEqualTo(MEGABYTE_IN_BYTES);
}
} }

View File

@@ -43,7 +43,6 @@ import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.FragmentTransaction;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings; import com.android.settings.SubSettings;
@@ -51,10 +50,8 @@ import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment; import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.deviceinfo.PrivateVolumeSettings; import com.android.settings.deviceinfo.PrivateVolumeSettings;
import com.android.settings.deviceinfo.StorageItemPreference; import com.android.settings.deviceinfo.StorageItemPreference;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.applications.StorageStatsSource; import com.android.settingslib.applications.StorageStatsSource;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.deviceinfo.StorageVolumeProvider; import com.android.settingslib.deviceinfo.StorageVolumeProvider;
import org.junit.Before; import org.junit.Before;
@@ -84,8 +81,7 @@ public class StorageItemPreferenceControllerTest {
private FragmentTransaction mFragmentTransaction; private FragmentTransaction mFragmentTransaction;
private StorageItemPreferenceController mController; private StorageItemPreferenceController mController;
private StorageItemPreference mPreference; private StorageItemPreference mPreference;
private FakeFeatureFactory mFakeFeatureFactory; private PreferenceScreen mPreferenceScreen;
private MetricsFeatureProvider mMetricsFeatureProvider;
@Before @Before
public void setUp() { public void setUp() {
@@ -94,8 +90,6 @@ public class StorageItemPreferenceControllerTest {
when(mFragment.getFragmentManager()).thenReturn(mFragmentManager); when(mFragment.getFragmentManager()).thenReturn(mFragmentManager);
when(mFragmentManager.beginTransaction()).thenReturn(mFragmentTransaction); when(mFragmentManager.beginTransaction()).thenReturn(mFragmentTransaction);
mContext = spy(RuntimeEnvironment.application.getApplicationContext()); mContext = spy(RuntimeEnvironment.application.getApplicationContext());
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
mVolume = spy(new VolumeInfo("id", 0, null, "id")); mVolume = spy(new VolumeInfo("id", 0, null, "id"));
// Note: null is passed as the Lifecycle because we are handling it outside of the normal // Note: null is passed as the Lifecycle because we are handling it outside of the normal
// Settings fragment lifecycle for test purposes. // Settings fragment lifecycle for test purposes.
@@ -105,6 +99,47 @@ public class StorageItemPreferenceControllerTest {
// Inflate the preference and the widget. // Inflate the preference and the widget.
final LayoutInflater inflater = LayoutInflater.from(mContext); final LayoutInflater inflater = LayoutInflater.from(mContext);
inflater.inflate(mPreference.getLayoutResource(), new LinearLayout(mContext), false); inflater.inflate(mPreference.getLayoutResource(), new LinearLayout(mContext), false);
mPreferenceScreen = getPreferenceScreen();
}
private PreferenceScreen getPreferenceScreen() {
final StorageItemPreference images = spy(new StorageItemPreference(mContext));
images.setIcon(R.drawable.ic_photo_library);
final StorageItemPreference videos = spy(new StorageItemPreference(mContext));
videos.setIcon(R.drawable.ic_local_movies);
final StorageItemPreference audios = spy(new StorageItemPreference(mContext));
audios.setIcon(R.drawable.ic_media_stream);
final StorageItemPreference apps = spy(new StorageItemPreference(mContext));
apps.setIcon(R.drawable.ic_storage_apps);
final StorageItemPreference games = spy(new StorageItemPreference(mContext));
games.setIcon(R.drawable.ic_videogame_vd_theme_24);
final StorageItemPreference documentsAndOther = spy(new StorageItemPreference(mContext));
documentsAndOther.setIcon(R.drawable.ic_folder_vd_theme_24);
final StorageItemPreference system = spy(new StorageItemPreference(mContext));
system.setIcon(R.drawable.ic_system_update);
final StorageItemPreference trash = spy(new StorageItemPreference(mContext));
trash.setIcon(R.drawable.ic_trash_can);
final PreferenceScreen screen = mock(PreferenceScreen.class);
when(screen.findPreference(eq(StorageItemPreferenceController.IMAGES_KEY)))
.thenReturn(images);
when(screen.findPreference(eq(StorageItemPreferenceController.VIDEOS_KEY)))
.thenReturn(videos);
when(screen.findPreference(eq(StorageItemPreferenceController.AUDIOS_KEY)))
.thenReturn(audios);
when(screen.findPreference(eq(StorageItemPreferenceController.APPS_KEY)))
.thenReturn(apps);
when(screen.findPreference(eq(StorageItemPreferenceController.GAMES_KEY)))
.thenReturn(games);
when(screen.findPreference(eq(StorageItemPreferenceController.DOCUMENTS_AND_OTHER_KEY)))
.thenReturn(documentsAndOther);
when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
.thenReturn(system);
when(screen.findPreference(eq(StorageItemPreferenceController.TRASH_KEY)))
.thenReturn(trash);
return screen;
} }
@Test @Test
@@ -114,8 +149,8 @@ public class StorageItemPreferenceControllerTest {
} }
@Test @Test
public void testClickPhotos() { public void launchImagesIntent_resolveActionViewNull_settingsIntent() {
mPreference.setKey("pref_photos_videos"); mPreference.setKey(StorageItemPreferenceController.IMAGES_KEY);
mController.handlePreferenceTreeClick(mPreference); mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class); final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -132,8 +167,8 @@ public class StorageItemPreferenceControllerTest {
} }
@Test @Test
public void testClickAudio() { public void launchAudiosIntent_resolveActionViewNull_settingsIntent() {
mPreference.setKey("pref_music_audio"); mPreference.setKey(StorageItemPreferenceController.AUDIOS_KEY);
mController.handlePreferenceTreeClick(mPreference); mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class); final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -151,16 +186,24 @@ public class StorageItemPreferenceControllerTest {
} }
@Test @Test
public void handlePreferenceTreeClick_tappingAudioWhileUninitializedDoesntCrash() { public void setVolume_nullVolume_hidePreferences() {
mController.displayPreference(mPreferenceScreen);
mController.setVolume(null); mController.setVolume(null);
mPreference.setKey("pref_music_audio"); assertThat(mController.mImagesPreference.isVisible()).isFalse();
mController.handlePreferenceTreeClick(mPreference); assertThat(mController.mVideosPreference.isVisible()).isFalse();
assertThat(mController.mAudiosPreference.isVisible()).isFalse();
assertThat(mController.mAppsPreference.isVisible()).isFalse();
assertThat(mController.mGamesPreference.isVisible()).isFalse();
assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
assertThat(mController.mSystemPreference.isVisible()).isFalse();
assertThat(mController.mTrashPreference.isVisible()).isFalse();
} }
@Test @Test
public void testClickApps() { public void launchAppsIntent_forPersonal_settingsIntent() {
mPreference.setKey("pref_other_apps"); mPreference.setKey(StorageItemPreferenceController.APPS_KEY);
mController.handlePreferenceTreeClick(mPreference); mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class); final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -177,9 +220,9 @@ public class StorageItemPreferenceControllerTest {
} }
@Test @Test
public void testClickAppsForWork() { public void launchAppsIntent_forWork_settingsIntent() {
mController = new StorageItemPreferenceController(mContext, mFragment, mVolume, mSvp, true); mController = new StorageItemPreferenceController(mContext, mFragment, mVolume, mSvp, true);
mPreference.setKey("pref_other_apps"); mPreference.setKey(StorageItemPreferenceController.APPS_KEY);
mController.handlePreferenceTreeClick(mPreference); mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class); final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -204,18 +247,10 @@ public class StorageItemPreferenceControllerTest {
} }
@Test @Test
public void handlePreferenceTreeClick_tappingAppsWhileUninitializedDoesntCrash() { public void launchDocumentsAndOtherIntent_resolveActionViewNull_settingsIntent() {
mController.setVolume(null);
mPreference.setKey("pref_other_apps");
mController.handlePreferenceTreeClick(mPreference);
}
@Test
public void testClickFiles() {
when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume); when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
when(mVolume.buildBrowseIntent()).thenReturn(new Intent()); when(mVolume.buildBrowseIntent()).thenReturn(new Intent());
mPreference.setKey("pref_files"); mPreference.setKey(StorageItemPreferenceController.DOCUMENTS_AND_OTHER_KEY);
assertThat(mController.handlePreferenceTreeClick(mPreference)) assertThat(mController.handlePreferenceTreeClick(mPreference))
.isTrue(); .isTrue();
@@ -227,13 +262,11 @@ public class StorageItemPreferenceControllerTest {
Intent browseIntent = mVolume.buildBrowseIntent(); Intent browseIntent = mVolume.buildBrowseIntent();
assertThat(intent.getAction()).isEqualTo(browseIntent.getAction()); assertThat(intent.getAction()).isEqualTo(browseIntent.getAction());
assertThat(intent.getData()).isEqualTo(browseIntent.getData()); assertThat(intent.getData()).isEqualTo(browseIntent.getData());
verify(mMetricsFeatureProvider, times(1))
.action(nullable(Context.class), eq(MetricsEvent.STORAGE_FILES));
} }
@Test @Test
public void testClickGames() { public void launchGamesIntent_settingsIntent() {
mPreference.setKey("pref_games"); mPreference.setKey(StorageItemPreferenceController.GAMES_KEY);
mController.handlePreferenceTreeClick(mPreference); mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class); final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -250,8 +283,8 @@ public class StorageItemPreferenceControllerTest {
} }
@Test @Test
public void testClickMovies() { public void launchVideosIntent_resolveActionViewNull_settingsIntent() {
mPreference.setKey("pref_movies"); mPreference.setKey(StorageItemPreferenceController.VIDEOS_KEY);
mController.handlePreferenceTreeClick(mPreference); mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class); final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -269,7 +302,7 @@ public class StorageItemPreferenceControllerTest {
@Test @Test
public void testClickSystem() { public void testClickSystem() {
mPreference.setKey("pref_system"); mPreference.setKey(StorageItemPreferenceController.SYSTEM_KEY);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue(); assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
verify(mFragment.getFragmentManager().beginTransaction()) verify(mFragment.getFragmentManager().beginTransaction())
@@ -279,29 +312,7 @@ public class StorageItemPreferenceControllerTest {
@Test @Test
@Config(shadows = ShadowUserManager.class) @Config(shadows = ShadowUserManager.class)
public void testMeasurementCompletedUpdatesPreferences() { public void testMeasurementCompletedUpdatesPreferences() {
final StorageItemPreference audio = new StorageItemPreference(mContext); mController.displayPreference(mPreferenceScreen);
final StorageItemPreference image = new StorageItemPreference(mContext);
final StorageItemPreference games = new StorageItemPreference(mContext);
final StorageItemPreference movies = new StorageItemPreference(mContext);
final StorageItemPreference apps = new StorageItemPreference(mContext);
final StorageItemPreference system = new StorageItemPreference(mContext);
final StorageItemPreference files = new StorageItemPreference(mContext);
final PreferenceScreen screen = mock(PreferenceScreen.class);
when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
.thenReturn(games);
when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
.thenReturn(audio);
when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
.thenReturn(image);
when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
.thenReturn(files);
when(screen.findPreference(eq(StorageItemPreferenceController.MOVIES_KEY)))
.thenReturn(movies);
when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
.thenReturn(system);
when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
.thenReturn(apps);
mController.displayPreference(screen);
mController.setUsedSize(MEGABYTE_IN_BYTES * 970); // There should 870MB attributed. mController.setUsedSize(MEGABYTE_IN_BYTES * 970); // There should 870MB attributed.
final StorageAsyncLoader.AppsStorageResult result = final StorageAsyncLoader.AppsStorageResult result =
@@ -321,211 +332,90 @@ public class StorageItemPreferenceControllerTest {
results.put(0, result); results.put(0, result);
mController.onLoadFinished(results, 0); mController.onLoadFinished(results, 0);
assertThat(audio.getSummary().toString()).isEqualTo("0.14 GB"); assertThat(mController.mImagesPreference.getSummary().toString()).isEqualTo("0.35 GB");
assertThat(image.getSummary().toString()).isEqualTo("0.35 GB"); assertThat(mController.mVideosPreference.getSummary().toString()).isEqualTo("0.16 GB");
assertThat(games.getSummary().toString()).isEqualTo("0.08 GB"); assertThat(mController.mAudiosPreference.getSummary().toString()).isEqualTo("0.14 GB");
assertThat(movies.getSummary().toString()).isEqualTo("0.16 GB"); assertThat(mController.mAppsPreference.getSummary().toString()).isEqualTo("0.09 GB");
assertThat(apps.getSummary().toString()).isEqualTo("0.09 GB"); assertThat(mController.mGamesPreference.getSummary().toString()).isEqualTo("0.08 GB");
assertThat(files.getSummary().toString()).isEqualTo("0.05 GB"); assertThat(mController.mDocumentsAndOtherPreference.getSummary().toString())
.isEqualTo("0.05 GB");
} }
@Test @Test
public void settingUserIdAppliesNewIcons() { public void settingUserIdAppliesNewIcons() {
final StorageItemPreference audio = spy(new StorageItemPreference(mContext)); mController.displayPreference(mPreferenceScreen);
audio.setIcon(R.drawable.ic_media_stream);
final StorageItemPreference video = spy(new StorageItemPreference(mContext));
video.setIcon(R.drawable.ic_local_movies);
final StorageItemPreference image = spy(new StorageItemPreference(mContext));
image.setIcon(R.drawable.ic_photo_library);
final StorageItemPreference games = spy(new StorageItemPreference(mContext));
games.setIcon(R.drawable.ic_videogame_vd_theme_24);
final StorageItemPreference apps = spy(new StorageItemPreference(mContext));
apps.setIcon(R.drawable.ic_storage_apps);
final StorageItemPreference system = spy(new StorageItemPreference(mContext));
system.setIcon(R.drawable.ic_system_update);
final StorageItemPreference files = spy(new StorageItemPreference(mContext));
files.setIcon(R.drawable.ic_folder_vd_theme_24);
final PreferenceScreen screen = mock(PreferenceScreen.class);
when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
.thenReturn(games);
when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
.thenReturn(audio);
when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
.thenReturn(image);
when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
.thenReturn(files);
when(screen.findPreference(eq(StorageItemPreferenceController.MOVIES_KEY)))
.thenReturn(video);
when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
.thenReturn(system);
when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
.thenReturn(apps);
mController.displayPreference(screen);
mController.setUserId(new UserHandle(10)); mController.setUserId(new UserHandle(10));
verify(audio, times(2)).setIcon(nullable(Drawable.class)); verify(mController.mImagesPreference, times(2)).setIcon(nullable(Drawable.class));
verify(video, times(2)).setIcon(nullable(Drawable.class)); verify(mController.mVideosPreference, times(2)).setIcon(nullable(Drawable.class));
verify(image, times(2)).setIcon(nullable(Drawable.class)); verify(mController.mAudiosPreference, times(2)).setIcon(nullable(Drawable.class));
verify(games, times(2)).setIcon(nullable(Drawable.class)); verify(mController.mAppsPreference, times(2)).setIcon(nullable(Drawable.class));
verify(apps, times(2)).setIcon(nullable(Drawable.class)); verify(mController.mGamesPreference, times(2)).setIcon(nullable(Drawable.class));
verify(system, times(2)).setIcon(nullable(Drawable.class)); verify(mController.mDocumentsAndOtherPreference, times(2))
verify(files, times(2)).setIcon(nullable(Drawable.class)); .setIcon(nullable(Drawable.class));
verify(mController.mSystemPreference, times(2)).setIcon(nullable(Drawable.class));
verify(mController.mTrashPreference, times(2)).setIcon(nullable(Drawable.class));
} }
@Test @Test
public void displayPreference_dontHideFilePreferenceWhenEmulatedInternalStorageUsed() { public void displayPreference_dontHideFilePreferenceWhenEmulatedInternalStorageUsed() {
final StorageItemPreference audio = new StorageItemPreference(mContext);
final StorageItemPreference image = new StorageItemPreference(mContext);
final StorageItemPreference games = new StorageItemPreference(mContext);
final StorageItemPreference apps = new StorageItemPreference(mContext);
final StorageItemPreference system = new StorageItemPreference(mContext);
final StorageItemPreference files = new StorageItemPreference(mContext);
final PreferenceScreen screen = mock(PreferenceScreen.class);
when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
.thenReturn(games);
when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
.thenReturn(audio);
when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
.thenReturn(image);
when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
.thenReturn(files);
when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
.thenReturn(system);
when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
.thenReturn(apps);
when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume); when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
when(mVolume.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
when(mVolume.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
when(mVolume.isMountedReadable()).thenReturn(true); when(mVolume.isMountedReadable()).thenReturn(true);
mController.displayPreference(screen); mController.displayPreference(mPreferenceScreen);
verify(screen, times(0)).removePreference(files); assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isTrue();
} }
@Test @Test
public void displayPreference_hideFilePreferenceWhenEmulatedStorageUnreadable() { public void displayPreference_hideFilePreferenceWhenEmulatedStorageUnreadable() {
final StorageItemPreference audio = new StorageItemPreference(mContext);
final StorageItemPreference image = new StorageItemPreference(mContext);
final StorageItemPreference games = new StorageItemPreference(mContext);
final StorageItemPreference apps = new StorageItemPreference(mContext);
final StorageItemPreference system = new StorageItemPreference(mContext);
final StorageItemPreference files = new StorageItemPreference(mContext);
final PreferenceScreen screen = mock(PreferenceScreen.class);
when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
.thenReturn(games);
when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
.thenReturn(audio);
when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
.thenReturn(image);
when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
.thenReturn(files);
when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
.thenReturn(system);
when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
.thenReturn(apps);
when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume); when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
when(mVolume.isMountedReadable()).thenReturn(false); when(mVolume.isMountedReadable()).thenReturn(false);
mController.displayPreference(screen); mController.displayPreference(mPreferenceScreen);
verify(screen).removePreference(files); assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
} }
@Test @Test
public void displayPreference_hideFilePreferenceWhenNoEmulatedInternalStorage() { public void displayPreference_noEmulatedInternalStorage_hidePreference() {
final StorageItemPreference audio = new StorageItemPreference(mContext);
final StorageItemPreference image = new StorageItemPreference(mContext);
final StorageItemPreference games = new StorageItemPreference(mContext);
final StorageItemPreference apps = new StorageItemPreference(mContext);
final StorageItemPreference system = new StorageItemPreference(mContext);
final StorageItemPreference files = new StorageItemPreference(mContext);
final PreferenceScreen screen = mock(PreferenceScreen.class);
when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
.thenReturn(games);
when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
.thenReturn(audio);
when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
.thenReturn(image);
when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
.thenReturn(files);
when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
.thenReturn(system);
when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
.thenReturn(apps);
when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(null); when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(null);
mController.displayPreference(screen); mController.displayPreference(mPreferenceScreen);
verify(screen).removePreference(files); assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
} }
@Test @Test
public void displayPreference_updateFilePreferenceToHideAfterSettingVolume() { public void setVolume_updateFilePreferenceToHideAfterSettingVolume_hidePreference() {
final StorageItemPreference audio = new StorageItemPreference(mContext);
final StorageItemPreference image = new StorageItemPreference(mContext);
final StorageItemPreference games = new StorageItemPreference(mContext);
final StorageItemPreference apps = new StorageItemPreference(mContext);
final StorageItemPreference system = new StorageItemPreference(mContext);
final StorageItemPreference files = new StorageItemPreference(mContext);
final PreferenceScreen screen = mock(PreferenceScreen.class);
when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
.thenReturn(games);
when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
.thenReturn(audio);
when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
.thenReturn(image);
when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
.thenReturn(files);
when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
.thenReturn(system);
when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
.thenReturn(apps);
when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume); when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
when(mVolume.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
when(mVolume.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
when(mVolume.isMountedReadable()).thenReturn(true); when(mVolume.isMountedReadable()).thenReturn(true);
mController.displayPreference(screen); mController.displayPreference(mPreferenceScreen);
when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(null); when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(null);
mController.setVolume(mVolume); mController.setVolume(mVolume);
verify(screen).removePreference(files); assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
} }
@Test @Test
public void displayPreference_updateFilePreferenceToShowAfterSettingVolume() { public void setVolume_updateFilePreferenceToShowAfterSettingVolume_showPreference() {
final StorageItemPreference audio = new StorageItemPreference(mContext);
final StorageItemPreference image = new StorageItemPreference(mContext);
final StorageItemPreference games = new StorageItemPreference(mContext);
final StorageItemPreference apps = new StorageItemPreference(mContext);
final StorageItemPreference system = new StorageItemPreference(mContext);
final StorageItemPreference files = new StorageItemPreference(mContext);
final PreferenceScreen screen = mock(PreferenceScreen.class);
when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
.thenReturn(games);
when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
.thenReturn(audio);
when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
.thenReturn(image);
when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
.thenReturn(files);
when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
.thenReturn(system);
when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
.thenReturn(apps);
// This will hide it initially. // This will hide it initially.
mController.displayPreference(screen); mController.displayPreference(mPreferenceScreen);
when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume); when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
when(mVolume.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
when(mVolume.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
when(mVolume.isMountedReadable()).thenReturn(true); when(mVolume.isMountedReadable()).thenReturn(true);
// And we bring it back. // And we bring it back.
mController.setVolume(mVolume); mController.setVolume(mVolume);
verify(screen).addPreference(files); assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isTrue();
} }
} }