Loading src/com/android/documentsui/archives/ArchivesProvider.java +43 −9 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.concurrent.locks.Lock; /** Loading @@ -64,10 +65,10 @@ public class ArchivesProvider extends DocumentsProvider implements Closeable { }; @GuardedBy("mArchives") private final LruCache<Uri, Loader> mArchives = new LruCache<Uri, Loader>(OPENED_ARCHIVES_CACHE_SIZE) { private final LruCache<Key, Loader> mArchives = new LruCache<Key, Loader>(OPENED_ARCHIVES_CACHE_SIZE) { @Override public void entryRemoved(boolean evicted, Uri key, public void entryRemoved(boolean evicted, Key key, Loader oldValue, Loader newValue) { oldValue.getWriteLock().lock(); try { Loading Loading @@ -274,8 +275,10 @@ public class ArchivesProvider extends DocumentsProvider implements Closeable { private Loader getInstanceUncheckedLocked(String documentId) throws FileNotFoundException { final ArchiveId id = ArchiveId.fromDocumentId(documentId); if (mArchives.get(id.mArchiveUri) != null) { return mArchives.get(id.mArchiveUri); final Key key = Key.fromArchiveId(id); final Loader existingLoader = mArchives.get(key); if (existingLoader != null) { return existingLoader; } final Cursor cursor = getContext().getContentResolver().query( Loading @@ -294,23 +297,54 @@ public class ArchivesProvider extends DocumentsProvider implements Closeable { // Remove the instance from mArchives collection once the archive file changes. if (notificationUri != null) { final LruCache<Uri, Loader> finalArchives = mArchives; final LruCache<Key, Loader> finalArchives = mArchives; getContext().getContentResolver().registerContentObserver(notificationUri, false, new ContentObserver(null) { @Override public void onChange(boolean selfChange, Uri uri) { synchronized (mArchives) { final Loader currentLoader = mArchives.get(id.mArchiveUri); final Loader currentLoader = mArchives.get(key); if (currentLoader == loader) { mArchives.remove(id.mArchiveUri); mArchives.remove(key); } } } }); } mArchives.put(id.mArchiveUri, loader); mArchives.put(key, loader); return loader; } private static class Key { Uri archiveUri; int accessMode; public Key(Uri archiveUri, int accessMode) { this.archiveUri = archiveUri; this.accessMode = accessMode; } public static Key fromArchiveId(ArchiveId id) { return new Key(id.mArchiveUri, id.mAccessMode); } @Override public boolean equals(Object other) { if (other == null) { return false; } if (!(other instanceof Key)) { return false; } return archiveUri.equals(((Key) other).archiveUri) && accessMode == ((Key) other).accessMode; } @Override public int hashCode() { return Objects.hash(archiveUri, accessMode); } } } Loading
src/com/android/documentsui/archives/ArchivesProvider.java +43 −9 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.concurrent.locks.Lock; /** Loading @@ -64,10 +65,10 @@ public class ArchivesProvider extends DocumentsProvider implements Closeable { }; @GuardedBy("mArchives") private final LruCache<Uri, Loader> mArchives = new LruCache<Uri, Loader>(OPENED_ARCHIVES_CACHE_SIZE) { private final LruCache<Key, Loader> mArchives = new LruCache<Key, Loader>(OPENED_ARCHIVES_CACHE_SIZE) { @Override public void entryRemoved(boolean evicted, Uri key, public void entryRemoved(boolean evicted, Key key, Loader oldValue, Loader newValue) { oldValue.getWriteLock().lock(); try { Loading Loading @@ -274,8 +275,10 @@ public class ArchivesProvider extends DocumentsProvider implements Closeable { private Loader getInstanceUncheckedLocked(String documentId) throws FileNotFoundException { final ArchiveId id = ArchiveId.fromDocumentId(documentId); if (mArchives.get(id.mArchiveUri) != null) { return mArchives.get(id.mArchiveUri); final Key key = Key.fromArchiveId(id); final Loader existingLoader = mArchives.get(key); if (existingLoader != null) { return existingLoader; } final Cursor cursor = getContext().getContentResolver().query( Loading @@ -294,23 +297,54 @@ public class ArchivesProvider extends DocumentsProvider implements Closeable { // Remove the instance from mArchives collection once the archive file changes. if (notificationUri != null) { final LruCache<Uri, Loader> finalArchives = mArchives; final LruCache<Key, Loader> finalArchives = mArchives; getContext().getContentResolver().registerContentObserver(notificationUri, false, new ContentObserver(null) { @Override public void onChange(boolean selfChange, Uri uri) { synchronized (mArchives) { final Loader currentLoader = mArchives.get(id.mArchiveUri); final Loader currentLoader = mArchives.get(key); if (currentLoader == loader) { mArchives.remove(id.mArchiveUri); mArchives.remove(key); } } } }); } mArchives.put(id.mArchiveUri, loader); mArchives.put(key, loader); return loader; } private static class Key { Uri archiveUri; int accessMode; public Key(Uri archiveUri, int accessMode) { this.archiveUri = archiveUri; this.accessMode = accessMode; } public static Key fromArchiveId(ArchiveId id) { return new Key(id.mArchiveUri, id.mAccessMode); } @Override public boolean equals(Object other) { if (other == null) { return false; } if (!(other instanceof Key)) { return false; } return archiveUri.equals(((Key) other).archiveUri) && accessMode == ((Key) other).accessMode; } @Override public int hashCode() { return Objects.hash(archiveUri, accessMode); } } }