Merge "Update animation on storage item" into tm-dev
diff --git a/src/com/android/settings/deviceinfo/StorageItemPreference.java b/src/com/android/settings/deviceinfo/StorageItemPreference.java
index d3549d4..91102a0 100644
--- a/src/com/android/settings/deviceinfo/StorageItemPreference.java
+++ b/src/com/android/settings/deviceinfo/StorageItemPreference.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.deviceinfo;
 
+import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.widget.ProgressBar;
@@ -30,6 +32,7 @@
     public int userHandle;
 
     private static final int UNINITIALIZED = -1;
+    private static final int ANIMATE_DURATION_IN_MILLIS = 1000;
 
     private ProgressBar mProgressBar;
     private static final int PROGRESS_MAX = 100;
@@ -46,15 +49,33 @@
     }
 
     public void setStorageSize(long size, long total) {
-        mStorageSize = size;
-        setSummary(StorageUtils.getStorageSizeLabel(getContext(), size));
+        setStorageSize(size, total, false /* animate */);
+    }
 
-        if (total == 0) {
-            mProgressPercent = 0;
+    /**
+     * Set the storage size info with/without animation
+     */
+    public void setStorageSize(long size, long total, boolean animate) {
+        if (animate) {
+            TypeEvaluator<Long> longEvaluator =
+                    (fraction, startValue, endValue) -> {
+                        // Directly returns end value if fraction is 1.0 and the end value is 0.
+                        if (fraction >= 1.0f && endValue == 0) {
+                            return endValue;
+                        }
+                        return startValue + (long) (fraction * (endValue - startValue));
+                    };
+            ValueAnimator valueAnimator = ValueAnimator.ofObject(longEvaluator, mStorageSize, size);
+            valueAnimator.setDuration(ANIMATE_DURATION_IN_MILLIS);
+            valueAnimator.addUpdateListener(
+                    animation -> {
+                        updateProgressBarAndSizeInfo((long) animation.getAnimatedValue(), total);
+                    });
+            valueAnimator.start();
         } else {
-            mProgressPercent = (int)(size * PROGRESS_MAX / total);
+            updateProgressBarAndSizeInfo(size, total);
         }
-        updateProgressBar();
+        mStorageSize = size;
     }
 
     public long getStorageSize() {
@@ -62,11 +83,18 @@
     }
 
     protected void updateProgressBar() {
-        if (mProgressBar == null || mProgressPercent == UNINITIALIZED)
+        if (mProgressBar == null || mProgressPercent == UNINITIALIZED) {
             return;
+        }
 
         mProgressBar.setMax(PROGRESS_MAX);
-        mProgressBar.setProgress(mProgressPercent, true /* animate */);
+        mProgressBar.setProgress(mProgressPercent);
+    }
+
+    private void updateProgressBarAndSizeInfo(long size, long total) {
+        setSummary(StorageUtils.getStorageSizeLabel(getContext(), size));
+        mProgressPercent = total == 0 ? 0 : (int) (size * PROGRESS_MAX / total);
+        updateProgressBar();
     }
 
     @Override
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index 9813439..7e27414 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -378,18 +378,22 @@
      */
     public void onLoadFinished(@Nullable SparseArray<StorageAsyncLoader.StorageResult> result,
             int userId) {
+        // Enable animation when the storage size info is from StorageAsyncLoader whereas disable
+        // animation when the cached storage size info is used instead.
+        boolean animate = result != null && mIsPreferenceOrderedBySize;
         // 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);
+        mImagesPreference.setStorageSize(storageCache.imagesSize, mTotalSize, animate);
+        mVideosPreference.setStorageSize(storageCache.videosSize, mTotalSize, animate);
+        mAudioPreference.setStorageSize(storageCache.audioSize, mTotalSize, animate);
+        mAppsPreference.setStorageSize(storageCache.allAppsExceptGamesSize, mTotalSize, animate);
+        mGamesPreference.setStorageSize(storageCache.gamesSize, mTotalSize, animate);
+        mDocumentsAndOtherPreference.setStorageSize(storageCache.documentsAndOtherSize, mTotalSize,
+                animate);
+        mTrashPreference.setStorageSize(storageCache.trashSize, mTotalSize, animate);
         if (mSystemPreference != null) {
-            mSystemPreference.setStorageSize(storageCache.systemSize, mTotalSize);
+            mSystemPreference.setStorageSize(storageCache.systemSize, mTotalSize, animate);
         }
         // Cache the size info
         if (result != null) {
@@ -519,7 +523,7 @@
         if (mTrashPreference == null) {
             return;
         }
-        mTrashPreference.setStorageSize(0, mTotalSize);
+        mTrashPreference.setStorageSize(0, mTotalSize, true /* animate */);
         updatePrivateStorageCategoryPreferencesOrder();
     }