Merge "Cache mechanism for Storage page with work profile" into tm-dev
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java
index c4ff91b..57988c5 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java
@@ -20,6 +20,7 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.os.storage.DiskInfo;
 import android.os.storage.StorageEventListener;
 import android.os.storage.StorageManager;
@@ -36,6 +37,7 @@
 import com.android.settings.deviceinfo.VolumeOptionMenuController;
 import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController;
 import com.android.settings.deviceinfo.storage.DiskInitFragment;
+import com.android.settings.deviceinfo.storage.StorageCacheHelper;
 import com.android.settings.deviceinfo.storage.StorageEntry;
 import com.android.settings.deviceinfo.storage.StorageSelectionPreferenceController;
 import com.android.settings.deviceinfo.storage.StorageUsageProgressBarPreferenceController;
@@ -71,6 +73,8 @@
     private StorageSelectionPreferenceController mStorageSelectionController;
     private StorageUsageProgressBarPreferenceController mStorageUsageProgressBarController;
     private VolumeOptionMenuController mOptionMenuController;
+    private boolean mIsLoadedFromCache;
+    private StorageCacheHelper mStorageCacheHelper;
 
     private final StorageEventListener mStorageEventListener = new StorageEventListener() {
         @Override
@@ -246,11 +250,20 @@
         }
 
         initializeOptionsMenu(activity);
+
+        if (mStorageCacheHelper.hasCachedSizeInfo()) {
+            mIsLoadedFromCache = true;
+            mStorageEntries.clear();
+            mStorageEntries.addAll(
+                    StorageUtils.getAllStorageEntries(getContext(), mStorageManager));
+            refreshUi();
+        }
     }
 
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
+        mStorageCacheHelper = new StorageCacheHelper(getContext(), UserHandle.myUserId());
         use(AutomaticStorageManagementSwitchPreferenceController.class).setFragmentManager(
                 getFragmentManager());
         mStorageSelectionController = use(StorageSelectionPreferenceController.class);
@@ -281,9 +294,14 @@
     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);
     }
 
diff --git a/src/com/android/settings/deviceinfo/StorageCategoryFragment.java b/src/com/android/settings/deviceinfo/StorageCategoryFragment.java
index c851987..efdd165 100644
--- a/src/com/android/settings/deviceinfo/StorageCategoryFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageCategoryFragment.java
@@ -39,6 +39,7 @@
 import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 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.UserIconLoader;
@@ -90,6 +91,8 @@
     private boolean mIsWorkProfile;
     private int mUserId;
     private Preference mFreeUpSpacePreference;
+    private boolean mIsLoadedFromCache;
+    private StorageCacheHelper mStorageCacheHelper;
 
     /**
      * Refresh UI for specified storageEntry.
@@ -111,14 +114,23 @@
             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);
+            if (mStorageCacheHelper.hasCachedSizeInfo()) {
+                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);
@@ -141,6 +153,15 @@
         }
 
         initializePreference();
+
+        if (mStorageCacheHelper.hasCachedSizeInfo()) {
+            mIsLoadedFromCache = true;
+            if (mSelectedStorageEntry != null) {
+                refreshUi(mSelectedStorageEntry);
+            }
+            updateSecondaryUserControllers(mSecondaryUsers, mAppsResult);
+            setSecondaryUsersVisible(true);
+        }
     }
 
     private void initializePreference() {
@@ -156,6 +177,7 @@
         mIsWorkProfile = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE)
                 == ProfileSelectFragment.ProfileType.WORK;
         mUserId = Utils.getCurrentUserId(mUserManager, mIsWorkProfile);
+        mStorageCacheHelper = new StorageCacheHelper(getContext(), mUserId);
 
         super.onAttach(context);
     }
@@ -164,12 +186,26 @@
     public void onResume() {
         super.onResume();
 
-        if (mSelectedStorageEntry != null) {
-            refreshUi(mSelectedStorageEntry);
+        if (mIsLoadedFromCache) {
+            mIsLoadedFromCache = false;
+        } else {
+            if (mSelectedStorageEntry != null) {
+                refreshUi(mSelectedStorageEntry);
+            }
         }
     }
 
     @Override
+    public void onPause() {
+        super.onPause();
+        // 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
     public void onSaveInstanceState(Bundle outState) {
         outState.putParcelable(SELECTED_STORAGE_ENTRY_KEY, mSelectedStorageEntry);
         super.onSaveInstanceState(outState);
@@ -188,6 +224,8 @@
         mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo());
         mPreferenceController.setUsedSize(privateUsedBytes);
         mPreferenceController.setTotalSize(mStorageInfo.totalBytes);
+        // Cache total size infor and used size info
+        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) {