Loading res/xml/storage_category_fragment.xml +1 −2 Original line number Diff line number Diff line Loading @@ -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" Loading src/com/android/settings/deviceinfo/StorageCategoryFragment.java +24 −39 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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: Loading Loading @@ -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; Loading @@ -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); Loading @@ -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() Loading Loading @@ -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 */) Loading @@ -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); Loading @@ -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 Loading Loading @@ -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(); } Loading @@ -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; Loading @@ -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. */ Loading @@ -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. Loading Loading @@ -414,7 +400,6 @@ public class StorageCategoryFragment extends DashboardFragment } mStorageInfo = privateStorageInfo; maybeCacheFreshValues(); onReceivedSizes(); } } Loading src/com/android/settings/deviceinfo/StorageDashboardFragment.java +24 −39 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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: Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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() Loading Loading @@ -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 */) Loading Loading @@ -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); Loading @@ -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 Loading Loading @@ -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(); } Loading @@ -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; Loading @@ -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. */ Loading @@ -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. Loading Loading @@ -614,7 +600,6 @@ public class StorageDashboardFragment extends DashboardFragment } mStorageInfo = privateStorageInfo; maybeCacheFreshValues(); onReceivedSizes(); } } Loading src/com/android/settings/deviceinfo/StorageItemPreference.java +0 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading src/com/android/settings/deviceinfo/storage/CachedStorageValuesHelper.javadeleted 100644 → 0 +0 −184 Original line number Diff line number Diff line /* * 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(); } } } Loading
res/xml/storage_category_fragment.xml +1 −2 Original line number Diff line number Diff line Loading @@ -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" Loading
src/com/android/settings/deviceinfo/StorageCategoryFragment.java +24 −39 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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: Loading Loading @@ -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; Loading @@ -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); Loading @@ -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() Loading Loading @@ -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 */) Loading @@ -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); Loading @@ -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 Loading Loading @@ -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(); } Loading @@ -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; Loading @@ -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. */ Loading @@ -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. Loading Loading @@ -414,7 +400,6 @@ public class StorageCategoryFragment extends DashboardFragment } mStorageInfo = privateStorageInfo; maybeCacheFreshValues(); onReceivedSizes(); } } Loading
src/com/android/settings/deviceinfo/StorageDashboardFragment.java +24 −39 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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: Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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() Loading Loading @@ -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 */) Loading Loading @@ -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); Loading @@ -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 Loading Loading @@ -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(); } Loading @@ -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; Loading @@ -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. */ Loading @@ -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. Loading Loading @@ -614,7 +600,6 @@ public class StorageDashboardFragment extends DashboardFragment } mStorageInfo = privateStorageInfo; maybeCacheFreshValues(); onReceivedSizes(); } } Loading
src/com/android/settings/deviceinfo/StorageItemPreference.java +0 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading
src/com/android/settings/deviceinfo/storage/CachedStorageValuesHelper.javadeleted 100644 → 0 +0 −184 Original line number Diff line number Diff line /* * 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(); } } }