From c23be3fa162e11760a9cf41e35bae3e7efba4456 Mon Sep 17 00:00:00 2001 From: Mill Chen Date: Tue, 8 Feb 2022 15:37:53 +0800 Subject: [PATCH] Cache mechanism for Storage page - Use SharedPreference to cache the size info - Improve the flicker problem on Documents & other preference - The jobs are destroied on onPause to prevent the jobs being restarting when back to Storage page - Enable progress bar animation for each storage item Bug: 191117970 Test: manual test 1) The loading spinner will be shown when entering Storage page at first time. 2) Back to Settings homepage and switch back to Storage page, the loading spinner shouldn't be shown. 3) Click each preference in the Storage page and switch between these pages, the size info should be updated if something removed and the order of preference shouldn't be changed. Change-Id: I75533742a025dc61116207285a894ee728d0af68 Merged-In: I75533742a025dc61116207285a894ee728d0af68 (cherry picked from commit 77775a66f2004afcc8c93ac39b84d048f5dc04e9) --- .../deviceinfo/StorageDashboardFragment.java | 56 +++++++-- .../deviceinfo/StorageItemPreference.java | 2 +- .../storage/SecondaryUserController.java | 3 + .../storage/StorageCacheHelper.java | 115 ++++++++++++++++++ .../StorageItemPreferenceController.java | 112 +++++++++++------ ...eUsageProgressBarPreferenceController.java | 12 ++ .../storage/StorageCacheHelperTest.java | 97 +++++++++++++++ 7 files changed, 351 insertions(+), 46 deletions(-) create mode 100644 src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java create mode 100644 tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java index 746d2341696..cf31724ad69 100644 --- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java +++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java @@ -47,6 +47,7 @@ import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchP import com.android.settings.deviceinfo.storage.DiskInitFragment; import com.android.settings.deviceinfo.storage.SecondaryUserController; import com.android.settings.deviceinfo.storage.StorageAsyncLoader; +import com.android.settings.deviceinfo.storage.StorageCacheHelper; import com.android.settings.deviceinfo.storage.StorageEntry; import com.android.settings.deviceinfo.storage.StorageItemPreferenceController; import com.android.settings.deviceinfo.storage.StorageSelectionPreferenceController; @@ -109,6 +110,8 @@ public class StorageDashboardFragment extends DashboardFragment private boolean mIsWorkProfile; private int mUserId; private Preference mFreeUpSpacePreference; + private boolean mIsLoadedFromCache; + private StorageCacheHelper mStorageCacheHelper; private final StorageEventListener mStorageEventListener = new StorageEventListener() { @Override @@ -239,15 +242,27 @@ public class StorageDashboardFragment extends DashboardFragment mPreferenceController.setVolume(null); return; } + + if (mStorageCacheHelper.hasCachedSizeInfo() && mSelectedStorageEntry.isPrivate()) { + StorageCacheHelper.StorageCache cachedData = mStorageCacheHelper.retrieveCachedSize(); + mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo()); + mPreferenceController.setUsedSize(cachedData.usedSize); + mPreferenceController.setTotalSize(cachedData.totalSize); + } + if (mSelectedStorageEntry.isPrivate()) { mStorageInfo = null; 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); - + // Hide the loading spinner if there is cached data. + if (mStorageCacheHelper.hasCachedSizeInfo()) { + //TODO(b/220259287): apply cache mechanism to secondary user + mPreferenceController.onLoadFinished(mAppsResult, mUserId); + } else { + 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() @@ -277,6 +292,16 @@ public class StorageDashboardFragment extends DashboardFragment initializePreference(); initializeOptionsMenu(activity); + + if (mStorageCacheHelper.hasCachedSizeInfo()) { + mIsLoadedFromCache = true; + mStorageEntries.clear(); + mStorageEntries.addAll( + StorageUtils.getAllStorageEntries(getContext(), mStorageManager)); + refreshUi(); + updateSecondaryUserControllers(mSecondaryUsers, mAppsResult); + setSecondaryUsersVisible(true); + } } private void initializePreference() { @@ -291,6 +316,7 @@ public class StorageDashboardFragment extends DashboardFragment mUserManager = context.getSystemService(UserManager.class); mIsWorkProfile = false; mUserId = UserHandle.myUserId(); + mStorageCacheHelper = new StorageCacheHelper(getContext(), mUserId); super.onAttach(context); use(AutomaticStorageManagementSwitchPreferenceController.class).setFragmentManager( @@ -323,9 +349,14 @@ public class StorageDashboardFragment extends DashboardFragment public void onResume() { super.onResume(); - mStorageEntries.clear(); - mStorageEntries.addAll(StorageUtils.getAllStorageEntries(getContext(), mStorageManager)); - refreshUi(); + if (mIsLoadedFromCache) { + mIsLoadedFromCache = false; + } else { + mStorageEntries.clear(); + mStorageEntries.addAll( + StorageUtils.getAllStorageEntries(getContext(), mStorageManager)); + refreshUi(); + } mStorageManager.registerListener(mStorageEventListener); } @@ -333,6 +364,11 @@ public class StorageDashboardFragment extends DashboardFragment public void onPause() { super.onPause(); mStorageManager.unregisterListener(mStorageEventListener); + // Destroy the data loaders to prevent unnecessary data loading when switching back to the + // page. + getLoaderManager().destroyLoader(STORAGE_JOB_ID); + getLoaderManager().destroyLoader(ICON_JOB_ID); + getLoaderManager().destroyLoader(VOLUME_SIZE_JOB_ID); } @Override @@ -359,6 +395,8 @@ public class StorageDashboardFragment extends DashboardFragment mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo()); mPreferenceController.setUsedSize(privateUsedBytes); mPreferenceController.setTotalSize(mStorageInfo.totalBytes); + // Cache total size and used size + mStorageCacheHelper.cacheTotalSizeAndUsedSize(mStorageInfo.totalBytes, privateUsedBytes); for (int i = 0, size = mSecondaryUsers.size(); i < size; i++) { final AbstractPreferenceController controller = mSecondaryUsers.get(i); if (controller instanceof SecondaryUserController) { diff --git a/src/com/android/settings/deviceinfo/StorageItemPreference.java b/src/com/android/settings/deviceinfo/StorageItemPreference.java index 934ff3f603b..d3549d45061 100644 --- a/src/com/android/settings/deviceinfo/StorageItemPreference.java +++ b/src/com/android/settings/deviceinfo/StorageItemPreference.java @@ -66,7 +66,7 @@ public class StorageItemPreference extends Preference { return; mProgressBar.setMax(PROGRESS_MAX); - mProgressBar.setProgress(mProgressPercent); + mProgressBar.setProgress(mProgressPercent, true /* animate */); } @Override diff --git a/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java b/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java index f87a06a76f0..84cafd40797 100644 --- a/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java +++ b/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java @@ -183,6 +183,9 @@ public class SecondaryUserController extends AbstractPreferenceController implem @Override public void handleResult(SparseArray stats) { + if (stats == null) { + return; + } final StorageAsyncLoader.StorageResult result = stats.get(getUser().id); if (result != null) { setSize(result.externalStats.totalBytes); diff --git a/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java b/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java new file mode 100644 index 00000000000..a868c9f3f6e --- /dev/null +++ b/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2022 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; + +/** + * A utility class to cache and restore the storage size information. + */ +public class StorageCacheHelper { + + private static final String SHARED_PREFERENCE_NAME = "StorageCache"; + private static final String TOTAL_SIZE_KEY = "total_size_key"; + private static final String USED_SIZE_KEY = "used_size_key"; + private static final String IMAGES_SIZE_KEY = "images_size_key"; + private static final String VIDEOS_SIZE_KEY = "videos_size_key"; + private static final String AUDIO_SIZE_KEY = "audio_size_key"; + private static final String APPS_SIZE_KEY = "apps_size_key"; + private static final String GAMES_SIZE_KEY = "games_size_key"; + private static final String DOCUMENTS_AND_OTHER_SIZE_KEY = "documents_and_other_size_key"; + private static final String TRASH_SIZE_KEY = "trash_size_key"; + private static final String SYSTEM_SIZE_KEY = "system_size_key"; + + private final SharedPreferences mSharedPreferences; + + public StorageCacheHelper(Context context, int userId) { + String sharedPrefName = SHARED_PREFERENCE_NAME + userId; + mSharedPreferences = context.getSharedPreferences(sharedPrefName, Context.MODE_PRIVATE); + } + + /** + * Returns true if there's a cached size info. + */ + public boolean hasCachedSizeInfo() { + return mSharedPreferences.getAll().size() > 0; + } + + /** + * Cache the size info + * @param data a data about the file size info. + */ + public void cacheSizeInfo(StorageCache data) { + mSharedPreferences + .edit() + .putLong(IMAGES_SIZE_KEY, data.imagesSize) + .putLong(VIDEOS_SIZE_KEY, data.videosSize) + .putLong(AUDIO_SIZE_KEY, data.audioSize) + .putLong(APPS_SIZE_KEY, data.allAppsExceptGamesSize) + .putLong(GAMES_SIZE_KEY, data.gamesSize) + .putLong(DOCUMENTS_AND_OTHER_SIZE_KEY, data.documentsAndOtherSize) + .putLong(TRASH_SIZE_KEY, data.trashSize) + .putLong(SYSTEM_SIZE_KEY, data.systemSize) + .apply(); + } + + /** + * Cache total size and used size + */ + public void cacheTotalSizeAndUsedSize(long totalSize, long usedSize) { + mSharedPreferences + .edit() + .putLong(TOTAL_SIZE_KEY, totalSize) + .putLong(USED_SIZE_KEY, usedSize) + .apply(); + } + + /** + * Returns a cached data about all file size information. + */ + public StorageCache retrieveCachedSize() { + StorageCache result = new StorageCache(); + result.totalSize = mSharedPreferences.getLong(TOTAL_SIZE_KEY, 0); + result.usedSize = mSharedPreferences.getLong(USED_SIZE_KEY, 0); + result.imagesSize = mSharedPreferences.getLong(IMAGES_SIZE_KEY, 0); + result.videosSize = mSharedPreferences.getLong(VIDEOS_SIZE_KEY, 0); + result.audioSize = mSharedPreferences.getLong(AUDIO_SIZE_KEY, 0); + result.allAppsExceptGamesSize = mSharedPreferences.getLong(APPS_SIZE_KEY, 0); + result.gamesSize = mSharedPreferences.getLong(GAMES_SIZE_KEY, 0); + result.documentsAndOtherSize = mSharedPreferences.getLong(DOCUMENTS_AND_OTHER_SIZE_KEY, 0); + result.trashSize = mSharedPreferences.getLong(TRASH_SIZE_KEY, 0); + result.systemSize = mSharedPreferences.getLong(SYSTEM_SIZE_KEY, 0); + return result; + } + + /** + * All the cached data about the file size information. + */ + public static class StorageCache { + public long totalSize; + public long usedSize; + public long gamesSize; + public long allAppsExceptGamesSize; + public long audioSize; + public long imagesSize; + public long videosSize; + public long documentsAndOtherSize; + public long trashSize; + public long systemSize; + } +} diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java index ee0c9e75435..9813439b235 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java @@ -34,6 +34,7 @@ import android.util.Log; import android.util.SparseArray; import android.widget.Toast; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; import androidx.preference.Preference; @@ -135,7 +136,11 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle private boolean mIsWorkProfile; - private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents"; + private StorageCacheHelper mStorageCacheHelper; + // The mIsDocumentsPrefShown being used here is to prevent a flicker problem from displaying + // the Document entry. + private boolean mIsDocumentsPrefShown; + private boolean mIsPreferenceOrderedBySize; public StorageItemPreferenceController(Context context, Fragment hostFragment, VolumeInfo volume, StorageVolumeProvider svp, boolean isWorkProfile) { @@ -148,6 +153,8 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle mIsWorkProfile = isWorkProfile; mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); mUserId = getCurrentUserId(); + mIsDocumentsPrefShown = isDocumentsPrefShown(); + mStorageCacheHelper = new StorageCacheHelper(mContext, mUserId); mImagesUri = Uri.parse(context.getResources() .getString(R.string.config_images_storage_category_uri)); @@ -267,14 +274,17 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle // 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 (visible) { - final VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume); - mDocumentsAndOtherPreference.setVisible(sharedVolume != null - && sharedVolume.isMountedReadable()); + mDocumentsAndOtherPreference.setVisible(mIsDocumentsPrefShown); } else { mDocumentsAndOtherPreference.setVisible(false); } } + private boolean isDocumentsPrefShown() { + VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume); + return sharedVolume != null && sharedVolume.isMountedReadable(); + } + private void updatePrivateStorageCategoryPreferencesOrder() { if (mScreen == null || !isValidPrivateVolume()) { return; @@ -360,44 +370,74 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle mTrashPreference = screen.findPreference(TRASH_KEY); } - /** Fragments use it to set storage result and update UI of this controller. */ - public void onLoadFinished(SparseArray result, int userId) { - final StorageAsyncLoader.StorageResult data = result.get(userId); - - mImagesPreference.setStorageSize(data.imagesSize, mTotalSize); - mVideosPreference.setStorageSize(data.videosSize, mTotalSize); - mAudioPreference.setStorageSize(data.audioSize, mTotalSize); - mAppsPreference.setStorageSize(data.allAppsExceptGamesSize, mTotalSize); - mGamesPreference.setStorageSize(data.gamesSize, mTotalSize); - mDocumentsAndOtherPreference.setStorageSize(data.documentsAndOtherSize, mTotalSize); - mTrashPreference.setStorageSize(data.trashSize, mTotalSize); - + /** + * Fragments use it to set storage result and update UI of this controller. + * @param result The StorageResult from StorageAsyncLoader. This allows a nullable result. + * When it's null, the cached storage size info will be used instead. + * @param userId User ID to get the storage size info + */ + public void onLoadFinished(@Nullable SparseArray result, + int userId) { + // Calculate the size info for each category + StorageCacheHelper.StorageCache storageCache = getSizeInfo(result, userId); + // Set size info to each preference + mImagesPreference.setStorageSize(storageCache.imagesSize, mTotalSize); + mVideosPreference.setStorageSize(storageCache.videosSize, mTotalSize); + mAudioPreference.setStorageSize(storageCache.audioSize, mTotalSize); + mAppsPreference.setStorageSize(storageCache.allAppsExceptGamesSize, mTotalSize); + mGamesPreference.setStorageSize(storageCache.gamesSize, mTotalSize); + mDocumentsAndOtherPreference.setStorageSize(storageCache.documentsAndOtherSize, mTotalSize); + mTrashPreference.setStorageSize(storageCache.trashSize, mTotalSize); if (mSystemPreference != null) { - // Everything else that hasn't already been attributed is tracked as - // belonging to system. - long attributedSize = 0; - for (int i = 0; i < result.size(); i++) { - final StorageAsyncLoader.StorageResult otherData = result.valueAt(i); - attributedSize += - otherData.gamesSize - + otherData.audioSize - + otherData.videosSize - + otherData.imagesSize - + otherData.documentsAndOtherSize - + otherData.trashSize - + otherData.allAppsExceptGamesSize; - attributedSize -= otherData.duplicateCodeSize; - } - - final long systemSize = Math.max(DataUnit.GIBIBYTES.toBytes(1), - mUsedBytes - attributedSize); - mSystemPreference.setStorageSize(systemSize, mTotalSize); + mSystemPreference.setStorageSize(storageCache.systemSize, mTotalSize); + } + // Cache the size info + if (result != null) { + mStorageCacheHelper.cacheSizeInfo(storageCache); } - updatePrivateStorageCategoryPreferencesOrder(); + // Sort the preference according to size info in descending order + if (!mIsPreferenceOrderedBySize) { + updatePrivateStorageCategoryPreferencesOrder(); + mIsPreferenceOrderedBySize = true; + } setPrivateStorageCategoryPreferencesVisibility(true); } + private StorageCacheHelper.StorageCache getSizeInfo( + SparseArray result, int userId) { + if (result == null) { + return mStorageCacheHelper.retrieveCachedSize(); + } + StorageAsyncLoader.StorageResult data = result.get(userId); + StorageCacheHelper.StorageCache storageCache = new StorageCacheHelper.StorageCache(); + storageCache.imagesSize = data.imagesSize; + storageCache.videosSize = data.videosSize; + storageCache.audioSize = data.audioSize; + storageCache.allAppsExceptGamesSize = data.allAppsExceptGamesSize; + storageCache.gamesSize = data.gamesSize; + storageCache.documentsAndOtherSize = data.documentsAndOtherSize; + storageCache.trashSize = data.trashSize; + // Everything else that hasn't already been attributed is tracked as + // belonging to system. + long attributedSize = 0; + for (int i = 0; i < result.size(); i++) { + final StorageAsyncLoader.StorageResult otherData = result.valueAt(i); + attributedSize += + otherData.gamesSize + + otherData.audioSize + + otherData.videosSize + + otherData.imagesSize + + otherData.documentsAndOtherSize + + otherData.trashSize + + otherData.allAppsExceptGamesSize; + attributedSize -= otherData.duplicateCodeSize; + } + storageCache.systemSize = Math.max(DataUnit.GIBIBYTES.toBytes(1), + mUsedBytes - attributedSize); + return storageCache; + } + public void setUsedSize(long usedSizeBytes) { mUsedBytes = usedSizeBytes; } diff --git a/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java index 766035307e9..872fa8a462b 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java @@ -18,6 +18,7 @@ package com.android.settings.deviceinfo.storage; import android.app.usage.StorageStatsManager; import android.content.Context; +import android.os.UserHandle; import android.util.Log; import androidx.annotation.VisibleForTesting; @@ -47,11 +48,13 @@ public class StorageUsageProgressBarPreferenceController extends BasePreferenceC private UsageProgressBarPreference mUsageProgressBarPreference; private StorageEntry mStorageEntry; boolean mIsUpdateStateFromSelectedStorageEntry; + private StorageCacheHelper mStorageCacheHelper; public StorageUsageProgressBarPreferenceController(Context context, String key) { super(context, key); mStorageStatsManager = context.getSystemService(StorageStatsManager.class); + mStorageCacheHelper = new StorageCacheHelper(context, UserHandle.myUserId()); } /** Set StorageEntry to display. */ @@ -71,6 +74,15 @@ public class StorageUsageProgressBarPreferenceController extends BasePreferenceC } private void getStorageStatsAndUpdateUi() { + // Use cached data for both total size and used size. + if (mStorageEntry != null && mStorageEntry.isMounted() && mStorageEntry.isPrivate()) { + StorageCacheHelper.StorageCache cachedData = mStorageCacheHelper.retrieveCachedSize(); + mTotalBytes = cachedData.totalSize; + mUsedBytes = cachedData.usedSize; + mIsUpdateStateFromSelectedStorageEntry = true; + updateState(mUsageProgressBarPreference); + } + // Get the latest data from StorageStatsManager. ThreadUtils.postOnBackgroundThread(() -> { try { if (mStorageEntry == null || !mStorageEntry.isMounted()) { diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java new file mode 100644 index 00000000000..1956b09a95d --- /dev/null +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2022 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.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.os.UserHandle; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class StorageCacheHelperTest { + private static final long FAKE_IMAGES_SIZE = 7000L; + private static final long FAKE_VIDEOS_SIZE = 8900L; + private static final long FAKE_AUDIO_SIZE = 3500L; + private static final long FAKE_APPS_SIZE = 4000L; + private static final long FAKE_GAMES_SIZE = 5000L; + private static final long FAKE_DOCS_SIZE = 1500L; + private static final long FAKE_TRASH_SIZE = 500L; + private static final long FAKE_SYSTEM_SIZE = 2300L; + private static final long FAKE_TOTAL_SIZE = 256000L; + private static final long FAKE_USED_SIZE = 50000L; + + private Context mContext; + private StorageCacheHelper mHelper; + + @Before + public void setUp() { + mContext = ApplicationProvider.getApplicationContext(); + mHelper = new StorageCacheHelper(mContext, UserHandle.myUserId()); + } + + @Test + public void hasCachedSizeInfo_noCacheData_shouldReturnFalse() { + assertThat(mHelper.hasCachedSizeInfo()).isFalse(); + } + + @Test + public void hasCachedSizeInfo_hasCacheData_shouldReturnTrue() { + mHelper.cacheSizeInfo(getFakeStorageCache()); + + assertThat(mHelper.hasCachedSizeInfo()).isTrue(); + } + + @Test + public void cacheSizeInfo_shouldSaveToSharedPreference() { + mHelper.cacheSizeInfo(getFakeStorageCache()); + + StorageCacheHelper.StorageCache storageCache = mHelper.retrieveCachedSize(); + + assertThat(storageCache.imagesSize).isEqualTo(FAKE_IMAGES_SIZE); + assertThat(storageCache.totalSize).isEqualTo(0); + } + + @Test + public void cacheTotalSizeAndUsedSize_shouldSaveToSharedPreference() { + mHelper.cacheTotalSizeAndUsedSize(FAKE_TOTAL_SIZE, FAKE_USED_SIZE); + + StorageCacheHelper.StorageCache storageCache = mHelper.retrieveCachedSize(); + + assertThat(storageCache.totalSize).isEqualTo(FAKE_TOTAL_SIZE); + assertThat(storageCache.usedSize).isEqualTo(FAKE_USED_SIZE); + } + + private StorageCacheHelper.StorageCache getFakeStorageCache() { + StorageCacheHelper.StorageCache result = new StorageCacheHelper.StorageCache(); + result.trashSize = FAKE_TRASH_SIZE; + result.systemSize = FAKE_SYSTEM_SIZE; + result.imagesSize = FAKE_IMAGES_SIZE; + result.documentsAndOtherSize = FAKE_DOCS_SIZE; + result.audioSize = FAKE_AUDIO_SIZE; + result.gamesSize = FAKE_GAMES_SIZE; + result.videosSize = FAKE_VIDEOS_SIZE; + result.allAppsExceptGamesSize = FAKE_APPS_SIZE; + return result; + } +}