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

Commit 36f1d7e3 authored by Steve McKay's avatar Steve McKay
Browse files

Move stream based EXIF support to DocsProvider

@hide for now. Basically any client with stream for a file (advised to be local resource) can get standard metadata.
In FileSystemProvider, include METADATA SUPPORTED flag for image files.

Bug: 63893154
Test: build and test interactively.
Change-Id: Idc6fecd53625b108647d66a45ac115a945a1083c
parent ca3658d0
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ import android.util.Log;
import libcore.io.IoUtils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.Objects;

@@ -632,6 +634,29 @@ public abstract class DocumentsProvider extends ContentProvider {
        throw new UnsupportedOperationException("Metadata not supported");
    }

    /**
     * Returns metadata for arbitrary file given its stream and mimetype.
     *
     * <p><b>Note: Providers should only call this with streams for locally cached resources.
     * Use of network backed streams is inadvisable for performance reasons.
     *
     * @param stream The input stream. Should be backed by locally cached content.
     *       Client retains ownership of the stream.
     * @param mimeType The mime type of the file.
     * @param tags The list of tags to load, if known. Pass null to get a default set.
     * @return Bundle containing any metadata found.
     * @throws IOException in the event of an error reading metadata.
     *
     * @hide
     */
    protected Bundle getDocumentMetadataFromStream(
            InputStream stream, String mimeType, @Nullable String[] tags)
            throws IOException {
        Bundle metadata = new Bundle();
        MetadataReader.getMetadata(metadata, stream, mimeType, tags);
        return metadata;
    }

    /**
     * Return concrete MIME type of the requested document. Must match the value
     * of {@link Document#COLUMN_MIME_TYPE} for this document. The default
@@ -685,7 +710,9 @@ public abstract class DocumentsProvider extends ContentProvider {
     * @see ParcelFileDescriptor#parseMode(String)
     */
    public abstract ParcelFileDescriptor openDocument(
            String documentId, String mode, CancellationSignal signal) throws FileNotFoundException;
            String documentId,
            String mode,
            @Nullable CancellationSignal signal) throws FileNotFoundException;

    /**
     * Open and return a thumbnail of the requested document.
+32 −19
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsProvider;
import android.provider.MediaStore;
import android.provider.MetadataReader;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
@@ -75,12 +74,9 @@ public abstract class FileSystemProvider extends DocumentsProvider {
    private Handler mHandler;

    private static final String MIMETYPE_PDF = "application/pdf";

    private static final String MIMETYPE_JPEG = "image/jpeg";

    private static final String MIMETYPE_JPG = "image/jpg";


    private static final String MIMETYPE_OCTET_STREAM = "application/octet-stream";

    protected abstract File getFileForDocId(String docId, boolean visible)
            throws FileNotFoundException;
@@ -117,23 +113,32 @@ public abstract class FileSystemProvider extends DocumentsProvider {
    public @Nullable Bundle getDocumentMetadata(String documentId, @Nullable String[] tags)
            throws FileNotFoundException {
        File file = getFileForDocId(documentId);
        if (!(file.exists() && file.isFile() && file.canRead())) {

        if (!file.exists()) {
            throw new FileNotFoundException("Can't find the file for documentId: " + documentId);
        }

        if (!file.isFile()) {
            Log.w(TAG, "Can't stream non-regular file. Returning empty metadata.");
            return Bundle.EMPTY;
        }

        if (!file.canRead()) {
            Log.w(TAG, "Can't stream non-readable file. Returning empty metadata.");
            return Bundle.EMPTY;
        }

        String filePath = file.getAbsolutePath();
        Bundle metadata = new Bundle();
        if (getTypeForFile(file).equals(MIMETYPE_JPEG)
                || getTypeForFile(file).equals(MIMETYPE_JPG)) {
        FileInputStream stream = new FileInputStream(filePath);

        try {
                MetadataReader.getMetadata(metadata, stream, getTypeForFile(file), tags);
                return metadata;
            return getDocumentMetadataFromStream(stream, getTypeForFile(file), tags);
        } catch (IOException e) {
            Log.e(TAG, "An error occurred retrieving the metadata", e);
        } finally {
            IoUtils.closeQuietly(stream);
        }
        }

        return null;
    }

@@ -468,6 +473,10 @@ public abstract class FileSystemProvider extends DocumentsProvider {
            flags |= Document.FLAG_SUPPORTS_THUMBNAIL;
        }

        if (typeSupportsMetadata(mimeType)) {
            flags |= Document.FLAG_SUPPORTS_METADATA;
        }

        final RowBuilder row = result.newRow();
        row.add(Document.COLUMN_DOCUMENT_ID, docId);
        row.add(Document.COLUMN_DISPLAY_NAME, displayName);
@@ -493,6 +502,10 @@ public abstract class FileSystemProvider extends DocumentsProvider {
        }
    }

    protected boolean typeSupportsMetadata(String mimeType) {
        return MIMETYPE_JPG.equals(mimeType) || MIMETYPE_JPEG.equals(mimeType);
    }

    private static String getTypeForName(String name) {
        final int lastDot = name.lastIndexOf('.');
        if (lastDot >= 0) {
@@ -503,7 +516,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {
            }
        }

        return "application/octet-stream";
        return MIMETYPE_OCTET_STREAM;
    }

    protected final File getFileForDocId(String docId) throws FileNotFoundException {