Merge "Show "Files" category for public storage in Storage Settings" into sc-dev

This commit is contained in:
Arc Wang
2021-03-30 09:48:04 +00:00
committed by Android (Google) Code Review
6 changed files with 157 additions and 47 deletions

View File

@@ -44,38 +44,51 @@
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. -->
<Preference
android:key="pref_public_storage"
android:title="@string/storage_files"
android:icon="@drawable/ic_folder_vd_theme_24"
android:order="100"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_images"
android:title="@string/storage_images"
android:icon="@drawable/ic_photo_library"/>
android:icon="@drawable/ic_photo_library"
android:order="101"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_videos"
android:title="@string/storage_videos"
android:icon="@drawable/ic_local_movies"/>
android:icon="@drawable/ic_local_movies"
android:order="102"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_audios"
android:title="@string/storage_audios"
android:icon="@drawable/ic_media_stream"/>
android:icon="@drawable/ic_media_stream"
android:order="103"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_apps"
android:title="@string/storage_apps"
android:icon="@drawable/ic_storage_apps"/>
android:icon="@drawable/ic_storage_apps"
android:order="104"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_games"
android:title="@string/storage_games"
android:icon="@drawable/ic_videogame_vd_theme_24"/>
android:icon="@drawable/ic_videogame_vd_theme_24"
android:order="105"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_documents_and_other"
android:title="@string/storage_documents_and_other"
android:icon="@drawable/ic_folder_vd_theme_24"/>
android:icon="@drawable/ic_folder_vd_theme_24"
android:order="106"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_system"
android:title="@string/storage_system"
android:icon="@drawable/ic_system_update"/>
android:icon="@drawable/ic_system_update"
android:order="107"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_trash"
android:title="@string/storage_trash"
android:icon="@drawable/ic_trash_can"/>
android:icon="@drawable/ic_trash_can"
android:order="108"/>
<!-- Preference order 100~200 are 'ONLY' for storage category preferences above. -->
<PreferenceCategory
android:key="pref_secondary_users"

View File

@@ -248,15 +248,19 @@ public class StorageDashboardFragment extends DashboardFragment
mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo());
if (mSelectedStorageEntry.isPrivate() && mSelectedStorageEntry.isMounted()) {
if (!mSelectedStorageEntry.isMounted()) {
// Set null volume to hide category stats.
mPreferenceController.setVolume(null);
return;
}
if (mSelectedStorageEntry.isPrivate()) {
// Stats data is only available on private volumes.
getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this);
getLoaderManager()
.restartLoader(VOLUME_SIZE_JOB_ID, Bundle.EMPTY, new VolumeSizeCallbacks());
getLoaderManager().restartLoader(ICON_JOB_ID, Bundle.EMPTY, new IconLoaderCallbacks());
} else {
// Set null volume to hide category stats.
mPreferenceController.setVolume(null);
mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo());
}
}

View File

@@ -236,6 +236,14 @@ public class StorageEntry implements Comparable<StorageEntry>, Parcelable {
return mVolumeInfo == null ? false : mVolumeInfo.getType() == VolumeInfo.TYPE_PUBLIC;
}
/**
* Stub volume is a volume that is maintained by external party such as the ChromeOS processes
* in ARC++.
*/
public boolean isStub() {
return mVolumeInfo == null ? false : mVolumeInfo.getType() == VolumeInfo.TYPE_STUB;
}
/** Returns description. */
public String getDescription() {
if (isVolumeInfo()) {

View File

@@ -69,6 +69,8 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
private static final String SYSTEM_FRAGMENT_TAG = "SystemInfo";
@VisibleForTesting
static final String PUBLIC_STORAGE_KEY = "pref_public_storage";
@VisibleForTesting
static final String IMAGES_KEY = "pref_images";
@VisibleForTesting
@@ -103,9 +105,11 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
private long mUsedBytes;
private long mTotalSize;
private List<StorageItemPreference> mStorageItemPreferences;
private List<StorageItemPreference> mPrivateStorageItemPreferences;
private PreferenceScreen mScreen;
@VisibleForTesting
Preference mPublicStoragePreference;
@VisibleForTesting
StorageItemPreference mImagesPreference;
@VisibleForTesting
StorageItemPreference mVideosPreference;
@@ -167,6 +171,9 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
return false;
}
switch (preference.getKey()) {
case PUBLIC_STORAGE_KEY:
launchPublicStorageIntent();
return true;
case IMAGES_KEY:
launchImagesIntent();
return true;
@@ -210,37 +217,45 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
public void setVolume(VolumeInfo volume) {
mVolume = volume;
final boolean isValidVolume = isValidVolume();
setCategoryPreferencesVisibility(isValidVolume);
if (isValidVolume) {
updateCategoryPreferencesOrder();
}
updateCategoryPreferencesVisibility();
updatePrivateStorageCategoryPreferencesOrder();
}
// Stats data is only available on private volumes.
private boolean isValidVolume() {
private boolean isValidPrivateVolume() {
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) {
private boolean isValidPublicVolume() {
return mVolume != null
&& (mVolume.getType() == VolumeInfo.TYPE_PUBLIC
|| mVolume.getType() == VolumeInfo.TYPE_STUB)
&& (mVolume.getState() == VolumeInfo.STATE_MOUNTED
|| mVolume.getState() == VolumeInfo.STATE_MOUNTED_READ_ONLY);
}
private void updateCategoryPreferencesVisibility() {
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);
mPublicStoragePreference.setVisible(isValidPublicVolume());
final boolean privateStoragePreferencesVisible = isValidPrivateVolume();
mImagesPreference.setVisible(privateStoragePreferencesVisible);
mVideosPreference.setVisible(privateStoragePreferencesVisible);
mAudiosPreference.setVisible(privateStoragePreferencesVisible);
mAppsPreference.setVisible(privateStoragePreferencesVisible);
mGamesPreference.setVisible(privateStoragePreferencesVisible);
mDocumentsAndOtherPreference.setVisible(privateStoragePreferencesVisible);
mSystemPreference.setVisible(privateStoragePreferencesVisible);
// TODO(b/170918505): Shows trash category after trash category feature complete.
mTrashPreference.setVisible(false);
if (visible) {
if (privateStoragePreferencesVisible) {
final VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume);
// 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.
@@ -250,22 +265,22 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
}
}
private void updateCategoryPreferencesOrder() {
if (mScreen == null) {
private void updatePrivateStorageCategoryPreferencesOrder() {
if (mScreen == null || !isValidPrivateVolume()) {
return;
}
if (mStorageItemPreferences == null) {
mStorageItemPreferences = new ArrayList<>();
if (mPrivateStorageItemPreferences == null) {
mPrivateStorageItemPreferences = 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);
mPrivateStorageItemPreferences.add(mImagesPreference);
mPrivateStorageItemPreferences.add(mVideosPreference);
mPrivateStorageItemPreferences.add(mAudiosPreference);
mPrivateStorageItemPreferences.add(mAppsPreference);
mPrivateStorageItemPreferences.add(mGamesPreference);
mPrivateStorageItemPreferences.add(mDocumentsAndOtherPreference);
mPrivateStorageItemPreferences.add(mSystemPreference);
mPrivateStorageItemPreferences.add(mTrashPreference);
}
mScreen.removePreference(mImagesPreference);
mScreen.removePreference(mVideosPreference);
@@ -277,10 +292,10 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mScreen.removePreference(mTrashPreference);
// Sort display order by size.
Collections.sort(mStorageItemPreferences,
Collections.sort(mPrivateStorageItemPreferences,
Comparator.comparingLong(StorageItemPreference::getStorageSize));
int orderIndex = LAST_STORAGE_CATEGORY_PREFERENCE_ORDER;
for (StorageItemPreference preference : mStorageItemPreferences) {
for (StorageItemPreference preference : mPrivateStorageItemPreferences) {
preference.setOrder(orderIndex--);
mScreen.addPreference(preference);
}
@@ -292,6 +307,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
public void setUserId(UserHandle userHandle) {
mUserId = userHandle.getIdentifier();
tintPreference(mPublicStoragePreference);
tintPreference(mImagesPreference);
tintPreference(mVideosPreference);
tintPreference(mAudiosPreference);
@@ -320,6 +336,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
@Override
public void displayPreference(PreferenceScreen screen) {
mScreen = screen;
mPublicStoragePreference = screen.findPreference(PUBLIC_STORAGE_KEY);
mImagesPreference = screen.findPreference(IMAGES_KEY);
mVideosPreference = screen.findPreference(VIDEOS_KEY);
mAudiosPreference = screen.findPreference(AUDIOS_KEY);
@@ -329,11 +346,8 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mSystemPreference = screen.findPreference(SYSTEM_KEY);
mTrashPreference = screen.findPreference(TRASH_KEY);
final boolean isValidVolume = isValidVolume();
setCategoryPreferencesVisibility(isValidVolume);
if (isValidVolume) {
updateCategoryPreferencesOrder();
}
updateCategoryPreferencesVisibility();
updatePrivateStorageCategoryPreferencesOrder();
}
public void onLoadFinished(SparseArray<StorageAsyncLoader.AppsStorageResult> result,
@@ -371,7 +385,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mSystemPreference.setStorageSize(systemSize, mTotalSize);
}
updateCategoryPreferencesOrder();
updatePrivateStorageCategoryPreferencesOrder();
}
public void setUsedSize(long usedSizeBytes) {
@@ -382,6 +396,13 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mTotalSize = totalSizeBytes;
}
private void launchPublicStorageIntent() {
final Intent intent = mVolume.buildBrowseIntent();
if (intent != null) {
mContext.startActivity(intent);
}
}
// TODO(b/183078080): To simplify StorageItemPreferenceController, move launchxxxIntent to a
// utility object.
private void launchImagesIntent() {

View File

@@ -104,6 +104,8 @@ public class StorageItemPreferenceControllerTest {
}
private PreferenceScreen getPreferenceScreen() {
final StorageItemPreference publicStorage = spy(new StorageItemPreference(mContext));
publicStorage.setIcon(R.drawable.ic_folder_vd_theme_24);
final StorageItemPreference images = spy(new StorageItemPreference(mContext));
images.setIcon(R.drawable.ic_photo_library);
final StorageItemPreference videos = spy(new StorageItemPreference(mContext));
@@ -122,6 +124,8 @@ public class StorageItemPreferenceControllerTest {
trash.setIcon(R.drawable.ic_trash_can);
final PreferenceScreen screen = mock(PreferenceScreen.class);
when(screen.findPreference(eq(StorageItemPreferenceController.PUBLIC_STORAGE_KEY)))
.thenReturn(publicStorage);
when(screen.findPreference(eq(StorageItemPreferenceController.IMAGES_KEY)))
.thenReturn(images);
when(screen.findPreference(eq(StorageItemPreferenceController.VIDEOS_KEY)))
@@ -148,6 +152,24 @@ public class StorageItemPreferenceControllerTest {
.isEqualTo(mContext.getString(R.string.memory_calculating_size));
}
@Test
public void launchPublicStorageIntent_nonNullBrowseIntent_settingsIntent() {
final String fakeBrowseAction = "FAKE_BROWSE_ACTION";
final Intent fakeBrowseIntent = new Intent(fakeBrowseAction);
// mContext is not the activity, add FLAG_ACTIVITY_NEW_TASK to avoid AndroidRuntimeException
// during this test.
fakeBrowseIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
when(mVolume.buildBrowseIntent()).thenReturn(fakeBrowseIntent);
mPreference.setKey(StorageItemPreferenceController.PUBLIC_STORAGE_KEY);
mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext).startActivity(argumentCaptor.capture());
final Intent intent = argumentCaptor.getValue();
assertThat(intent.getAction()).isEqualTo(fakeBrowseAction);
}
@Test
public void launchImagesIntent_resolveActionViewNull_settingsIntent() {
mPreference.setKey(StorageItemPreferenceController.IMAGES_KEY);
@@ -191,6 +213,7 @@ public class StorageItemPreferenceControllerTest {
mController.setVolume(null);
assertThat(mController.mPublicStoragePreference.isVisible()).isFalse();
assertThat(mController.mImagesPreference.isVisible()).isFalse();
assertThat(mController.mVideosPreference.isVisible()).isFalse();
assertThat(mController.mAudiosPreference.isVisible()).isFalse();
@@ -347,6 +370,7 @@ public class StorageItemPreferenceControllerTest {
mController.setUserId(new UserHandle(10));
verify(mController.mPublicStoragePreference, times(2)).setIcon(nullable(Drawable.class));
verify(mController.mImagesPreference, times(2)).setIcon(nullable(Drawable.class));
verify(mController.mVideosPreference, times(2)).setIcon(nullable(Drawable.class));
verify(mController.mAudiosPreference, times(2)).setIcon(nullable(Drawable.class));
@@ -418,4 +442,26 @@ public class StorageItemPreferenceControllerTest {
assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isTrue();
}
@Test
public void setVolume_publicStorage_showFilePreference() {
// This will hide it initially.
mController.displayPreference(mPreferenceScreen);
when(mVolume.getType()).thenReturn(VolumeInfo.TYPE_PUBLIC);
when(mVolume.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
when(mVolume.isMountedReadable()).thenReturn(true);
// And we bring it back.
mController.setVolume(mVolume);
assertThat(mController.mPublicStoragePreference.isVisible()).isTrue();
assertThat(mController.mImagesPreference.isVisible()).isFalse();
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();
}
}

View File

@@ -208,6 +208,24 @@ public class StorageEntryTest {
assertThat(privateStorage.isPrivate()).isTrue();
}
@Test
public void isPublic_prublicVolume_shouldReturnTrue() {
final VolumeInfo publicVolumeInfo = mock(VolumeInfo.class);
final StorageEntry publicStorage = new StorageEntry(mContext, publicVolumeInfo);
when(publicVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PUBLIC);
assertThat(publicStorage.isPublic()).isTrue();
}
@Test
public void isStub_stubVolume_shouldReturnTrue() {
final VolumeInfo stubVolumeInfo = mock(VolumeInfo.class);
final StorageEntry stubStorage = new StorageEntry(mContext, stubVolumeInfo);
when(stubVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_STUB);
assertThat(stubStorage.isStub()).isTrue();
}
@Test
public void isPrivate_nonVolumeInfo_shouldReturnFalse() {
final DiskInfo diskInfo = mock(DiskInfo.class);