Loading packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java +28 −2 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -130,13 +137,32 @@ 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); synchronized (sizeMap) { sizeMap.remove(size); Loading packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +21 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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); } Loading Loading @@ -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 Loading packages/DocumentsUI/tests/src/com/android/documentsui/ThumbnailCacheTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading
packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java +28 −2 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -130,13 +137,32 @@ 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); synchronized (sizeMap) { sizeMap.remove(size); Loading
packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +21 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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); } Loading Loading @@ -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 Loading
packages/DocumentsUI/tests/src/com/android/documentsui/ThumbnailCacheTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -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()); Loading