Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f897037a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Open archives in different modes separately."

parents 8431311c 777efaea
Loading
Loading
Loading
Loading
+43 −9
Original line number Diff line number Diff line
@@ -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;

/**
@@ -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 {
@@ -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(
@@ -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);
        }
    }
}