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

Commit 21b4a27d authored by Steve McKay's avatar Steve McKay
Browse files

Support reading metadata from docs in archives.

Bug: 63893154
Test: Added coverage to ArchiveProviderTest.
Change-Id: I3219304b03309f84862505dfbed30caada7f22c9
parent 8d47f57a
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.storage.StorageManager;
import android.provider.DocumentsContract;
import android.provider.MetadataReader;
import android.provider.DocumentsContract.Document;
import android.support.annotation.Nullable;
import android.system.ErrnoException;
@@ -281,7 +282,10 @@ public abstract class Archive implements Closeable {
        final String mimeType = getMimeTypeForEntry(entry);
        row.add(Document.COLUMN_MIME_TYPE, mimeType);

        final int flags = mimeType.startsWith("image/") ? Document.FLAG_SUPPORTS_THUMBNAIL : 0;
        int flags = mimeType.startsWith("image/") ? Document.FLAG_SUPPORTS_THUMBNAIL : 0;
        if (MetadataReader.isSupportedMimeType(mimeType)) {
            flags |= Document.FLAG_SUPPORTS_METADATA;
        }
        row.add(Document.COLUMN_FLAGS, flags);
    }

+33 −11
Original line number Diff line number Diff line
@@ -17,38 +17,34 @@
package com.android.documentsui.archives;

import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.MatrixCursor.RowBuilder;
import android.database.MatrixCursor;
import android.database.MatrixCursor.RowBuilder;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
import android.provider.DocumentsContract;
import android.provider.DocumentsProvider;
import android.provider.MetadataReader;
import android.support.annotation.Nullable;
import android.util.Log;

import com.android.documentsui.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;

import java.io.Closeable;
import java.io.File;
import libcore.io.IoUtils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.locks.Lock;

/**
 * Provides basic implementation for creating, extracting and accessing
@@ -71,7 +67,7 @@ public class ArchivesProvider extends DocumentsProvider {
    };

    @GuardedBy("mArchives")
    private final Map<Key, Loader> mArchives = new HashMap<Key, Loader>();
    private final Map<Key, Loader> mArchives = new HashMap<>();

    @Override
    public Bundle call(String method, String arg, Bundle extras) {
@@ -152,6 +148,32 @@ public class ArchivesProvider extends DocumentsProvider {
        return loader.get().isChildDocument(parentDocumentId, documentId);
    }

    @Override
    public @Nullable Bundle getDocumentMetadata(String documentId)
            throws FileNotFoundException {

        Archive archive = getLoaderOrThrow(documentId).get();
        String mimeType = archive.getDocumentType(documentId);

        if (!MetadataReader.isSupportedMimeType(mimeType)) {
            return null;
        }

        InputStream stream = null;
        try {
            stream = new ParcelFileDescriptor.AutoCloseInputStream(
                    openDocument(documentId, "r", null));
            Bundle metadata = new Bundle();
            MetadataReader.getMetadata(metadata, stream, mimeType, null);
            return metadata;
        } catch (IOException e) {
            Log.e(TAG, "An error occurred retrieving the metadata", e);
            return null;
        } finally {
            IoUtils.closeQuietly(stream);
        }
    }

    @Override
    public Cursor queryDocument(String documentId, @Nullable String[] projection)
            throws FileNotFoundException {
+2.72 MiB

File added.

No diff preview for this file type.

+32 −1
Original line number Diff line number Diff line
@@ -28,11 +28,11 @@ import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.DocumentsContract;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
@@ -264,4 +264,35 @@ public class ArchivesProviderTest {

        client.release();
    }

    @Test
    public void testGetDocumentMetadata() throws InterruptedException, RemoteException {
        final Uri sourceUri = DocumentsContract.buildDocumentUri(
                ResourcesProvider.AUTHORITY, "images.zip");
        final Uri archiveUri = ArchivesProvider.buildUriForArchive(sourceUri,
                ParcelFileDescriptor.MODE_READ_ONLY);

        final ContentResolver resolver = mContext.getContentResolver();
        final ContentProviderClient client =
                resolver.acquireUnstableContentProviderClient(archiveUri);

        ArchivesProvider.acquireArchive(client, archiveUri);

        Uri archivedImageUri = Uri.parse(
                "content://com.android.documentsui.archives/document/content%3A%2F%2F"
                + "com.android.documentsui.archives.resourcesprovider%2F"
                + "document%2Fimages.zip%23268435456%23%2Ffreddy.jpg");

        Bundle metadata = DocumentsContract.getDocumentMetadata(client, archivedImageUri);
        assertNotNull(metadata);
        Bundle exif = metadata.getBundle(DocumentsContract.METADATA_EXIF);
        assertNotNull(exif);

        assertEquals(3036, exif.getInt(ExifInterface.TAG_IMAGE_WIDTH));
        assertEquals(4048, exif.getInt(ExifInterface.TAG_IMAGE_LENGTH));
        assertEquals("Pixel", exif.getString(ExifInterface.TAG_MODEL));

        ArchivesProvider.releaseArchive(client, archiveUri);
        client.release();
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -56,9 +56,10 @@ public class ResourcesProvider extends DocumentsProvider {
    private static final Map<String, Integer> RESOURCES = new HashMap<>();
    static {
        RESOURCES.put("archive.zip", R.raw.archive);
        RESOURCES.put("broken.zip", R.raw.broken);
        RESOURCES.put("empty_dirs.zip", R.raw.empty_dirs);
        RESOURCES.put("images.zip", R.raw.images);
        RESOURCES.put("no_dirs.zip", R.raw.no_dirs);
        RESOURCES.put("broken.zip", R.raw.broken);
    }

    private ExecutorService mExecutor = null;