Merge "Storage Settings hides categories when loading" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-06-04 11:09:01 +00:00
committed by Android (Google) Code Review
11 changed files with 95 additions and 649 deletions

View File

@@ -24,8 +24,7 @@
android:order="4"
android:title="@string/storage_free_up_space_title"
android:summary="@string/storage_free_up_space_summary"
android:icon="@drawable/ic_files_go_round"
settings:allowDividerAbove="true"/>
android:icon="@drawable/ic_files_go_round"/>
<!-- Preference order 100~200 are 'ONLY' for storage category preferences below. -->
<Preference
android:key="pref_public_storage"

View File

@@ -37,7 +37,6 @@ import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper;
import com.android.settings.deviceinfo.storage.SecondaryUserController;
import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
import com.android.settings.deviceinfo.storage.StorageEntry;
@@ -54,6 +53,7 @@ import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Storage Settings main UI is composed by 3 fragments:
@@ -85,7 +85,6 @@ public class StorageCategoryFragment extends DashboardFragment
private StorageEntry mSelectedStorageEntry;
private PrivateStorageInfo mStorageInfo;
private SparseArray<StorageAsyncLoader.StorageResult> mAppsResult;
private CachedStorageValuesHelper mCachedStorageValuesHelper;
private StorageItemPreferenceController mPreferenceController;
private List<AbstractPreferenceController> mSecondaryUsers;
@@ -104,6 +103,10 @@ public class StorageCategoryFragment extends DashboardFragment
return;
}
// To prevent flicker, hides secondary users preference.
// onReceivedSizes will set it visible for private storage.
setSecondaryUsersVisible(false);
if (!mSelectedStorageEntry.isMounted()) {
// Set null volume to hide category stats.
mPreferenceController.setVolume(null);
@@ -114,6 +117,10 @@ public class StorageCategoryFragment extends DashboardFragment
mAppsResult = null;
maybeSetLoading(isQuotaSupported());
// To prevent flicker, sets null volume to hide category preferences.
// onReceivedSizes will setVolume with the volume of selected storage.
mPreferenceController.setVolume(null);
// Stats data is only available on private volumes.
getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this);
getLoaderManager()
@@ -157,7 +164,6 @@ public class StorageCategoryFragment extends DashboardFragment
@Override
public void onViewCreated(View v, Bundle savedInstanceState) {
super.onViewCreated(v, savedInstanceState);
initializeCacheProvider();
EntityHeaderController.newInstance(getActivity(), this /*fragment*/,
null /* header view */)
@@ -184,6 +190,10 @@ public class StorageCategoryFragment extends DashboardFragment
return;
}
if (getView().findViewById(R.id.loading_container).getVisibility() == View.VISIBLE) {
setLoading(false /* loading */, true /* animate */);
}
final long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes;
mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo());
mPreferenceController.setUsedSize(privateUsedBytes);
@@ -198,10 +208,7 @@ public class StorageCategoryFragment extends DashboardFragment
mPreferenceController.onLoadFinished(mAppsResult, mUserId);
updateSecondaryUserControllers(mSecondaryUsers, mAppsResult);
if (getView().findViewById(R.id.loading_container).getVisibility() == View.VISIBLE) {
setLoading(false, true);
}
setSecondaryUsersVisible(true);
}
@Override
@@ -263,7 +270,6 @@ public class StorageCategoryFragment extends DashboardFragment
public void onLoadFinished(Loader<SparseArray<StorageAsyncLoader.StorageResult>> loader,
SparseArray<StorageAsyncLoader.StorageResult> data) {
mAppsResult = data;
maybeCacheFreshValues();
onReceivedSizes();
}
@@ -286,11 +292,6 @@ public class StorageCategoryFragment extends DashboardFragment
return false;
}
@VisibleForTesting
public void setCachedStorageValuesHelper(CachedStorageValuesHelper helper) {
mCachedStorageValuesHelper = helper;
}
@VisibleForTesting
public PrivateStorageInfo getPrivateStorageInfo() {
return mStorageInfo;
@@ -311,19 +312,6 @@ public class StorageCategoryFragment extends DashboardFragment
mAppsResult = info;
}
@VisibleForTesting
void initializeCachedValues() {
final PrivateStorageInfo info = mCachedStorageValuesHelper.getCachedPrivateStorageInfo();
final SparseArray<StorageAsyncLoader.StorageResult> loaderResult =
mCachedStorageValuesHelper.getCachedStorageResult();
if (info == null || loaderResult == null) {
return;
}
mStorageInfo = info;
mAppsResult = loaderResult;
}
/**
* Activate loading UI and animation if it's necessary.
*/
@@ -337,24 +325,22 @@ public class StorageCategoryFragment extends DashboardFragment
}
}
private void initializeCacheProvider() {
mCachedStorageValuesHelper = new CachedStorageValuesHelper(getContext(), mUserId);
initializeCachedValues();
onReceivedSizes();
}
private void maybeCacheFreshValues() {
if (mStorageInfo != null && mAppsResult != null) {
mCachedStorageValuesHelper.cacheResult(mStorageInfo, mAppsResult.get(mUserId));
}
}
private boolean isQuotaSupported() {
return mSelectedStorageEntry.isMounted()
&& getActivity().getSystemService(StorageStatsManager.class)
.isQuotaSupported(mSelectedStorageEntry.getFsUuid());
}
private void setSecondaryUsersVisible(boolean visible) {
final Optional<SecondaryUserController> secondaryUserController = mSecondaryUsers.stream()
.filter(controller -> controller instanceof SecondaryUserController)
.map(controller -> (SecondaryUserController) controller)
.findAny();
if (secondaryUserController.isPresent()) {
secondaryUserController.get().setPreferenceGroupVisible(visible);
}
}
/**
* IconLoaderCallbacks exists because StorageCategoryFragment already implements
* LoaderCallbacks for a different type.
@@ -414,7 +400,6 @@ public class StorageCategoryFragment extends DashboardFragment
}
mStorageInfo = privateStorageInfo;
maybeCacheFreshValues();
onReceivedSizes();
}
}

View File

@@ -44,7 +44,6 @@ import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController;
import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper;
import com.android.settings.deviceinfo.storage.DiskInitFragment;
import com.android.settings.deviceinfo.storage.SecondaryUserController;
import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
@@ -68,6 +67,7 @@ import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/**
* Storage Settings main UI is composed by 3 fragments:
@@ -101,7 +101,6 @@ public class StorageDashboardFragment extends DashboardFragment
private StorageEntry mSelectedStorageEntry;
private PrivateStorageInfo mStorageInfo;
private SparseArray<StorageAsyncLoader.StorageResult> mAppsResult;
private CachedStorageValuesHelper mCachedStorageValuesHelper;
private StorageItemPreferenceController mPreferenceController;
private VolumeOptionMenuController mOptionMenuController;
@@ -232,6 +231,10 @@ public class StorageDashboardFragment extends DashboardFragment
mOptionMenuController.setSelectedStorageEntry(mSelectedStorageEntry);
getActivity().invalidateOptionsMenu();
// To prevent flicker, hides secondary users preference.
// onReceivedSizes will set it visible for private storage.
setSecondaryUsersVisible(false);
if (!mSelectedStorageEntry.isMounted()) {
// Set null volume to hide category stats.
mPreferenceController.setVolume(null);
@@ -242,6 +245,10 @@ public class StorageDashboardFragment extends DashboardFragment
mAppsResult = null;
maybeSetLoading(isQuotaSupported());
// To prevent flicker, sets null volume to hide category preferences.
// onReceivedSizes will setVolume with the volume of selected storage.
mPreferenceController.setVolume(null);
// Stats data is only available on private volumes.
getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this);
getLoaderManager()
@@ -316,7 +323,6 @@ public class StorageDashboardFragment extends DashboardFragment
@Override
public void onViewCreated(View v, Bundle savedInstanceState) {
super.onViewCreated(v, savedInstanceState);
initializeCacheProvider();
EntityHeaderController.newInstance(getActivity(), this /*fragment*/,
null /* header view */)
@@ -355,6 +361,10 @@ public class StorageDashboardFragment extends DashboardFragment
return;
}
if (getView().findViewById(R.id.loading_container).getVisibility() == View.VISIBLE) {
setLoading(false /* loading */, true /* animate */);
}
final long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes;
mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo());
mPreferenceController.setUsedSize(privateUsedBytes);
@@ -369,10 +379,7 @@ public class StorageDashboardFragment extends DashboardFragment
mPreferenceController.onLoadFinished(mAppsResult, mUserId);
updateSecondaryUserControllers(mSecondaryUsers, mAppsResult);
if (getView().findViewById(R.id.loading_container).getVisibility() == View.VISIBLE) {
setLoading(false, true);
}
setSecondaryUsersVisible(true);
}
@Override
@@ -463,7 +470,6 @@ public class StorageDashboardFragment extends DashboardFragment
public void onLoadFinished(Loader<SparseArray<StorageAsyncLoader.StorageResult>> loader,
SparseArray<StorageAsyncLoader.StorageResult> data) {
mAppsResult = data;
maybeCacheFreshValues();
onReceivedSizes();
}
@@ -486,11 +492,6 @@ public class StorageDashboardFragment extends DashboardFragment
return false;
}
@VisibleForTesting
public void setCachedStorageValuesHelper(CachedStorageValuesHelper helper) {
mCachedStorageValuesHelper = helper;
}
@VisibleForTesting
public PrivateStorageInfo getPrivateStorageInfo() {
return mStorageInfo;
@@ -511,19 +512,6 @@ public class StorageDashboardFragment extends DashboardFragment
mAppsResult = info;
}
@VisibleForTesting
void initializeCachedValues() {
final PrivateStorageInfo info = mCachedStorageValuesHelper.getCachedPrivateStorageInfo();
final SparseArray<StorageAsyncLoader.StorageResult> loaderResult =
mCachedStorageValuesHelper.getCachedStorageResult();
if (info == null || loaderResult == null) {
return;
}
mStorageInfo = info;
mAppsResult = loaderResult;
}
/**
* Activate loading UI and animation if it's necessary.
*/
@@ -537,24 +525,22 @@ public class StorageDashboardFragment extends DashboardFragment
}
}
private void initializeCacheProvider() {
mCachedStorageValuesHelper = new CachedStorageValuesHelper(getContext(), mUserId);
initializeCachedValues();
onReceivedSizes();
}
private void maybeCacheFreshValues() {
if (mStorageInfo != null && mAppsResult != null) {
mCachedStorageValuesHelper.cacheResult(mStorageInfo, mAppsResult.get(mUserId));
}
}
private boolean isQuotaSupported() {
return mSelectedStorageEntry.isMounted()
&& getActivity().getSystemService(StorageStatsManager.class)
.isQuotaSupported(mSelectedStorageEntry.getFsUuid());
}
private void setSecondaryUsersVisible(boolean visible) {
final Optional<SecondaryUserController> secondaryUserController = mSecondaryUsers.stream()
.filter(controller -> controller instanceof SecondaryUserController)
.map(controller -> (SecondaryUserController) controller)
.findAny();
if (secondaryUserController.isPresent()) {
secondaryUserController.get().setPreferenceGroupVisible(visible);
}
}
/**
* IconLoaderCallbacks exists because StorageDashboardFragment already implements
* LoaderCallbacks for a different type.
@@ -614,7 +600,6 @@ public class StorageDashboardFragment extends DashboardFragment
}
mStorageInfo = privateStorageInfo;
maybeCacheFreshValues();
onReceivedSizes();
}
}

View File

@@ -43,7 +43,6 @@ public class StorageItemPreference extends Preference {
public StorageItemPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.storage_item);
setSummary(R.string.memory_calculating_size);
}
public void setStorageSize(long size, long total) {

View File

@@ -1,184 +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.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings;
import android.util.SparseArray;
import androidx.annotation.VisibleForTesting;
import com.android.settingslib.applications.StorageStatsSource;
import com.android.settingslib.deviceinfo.PrivateStorageInfo;
import java.util.concurrent.TimeUnit;
public class CachedStorageValuesHelper {
@VisibleForTesting public static final String SHARED_PREFERENCES_NAME = "CachedStorageValues";
public static final String TIMESTAMP_KEY = "last_query_timestamp";
public static final String FREE_BYTES_KEY = "free_bytes";
public static final String TOTAL_BYTES_KEY = "total_bytes";
public static final String GAME_APPS_SIZE_KEY = "game_apps_size";
public static final String AUDIO_SIZE_KEY = "audio_size";
public static final String VIDEOS_SIZE_KEY = "videos_size";
public static final String IMAGES_SIZE_KEY = "images_size";
public static final String DOCUMENTS_AND_OTHER_SIZE_KEY = "documents_and_other_size";
public static final String TRASH_SIZE_KEY = "trash_size";
public static final String OTHER_APPS_SIZE_KEY = "other_apps_size";
public static final String CACHE_APPS_SIZE_KEY = "cache_apps_size";
public static final String EXTERNAL_TOTAL_BYTES = "external_total_bytes";
public static final String EXTERNAL_AUDIO_BYTES = "external_audio_bytes";
public static final String EXTERNAL_VIDEO_BYTES = "external_video_bytes";
public static final String EXTERNAL_IMAGE_BYTES = "external_image_bytes";
public static final String EXTERNAL_APP_BYTES = "external_apps_bytes";
public static final String USER_ID_KEY = "user_id";
private final Long mClobberThreshold;
private final SharedPreferences mSharedPreferences;
private final int mUserId;
// This clock is used to provide the time. By default, it uses the system clock, but can be
// replaced for test purposes.
protected Clock mClock;
public CachedStorageValuesHelper(Context context, int userId) {
mSharedPreferences =
context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mClock = new Clock();
mUserId = userId;
mClobberThreshold =
Settings.Global.getLong(
context.getContentResolver(),
Settings.Global.STORAGE_SETTINGS_CLOBBER_THRESHOLD,
TimeUnit.MINUTES.toMillis(5));
}
public PrivateStorageInfo getCachedPrivateStorageInfo() {
if (!isDataValid()) {
return null;
}
final long freeBytes = mSharedPreferences.getLong(FREE_BYTES_KEY, -1);
final long totalBytes = mSharedPreferences.getLong(TOTAL_BYTES_KEY, -1);
if (freeBytes < 0 || totalBytes < 0) {
return null;
}
return new PrivateStorageInfo(freeBytes, totalBytes);
}
/** Returns cached storage result or null if it's not available. */
public SparseArray<StorageAsyncLoader.StorageResult> getCachedStorageResult() {
if (!isDataValid()) {
return null;
}
final long gamesSize = mSharedPreferences.getLong(GAME_APPS_SIZE_KEY, -1);
final long audioSize = mSharedPreferences.getLong(AUDIO_SIZE_KEY, -1);
final long videosSize = mSharedPreferences.getLong(VIDEOS_SIZE_KEY, -1);
final long imagesSize = mSharedPreferences.getLong(IMAGES_SIZE_KEY, -1);
final long documentsAndOtherSize =
mSharedPreferences.getLong(DOCUMENTS_AND_OTHER_SIZE_KEY, -1);
final long trashSize = mSharedPreferences.getLong(TRASH_SIZE_KEY, -1);
final long allAppsExceptGamesSize = mSharedPreferences.getLong(OTHER_APPS_SIZE_KEY, -1);
final long cacheSize = mSharedPreferences.getLong(CACHE_APPS_SIZE_KEY, -1);
if (gamesSize < 0
|| audioSize < 0
|| videosSize < 0
|| imagesSize < 0
|| documentsAndOtherSize < 0
|| trashSize < 0
|| allAppsExceptGamesSize < 0
|| cacheSize < 0) {
return null;
}
final long externalTotalBytes = mSharedPreferences.getLong(EXTERNAL_TOTAL_BYTES, -1);
final long externalAudioBytes = mSharedPreferences.getLong(EXTERNAL_AUDIO_BYTES, -1);
final long externalVideoBytes = mSharedPreferences.getLong(EXTERNAL_VIDEO_BYTES, -1);
final long externalImageBytes = mSharedPreferences.getLong(EXTERNAL_IMAGE_BYTES, -1);
final long externalAppBytes = mSharedPreferences.getLong(EXTERNAL_APP_BYTES, -1);
if (externalTotalBytes < 0
|| externalAudioBytes < 0
|| externalVideoBytes < 0
|| externalImageBytes < 0
|| externalAppBytes < 0) {
return null;
}
final StorageStatsSource.ExternalStorageStats externalStats =
new StorageStatsSource.ExternalStorageStats(
externalTotalBytes,
externalAudioBytes,
externalVideoBytes,
externalImageBytes,
externalAppBytes);
final StorageAsyncLoader.StorageResult result = new StorageAsyncLoader.StorageResult();
result.gamesSize = gamesSize;
result.audioSize = audioSize;
result.videosSize = videosSize;
result.imagesSize = imagesSize;
result.documentsAndOtherSize = documentsAndOtherSize;
result.trashSize = trashSize;
result.allAppsExceptGamesSize = allAppsExceptGamesSize;
result.cacheSize = cacheSize;
result.externalStats = externalStats;
final SparseArray<StorageAsyncLoader.StorageResult> resultArray = new SparseArray<>();
resultArray.append(mUserId, result);
return resultArray;
}
public void cacheResult(
PrivateStorageInfo storageInfo, StorageAsyncLoader.StorageResult result) {
mSharedPreferences
.edit()
.putLong(FREE_BYTES_KEY, storageInfo.freeBytes)
.putLong(TOTAL_BYTES_KEY, storageInfo.totalBytes)
.putLong(GAME_APPS_SIZE_KEY, result.gamesSize)
.putLong(AUDIO_SIZE_KEY, result.audioSize)
.putLong(VIDEOS_SIZE_KEY, result.videosSize)
.putLong(IMAGES_SIZE_KEY, result.imagesSize)
.putLong(DOCUMENTS_AND_OTHER_SIZE_KEY, result.documentsAndOtherSize)
.putLong(TRASH_SIZE_KEY, result.trashSize)
.putLong(OTHER_APPS_SIZE_KEY, result.allAppsExceptGamesSize)
.putLong(CACHE_APPS_SIZE_KEY, result.cacheSize)
.putLong(EXTERNAL_TOTAL_BYTES, result.externalStats.totalBytes)
.putLong(EXTERNAL_AUDIO_BYTES, result.externalStats.audioBytes)
.putLong(EXTERNAL_VIDEO_BYTES, result.externalStats.videoBytes)
.putLong(EXTERNAL_IMAGE_BYTES, result.externalStats.imageBytes)
.putLong(EXTERNAL_APP_BYTES, result.externalStats.appBytes)
.putInt(USER_ID_KEY, mUserId)
.putLong(TIMESTAMP_KEY, mClock.getCurrentTime())
.apply();
}
private boolean isDataValid() {
final int cachedUserId = mSharedPreferences.getInt(USER_ID_KEY, -1);
if (cachedUserId != mUserId) {
return false;
}
final long lastQueryTime = mSharedPreferences.getLong(TIMESTAMP_KEY, Long.MAX_VALUE);
final long currentTime = mClock.getCurrentTime();
return currentTime - lastQueryTime < mClobberThreshold;
}
/** Clock provides the current time. */
static class Clock {
public long getCurrentTime() {
return System.currentTimeMillis();
}
}
}

View File

@@ -53,9 +53,11 @@ public class SecondaryUserController extends AbstractPreferenceController implem
UserInfo mUser;
private @Nullable
StorageItemPreference mStoragePreference;
private PreferenceGroup mPreferenceGroup;
private Drawable mUserIcon;
private long mSize;
private long mTotalSizeBytes;
private boolean mIsVisible;
/**
* Adds the appropriate controllers to a controller list for handling all secondary users on
@@ -115,16 +117,15 @@ public class SecondaryUserController extends AbstractPreferenceController implem
if (mStoragePreference == null) {
mStoragePreference = new StorageItemPreference(screen.getContext());
PreferenceGroup group =
screen.findPreference(TARGET_PREFERENCE_GROUP_KEY);
mPreferenceGroup = screen.findPreference(TARGET_PREFERENCE_GROUP_KEY);
mStoragePreference.setTitle(mUser.name);
mStoragePreference.setKey(PREFERENCE_KEY_BASE + mUser.id);
if (mSize != SIZE_NOT_SET) {
mStoragePreference.setStorageSize(mSize, mTotalSizeBytes);
}
group.setVisible(true);
group.addPreference(mStoragePreference);
mPreferenceGroup.setVisible(mIsVisible);
mPreferenceGroup.addPreference(mStoragePreference);
maybeSetIcon();
}
}
@@ -168,6 +169,18 @@ public class SecondaryUserController extends AbstractPreferenceController implem
mTotalSizeBytes = totalSizeBytes;
}
/**
* Sets visibility of the PreferenceGroup of secondary user.
*
* @param visible Visibility of the PreferenceGroup.
*/
public void setPreferenceGroupVisible(boolean visible) {
mIsVisible = visible;
if (mPreferenceGroup != null) {
mPreferenceGroup.setVisible(mIsVisible);
}
}
@Override
public void handleResult(SparseArray<StorageAsyncLoader.StorageResult> stats) {
final StorageAsyncLoader.StorageResult result = stats.get(getUser().id);

View File

@@ -221,7 +221,15 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
public void setVolume(VolumeInfo volume) {
mVolume = volume;
updateCategoryPreferencesVisibility();
if (mPublicStoragePreference != null) {
mPublicStoragePreference.setVisible(isValidPublicVolume());
}
// If isValidPrivateVolume() is true, these preferences will become visible at
// onLoadFinished.
if (!isValidPrivateVolume()) {
setPrivateStorageCategoryPreferencesVisibility(false);
}
}
// Stats data is only available on private volumes.
@@ -242,32 +250,30 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
|| mVolume.getState() == VolumeInfo.STATE_MOUNTED_READ_ONLY);
}
private void updateCategoryPreferencesVisibility() {
@VisibleForTesting
void setPrivateStorageCategoryPreferencesVisibility(boolean visible) {
if (mScreen == null) {
return;
}
mPublicStoragePreference.setVisible(isValidPublicVolume());
mImagesPreference.setVisible(visible);
mVideosPreference.setVisible(visible);
mAudioPreference.setVisible(visible);
mAppsPreference.setVisible(visible);
mGamesPreference.setVisible(visible);
mSystemPreference.setVisible(visible);
mTrashPreference.setVisible(visible);
final boolean privateStoragePreferencesVisible = isValidPrivateVolume();
mImagesPreference.setVisible(privateStoragePreferencesVisible);
mVideosPreference.setVisible(privateStoragePreferencesVisible);
mAudioPreference.setVisible(privateStoragePreferencesVisible);
mAppsPreference.setVisible(privateStoragePreferencesVisible);
mGamesPreference.setVisible(privateStoragePreferencesVisible);
mDocumentsAndOtherPreference.setVisible(privateStoragePreferencesVisible);
mSystemPreference.setVisible(privateStoragePreferencesVisible);
mTrashPreference.setVisible(privateStoragePreferencesVisible);
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.
if (sharedVolume == null || !sharedVolume.isMountedReadable()) {
if (visible) {
final VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume);
mDocumentsAndOtherPreference.setVisible(sharedVolume != null
&& sharedVolume.isMountedReadable());
} else {
mDocumentsAndOtherPreference.setVisible(false);
}
}
}
private void updatePrivateStorageCategoryPreferencesOrder() {
if (mScreen == null || !isValidPrivateVolume()) {
@@ -390,6 +396,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
}
updatePrivateStorageCategoryPreferencesOrder();
setPrivateStorageCategoryPreferencesVisibility(true);
}
public void setUsedSize(long usedSizeBytes) {

View File

@@ -33,8 +33,6 @@ import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper;
import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
import com.android.settingslib.deviceinfo.PrivateStorageInfo;
import com.android.settingslib.drawer.CategoryKey;
@@ -72,47 +70,6 @@ public class StorageDashboardFragmentTest {
verify(activity).invalidateOptionsMenu();
}
@Test
public void test_cacheProviderProvidesValuesIfBothCached() {
CachedStorageValuesHelper helper = mock(CachedStorageValuesHelper.class);
PrivateStorageInfo info = new PrivateStorageInfo(0, 0);
when(helper.getCachedPrivateStorageInfo()).thenReturn(info);
SparseArray<StorageAsyncLoader.StorageResult> result = new SparseArray<>();
when(helper.getCachedStorageResult()).thenReturn(result);
mFragment.setCachedStorageValuesHelper(helper);
mFragment.initializeCachedValues();
assertThat(mFragment.getPrivateStorageInfo()).isEqualTo(info);
assertThat(mFragment.getStorageResult()).isEqualTo(result);
}
@Test
public void test_cacheProviderDoesntProvideValuesIfAppsMissing() {
CachedStorageValuesHelper helper = mock(CachedStorageValuesHelper.class);
PrivateStorageInfo info = new PrivateStorageInfo(0, 0);
when(helper.getCachedPrivateStorageInfo()).thenReturn(info);
mFragment.setCachedStorageValuesHelper(helper);
mFragment.initializeCachedValues();
assertThat(mFragment.getPrivateStorageInfo()).isNull();
assertThat(mFragment.getStorageResult()).isNull();
}
@Test
public void test_cacheProviderDoesntProvideValuesIfVolumeInfoMissing() {
CachedStorageValuesHelper helper = mock(CachedStorageValuesHelper.class);
SparseArray<StorageAsyncLoader.StorageResult> result = new SparseArray<>();
when(helper.getCachedStorageResult()).thenReturn(result);
mFragment.setCachedStorageValuesHelper(helper);
mFragment.initializeCachedValues();
assertThat(mFragment.getPrivateStorageInfo()).isNull();
assertThat(mFragment.getStorageResult()).isNull();
}
@Test
public void test_loadWhenQuotaOffIfVolumeInfoNotLoaded() {
View fakeView = mock(View.class, RETURNS_DEEP_STUBS);

View File

@@ -45,12 +45,6 @@ public class StorageItemPreferenceTest {
mPreference = new StorageItemPreference(mContext);
}
@Test
public void testBeforeLoad() {
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getString(R.string.memory_calculating_size));
}
@Test
public void testAfterLoad() {
mPreference.setStorageSize(MEGABYTE_IN_BYTES * 10, MEGABYTE_IN_BYTES * 100);

View File

@@ -1,304 +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.deviceinfo.storage.CachedStorageValuesHelper.AUDIO_SIZE_KEY;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.CACHE_APPS_SIZE_KEY;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.DOCUMENTS_AND_OTHER_SIZE_KEY;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.EXTERNAL_APP_BYTES;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper
.EXTERNAL_AUDIO_BYTES;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper
.EXTERNAL_IMAGE_BYTES;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper
.EXTERNAL_TOTAL_BYTES;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper
.EXTERNAL_VIDEO_BYTES;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.FREE_BYTES_KEY;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.GAME_APPS_SIZE_KEY;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.IMAGES_SIZE_KEY;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.OTHER_APPS_SIZE_KEY;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper
.SHARED_PREFERENCES_NAME;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.TIMESTAMP_KEY;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.TOTAL_BYTES_KEY;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.TRASH_SIZE_KEY;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.USER_ID_KEY;
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.VIDEOS_SIZE_KEY;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.SparseArray;
import com.android.settingslib.applications.StorageStatsSource;
import com.android.settingslib.deviceinfo.PrivateStorageInfo;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class CachedStorageValuesHelperTest {
private Context mContext;
@Mock private CachedStorageValuesHelper.Clock mMockClock;
private CachedStorageValuesHelper mCachedValuesHelper;
private SharedPreferences mSharedPreferences;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mSharedPreferences = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, 0);
mCachedValuesHelper = new CachedStorageValuesHelper(mContext, 0);
mCachedValuesHelper.mClock = mMockClock;
}
@Test
public void getCachedPrivateStorageInfo_cachedValuesAreLoaded() {
when(mMockClock.getCurrentTime()).thenReturn(10001L);
mSharedPreferences
.edit()
.putLong(GAME_APPS_SIZE_KEY, 0)
.putLong(AUDIO_SIZE_KEY, 10)
.putLong(VIDEOS_SIZE_KEY, 100)
.putLong(IMAGES_SIZE_KEY, 1000)
.putLong(OTHER_APPS_SIZE_KEY, 10000)
.putLong(CACHE_APPS_SIZE_KEY, 100000)
.putLong(EXTERNAL_TOTAL_BYTES, 2)
.putLong(EXTERNAL_AUDIO_BYTES, 22)
.putLong(EXTERNAL_VIDEO_BYTES, 222)
.putLong(EXTERNAL_IMAGE_BYTES, 2222)
.putLong(EXTERNAL_APP_BYTES, 22222)
.putLong(FREE_BYTES_KEY, 1000L)
.putLong(TOTAL_BYTES_KEY, 6000L)
.putInt(USER_ID_KEY, 0)
.putLong(TIMESTAMP_KEY, 10000L)
.apply();
final PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo();
assertThat(info.freeBytes).isEqualTo(1000L);
assertThat(info.totalBytes).isEqualTo(6000L);
}
@Test
public void getCachedStorageResult_cachedValuesAreLoaded() {
when(mMockClock.getCurrentTime()).thenReturn(10001L);
mSharedPreferences
.edit()
.putLong(GAME_APPS_SIZE_KEY, 1)
.putLong(AUDIO_SIZE_KEY, 10)
.putLong(VIDEOS_SIZE_KEY, 100)
.putLong(IMAGES_SIZE_KEY, 1000)
.putLong(DOCUMENTS_AND_OTHER_SIZE_KEY, 1001)
.putLong(TRASH_SIZE_KEY, 1002)
.putLong(OTHER_APPS_SIZE_KEY, 10000)
.putLong(CACHE_APPS_SIZE_KEY, 100000)
.putLong(EXTERNAL_TOTAL_BYTES, 222222)
.putLong(EXTERNAL_AUDIO_BYTES, 22)
.putLong(EXTERNAL_VIDEO_BYTES, 222)
.putLong(EXTERNAL_IMAGE_BYTES, 2222)
.putLong(EXTERNAL_APP_BYTES, 22222)
.putLong(FREE_BYTES_KEY, 1000L)
.putLong(TOTAL_BYTES_KEY, 5000L)
.putInt(USER_ID_KEY, 0)
.putLong(TIMESTAMP_KEY, 10000L)
.apply();
final SparseArray<StorageAsyncLoader.StorageResult> result =
mCachedValuesHelper.getCachedStorageResult();
StorageAsyncLoader.StorageResult primaryResult = result.get(0);
assertThat(primaryResult.gamesSize).isEqualTo(1L);
assertThat(primaryResult.audioSize).isEqualTo(10L);
assertThat(primaryResult.videosSize).isEqualTo(100L);
assertThat(primaryResult.imagesSize).isEqualTo(1000L);
assertThat(primaryResult.documentsAndOtherSize).isEqualTo(1001L);
assertThat(primaryResult.trashSize).isEqualTo(1002L);
assertThat(primaryResult.allAppsExceptGamesSize).isEqualTo(10000L);
assertThat(primaryResult.cacheSize).isEqualTo(100000L);
assertThat(primaryResult.externalStats.totalBytes).isEqualTo(222222L);
assertThat(primaryResult.externalStats.audioBytes).isEqualTo(22L);
assertThat(primaryResult.externalStats.videoBytes).isEqualTo(222L);
assertThat(primaryResult.externalStats.imageBytes).isEqualTo(2222L);
assertThat(primaryResult.externalStats.appBytes).isEqualTo(22222L);
}
@Test
public void getCachedPrivateStorageInfo_nullIfDataIsStale() {
when(mMockClock.getCurrentTime()).thenReturn(10000000L);
mSharedPreferences
.edit()
.putLong(GAME_APPS_SIZE_KEY, 0)
.putLong(AUDIO_SIZE_KEY, 10)
.putLong(VIDEOS_SIZE_KEY, 100)
.putLong(IMAGES_SIZE_KEY, 1000)
.putLong(OTHER_APPS_SIZE_KEY, 10000)
.putLong(CACHE_APPS_SIZE_KEY, 100000)
.putLong(EXTERNAL_TOTAL_BYTES, 2)
.putLong(EXTERNAL_AUDIO_BYTES, 22)
.putLong(EXTERNAL_VIDEO_BYTES, 222)
.putLong(EXTERNAL_IMAGE_BYTES, 2222)
.putLong(EXTERNAL_APP_BYTES, 22222)
.putLong(FREE_BYTES_KEY, 1000L)
.putLong(TOTAL_BYTES_KEY, 5000L)
.putInt(USER_ID_KEY, 0)
.putLong(TIMESTAMP_KEY, 10000L)
.apply();
final PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo();
assertThat(info).isNull();
}
@Test
public void getCachedStorageResult_nullIfDataIsStale() {
when(mMockClock.getCurrentTime()).thenReturn(10000000L);
mSharedPreferences
.edit()
.putLong(GAME_APPS_SIZE_KEY, 0)
.putLong(AUDIO_SIZE_KEY, 10)
.putLong(VIDEOS_SIZE_KEY, 100)
.putLong(IMAGES_SIZE_KEY, 1000)
.putLong(OTHER_APPS_SIZE_KEY, 10000)
.putLong(CACHE_APPS_SIZE_KEY, 100000)
.putLong(EXTERNAL_TOTAL_BYTES, 2)
.putLong(EXTERNAL_AUDIO_BYTES, 22)
.putLong(EXTERNAL_VIDEO_BYTES, 222)
.putLong(EXTERNAL_IMAGE_BYTES, 2222)
.putLong(EXTERNAL_APP_BYTES, 22222)
.putLong(FREE_BYTES_KEY, 1000L)
.putLong(TOTAL_BYTES_KEY, 5000L)
.putInt(USER_ID_KEY, 0)
.putLong(TIMESTAMP_KEY, 10000L)
.apply();
final SparseArray<StorageAsyncLoader.StorageResult> result =
mCachedValuesHelper.getCachedStorageResult();
assertThat(result).isNull();
}
@Test
public void getCachedPrivateStorageInfo_nullIfWrongUser() {
when(mMockClock.getCurrentTime()).thenReturn(10001L);
mSharedPreferences
.edit()
.putLong(GAME_APPS_SIZE_KEY, 0)
.putLong(AUDIO_SIZE_KEY, 10)
.putLong(VIDEOS_SIZE_KEY, 100)
.putLong(IMAGES_SIZE_KEY, 1000)
.putLong(OTHER_APPS_SIZE_KEY, 10000)
.putLong(CACHE_APPS_SIZE_KEY, 100000)
.putLong(EXTERNAL_TOTAL_BYTES, 2)
.putLong(EXTERNAL_AUDIO_BYTES, 22)
.putLong(EXTERNAL_VIDEO_BYTES, 222)
.putLong(EXTERNAL_IMAGE_BYTES, 2222)
.putLong(EXTERNAL_APP_BYTES, 22222)
.putLong(FREE_BYTES_KEY, 1000L)
.putLong(TOTAL_BYTES_KEY, 5000L)
.putInt(USER_ID_KEY, 1)
.putLong(TIMESTAMP_KEY, 10000L)
.apply();
final PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo();
assertThat(info).isNull();
}
@Test
public void getCachedStorageResult_nullIfWrongUser() {
when(mMockClock.getCurrentTime()).thenReturn(10001L);
mSharedPreferences
.edit()
.putLong(GAME_APPS_SIZE_KEY, 0)
.putLong(AUDIO_SIZE_KEY, 10)
.putLong(VIDEOS_SIZE_KEY, 100)
.putLong(IMAGES_SIZE_KEY, 1000)
.putLong(OTHER_APPS_SIZE_KEY, 10000)
.putLong(CACHE_APPS_SIZE_KEY, 100000)
.putLong(EXTERNAL_TOTAL_BYTES, 2)
.putLong(EXTERNAL_AUDIO_BYTES, 22)
.putLong(EXTERNAL_VIDEO_BYTES, 222)
.putLong(EXTERNAL_IMAGE_BYTES, 2222)
.putLong(EXTERNAL_APP_BYTES, 22222)
.putLong(FREE_BYTES_KEY, 1000L)
.putLong(TOTAL_BYTES_KEY, 5000L)
.putInt(USER_ID_KEY, 1)
.putLong(TIMESTAMP_KEY, 10000L)
.apply();
final SparseArray<StorageAsyncLoader.StorageResult> result =
mCachedValuesHelper.getCachedStorageResult();
assertThat(result).isNull();
}
@Test
public void getCachedPrivateStorageInfo_nullIfEmpty() {
final PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo();
assertThat(info).isNull();
}
@Test
public void getCachedStorageResult_nullIfEmpty() {
final SparseArray<StorageAsyncLoader.StorageResult> result =
mCachedValuesHelper.getCachedStorageResult();
assertThat(result).isNull();
}
@Test
public void cacheResult_succeeds() {
when(mMockClock.getCurrentTime()).thenReturn(10000L);
final StorageStatsSource.ExternalStorageStats externalStats =
new StorageStatsSource.ExternalStorageStats(22222L, 2L, 20L, 200L, 2000L);
final StorageAsyncLoader.StorageResult result =
new StorageAsyncLoader.StorageResult();
result.gamesSize = 1L;
result.audioSize = 10L;
result.videosSize = 100L;
result.imagesSize = 1000L;
result.allAppsExceptGamesSize = 10000L;
result.cacheSize = 100000L;
result.externalStats = externalStats;
final PrivateStorageInfo info = new PrivateStorageInfo(1000L, 6000L);
mCachedValuesHelper.cacheResult(info, result);
assertThat(mSharedPreferences.getLong(GAME_APPS_SIZE_KEY, -1)).isEqualTo(1L);
assertThat(mSharedPreferences.getLong(AUDIO_SIZE_KEY, -1)).isEqualTo(10L);
assertThat(mSharedPreferences.getLong(VIDEOS_SIZE_KEY, -1)).isEqualTo(100L);
assertThat(mSharedPreferences.getLong(IMAGES_SIZE_KEY, -1)).isEqualTo(1000L);
assertThat(mSharedPreferences.getLong(OTHER_APPS_SIZE_KEY, -1)).isEqualTo(10000L);
assertThat(mSharedPreferences.getLong(CACHE_APPS_SIZE_KEY, -1)).isEqualTo(100000L);
assertThat(mSharedPreferences.getLong(EXTERNAL_TOTAL_BYTES, -1)).isEqualTo(22222L);
assertThat(mSharedPreferences.getLong(EXTERNAL_AUDIO_BYTES, -1)).isEqualTo(2L);
assertThat(mSharedPreferences.getLong(EXTERNAL_VIDEO_BYTES, -1)).isEqualTo(20L);
assertThat(mSharedPreferences.getLong(EXTERNAL_IMAGE_BYTES, -1)).isEqualTo(200L);
assertThat(mSharedPreferences.getLong(EXTERNAL_APP_BYTES, -1)).isEqualTo(2000L);
assertThat(mSharedPreferences.getLong(FREE_BYTES_KEY, -1)).isEqualTo(1000L);
assertThat(mSharedPreferences.getLong(TOTAL_BYTES_KEY, -1)).isEqualTo(6000L);
assertThat(mSharedPreferences.getInt(USER_ID_KEY, -1)).isEqualTo(0);
assertThat(mSharedPreferences.getLong(TIMESTAMP_KEY, -1)).isEqualTo(10000L);
}
}

View File

@@ -150,12 +150,6 @@ public class StorageItemPreferenceControllerTest {
return screen;
}
@Test
public void testUpdateStateWithInitialState() {
assertThat(mPreference.getSummary().toString())
.isEqualTo(mContext.getString(R.string.memory_calculating_size));
}
@Test
public void launchPublicStorageIntent_nonNullBrowseIntent_settingsIntent() {
final String fakeBrowseAction = "FAKE_BROWSE_ACTION";
@@ -398,16 +392,17 @@ public class StorageItemPreferenceControllerTest {
}
@Test
public void setVolume_updateFilePreferenceToHideAfterSettingVolume_hidePreference() {
public void setPrivateStorageCategoryPreferencesVisibility_updateFilePreferenceToHideAfterSettingVolume_hidePreference() {
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);
mController.displayPreference(mPreferenceScreen);
when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(null);
mController.setVolume(mVolume);
mController.setPrivateStorageCategoryPreferencesVisibility(true);
assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
}