diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2016-07-25 19:23:54 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2016-07-25 19:23:56 +0000 |
commit | eadd9ca5aca0eed35f070fed6038f41e6d17ff5f (patch) | |
tree | 6e7f85da7cc442fcb617ca7e95cec64e73f125d1 | |
parent | 7068bfc3834d0cd581881972d2516fefcad136c9 (diff) | |
parent | 996aa3ba1aa930d18120f6b6d6795413b17c04d6 (diff) |
Merge "Evict thumbnail caches and delay dismissing spinner on refresh finish."
3 files changed, 61 insertions, 3 deletions
diff --git a/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java b/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java index ecde685d29c4..639d4fb4feb3 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java +++ b/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java @@ -111,6 +111,13 @@ public class ThumbnailCache { return Result.obtainMiss(); } + /** + * Puts a thumbnail for the given uri and size in to the cache. + * @param uri the uri of the thumbnail + * @param size the size of the thumbnail + * @param thumbnail the thumbnail to put in cache + * @param lastModified last modified value of the thumbnail to track its validity + */ public void putThumbnail(Uri uri, Point size, Bitmap thumbnail, long lastModified) { Pair<Uri, Point> cacheKey = Pair.create(uri, size); @@ -130,14 +137,33 @@ public class ThumbnailCache { } } + /** + * Removes all thumbnail cache associated to the given uri. + * @param uri the uri which thumbnail cache to remove + */ + public void removeUri(Uri uri) { + TreeMap<Point, Pair<Uri, Point>> sizeMap; + synchronized (mSizeIndex) { + sizeMap = mSizeIndex.get(uri); + } + + if (sizeMap != null) { + // Create an array to hold all values to avoid ConcurrentModificationException because + // removeKey() will be called by LruCache but we can't modify the map while we're + // iterating over the collection of values. + for (Pair<Uri, Point> index : sizeMap.values().toArray(new Pair[0])) { + mCache.remove(index); + } + } + } + private void removeKey(Uri uri, Point size) { TreeMap<Point, Pair<Uri, Point>> sizeMap; synchronized (mSizeIndex) { sizeMap = mSizeIndex.get(uri); } - // LruCache tells us to remove a key, which should exist, so sizeMap can't be null. - assert (sizeMap != null); + assert(sizeMap != null); synchronized (sizeMap) { sizeMap.remove(size); } diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java index 2e1b1d67e365..db19881e5c79 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -42,6 +42,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; +import android.os.Handler; import android.os.Parcelable; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Document; @@ -92,6 +93,7 @@ import com.android.documentsui.Shared; import com.android.documentsui.Snackbars; import com.android.documentsui.State; import com.android.documentsui.State.ViewMode; +import com.android.documentsui.ThumbnailCache; import com.android.documentsui.clipping.DocumentClipper; import com.android.documentsui.clipping.UrisSupplier; import com.android.documentsui.dirlist.MultiSelectManager.Selection; @@ -140,6 +142,9 @@ public class DirectoryFragment extends Fragment private static final String TAG = "DirectoryFragment"; private static final int LOADER_ID = 42; + private static final int CACHE_EVICT_LIMIT = 100; + private static final int REFRESH_SPINNER_DISMISS_DELAY = 500; + private Model mModel; private MultiSelectManager mSelectionMgr; private Model.UpdateListener mModelUpdateListener = new ModelUpdateListener(); @@ -1610,6 +1615,17 @@ public class DirectoryFragment extends Fragment @Override public void onRefresh() { + // Remove thumbnail cache. We do this not because we're worried about stale thumbnails as it + // should be covered by last modified value we store in thumbnail cache, but rather to give + // the user a greater sense that contents are being reloaded. + ThumbnailCache cache = DocumentsApplication.getThumbnailCache(getContext()); + String[] ids = mModel.getModelIds(); + int numOfEvicts = Math.min(ids.length, CACHE_EVICT_LIMIT); + for (int i = 0; i < numOfEvicts; ++i) { + cache.removeUri(mModel.getItemUri(ids[i])); + } + + // Trigger loading getLoaderManager().restartLoader(LOADER_ID, null, this); } @@ -1679,7 +1695,11 @@ public class DirectoryFragment extends Fragment mTuner.onModelLoaded(mModel, mType, mSearchMode); - mRefreshLayout.setRefreshing(false); + if (mRefreshLayout.isRefreshing()) { + new Handler().postDelayed( + () -> mRefreshLayout.setRefreshing(false), + REFRESH_SPINNER_DISMISS_DELAY); + } } @Override diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/ThumbnailCacheTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/ThumbnailCacheTest.java index dda491847591..ee6ab01c26a9 100644 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/ThumbnailCacheTest.java +++ b/packages/DocumentsUI/tests/src/com/android/documentsui/ThumbnailCacheTest.java @@ -176,6 +176,18 @@ public class ThumbnailCacheTest { assertSame(SMALL_BITMAP, result.getThumbnail()); } + @Test + public void testRemoveUri() { + mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); + mCache.putThumbnail(URI_0, SMALL_SIZE, SMALL_BITMAP, LAST_MODIFIED); + mCache.putThumbnail(URI_1, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); + + mCache.removeUri(URI_0); + + assertMiss(mCache.getThumbnail(URI_0, MID_SIZE)); + assertHitExact(mCache.getThumbnail(URI_1, MID_SIZE)); + } + private static void assertMiss(Result result) { assertEquals(Result.CACHE_MISS, result.getStatus()); assertFalse(result.isExactHit()); |