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

Commit 9e8a4fa7 authored by Daichi Hirono's avatar Daichi Hirono
Browse files

Change ID format of MtpDocumentsProvider.

BUG=25704562

Change-Id: I5d9fc167512eee06964650e07206e226173611b2
parent 74bfa271
Loading
Loading
Loading
Loading
+0 −91
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.mtp;

import android.content.res.Resources;
import android.database.MatrixCursor;
import android.media.MediaFile;
import android.mtp.MtpConstants;
import android.mtp.MtpObjectInfo;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;

/**
 * TODO Remove this class after we switch to use MtpDatabase.
 */
final class CursorHelper {
    static final int DUMMY_HANDLE_FOR_ROOT = 0;

    private CursorHelper() {
    }

    static void addToCursor(Resources resources, MtpRoot root, MatrixCursor.RowBuilder builder) {
        final Identifier identifier = new Identifier(
                root.mDeviceId, root.mStorageId, DUMMY_HANDLE_FOR_ROOT);
        builder.add(Document.COLUMN_DOCUMENT_ID, identifier.toDocumentId());
        builder.add(Document.COLUMN_DISPLAY_NAME, root.getRootName(resources));
        builder.add(Document.COLUMN_MIME_TYPE, DocumentsContract.Document.MIME_TYPE_DIR);
        builder.add(Document.COLUMN_LAST_MODIFIED, null);
        builder.add(Document.COLUMN_FLAGS, 0);
        builder.add(Document.COLUMN_SIZE,
                (int) Math.min(root.mMaxCapacity - root.mFreeSpace, Integer.MAX_VALUE));
    }

    static void addToCursor(MtpObjectInfo objectInfo, Identifier rootIdentifier,
            MatrixCursor.RowBuilder builder) {
        final Identifier identifier = new Identifier(
                rootIdentifier.mDeviceId, rootIdentifier.mStorageId, objectInfo.getObjectHandle());
        final String mimeType = formatTypeToMimeType(objectInfo.getFormat());

        int flag = 0;
        if (objectInfo.getProtectionStatus() == 0) {
            flag |= DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
                    DocumentsContract.Document.FLAG_SUPPORTS_WRITE;
            if (mimeType == DocumentsContract.Document.MIME_TYPE_DIR) {
                flag |= DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE;
            }
        }
        if (objectInfo.getThumbCompressedSize() > 0) {
            flag |= DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL;
        }

        builder.add(Document.COLUMN_DOCUMENT_ID, identifier.toDocumentId());
        builder.add(Document.COLUMN_DISPLAY_NAME, objectInfo.getName());
        builder.add(Document.COLUMN_MIME_TYPE, mimeType);
        builder.add(
                Document.COLUMN_LAST_MODIFIED,
                objectInfo.getDateModified() != 0 ? objectInfo.getDateModified() : null);
        builder.add(Document.COLUMN_FLAGS, flag);
        builder.add(Document.COLUMN_SIZE, objectInfo.getCompressedSize());
    }

    static String formatTypeToMimeType(int format) {
        if (format == MtpConstants.FORMAT_ASSOCIATION) {
            return DocumentsContract.Document.MIME_TYPE_DIR;
        } else {
            return MediaFile.getMimeTypeForFormatCode(format);
        }
    }

    static int mimeTypeToFormatType(String fileName, String mimeType) {
        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
            return MtpConstants.FORMAT_ASSOCIATION;
        } else {
            return MediaFile.getFormatCode(fileName, mimeType);
        }
    }
}
+4 −5
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Process;
import android.provider.DocumentsContract;
import android.util.Log;

import java.io.FileNotFoundException;
import java.io.IOException;
@@ -75,7 +74,7 @@ class DocumentLoader {
            int parentHandle = parent.mObjectHandle;
            // Need to pass the special value MtpManager.OBJECT_HANDLE_ROOT_CHILDREN to
            // getObjectHandles if we would like to obtain children under the root.
            if (parentHandle == CursorHelper.DUMMY_HANDLE_FOR_ROOT) {
            if (parentHandle == Identifier.DUMMY_HANDLE_FOR_ROOT) {
                parentHandle = MtpManager.OBJECT_HANDLE_ROOT_CHILDREN;
            }
            // TODO: Handle nit race around here.
@@ -221,8 +220,8 @@ class DocumentLoader {
                    throw new IOException(mError);
            }

            final Cursor cursor = mDatabase.queryChildDocuments(
                    columnNames, mIdentifier.mDocumentId, /* use old ID format */ true);
            final Cursor cursor =
                    mDatabase.queryChildDocuments(columnNames, mIdentifier.mDocumentId);
            cursor.setNotificationUri(resolver, createUri());
            cursor.respond(extras);

@@ -282,7 +281,7 @@ class DocumentLoader {

        private Uri createUri() {
            return DocumentsContract.buildChildDocumentsUri(
                    MtpDocumentsProvider.AUTHORITY, mIdentifier.toDocumentId());
                    MtpDocumentsProvider.AUTHORITY, mIdentifier.mDocumentId);
        }
    }
}
+5 −35
Original line number Diff line number Diff line
@@ -16,39 +16,19 @@

package com.android.mtp;

import java.util.Objects;

/**
 * Static utilities for ID.
 */
class Identifier {
    final static int DUMMY_HANDLE_FOR_ROOT = 0;

    final int mDeviceId;
    final int mStorageId;
    final int mObjectHandle;
    final String mDocumentId;

    static Identifier createFromRootId(String rootId) {
        final String[] components = rootId.split("_");
        return new Identifier(
                Integer.parseInt(components[0]),
                Integer.parseInt(components[1]));
    }

    static Identifier createFromDocumentId(String documentId) {
        final String[] components = documentId.split("_");
        return new Identifier(
                Integer.parseInt(components[0]),
                Integer.parseInt(components[1]),
                Integer.parseInt(components[2]));
    }


    Identifier(int deviceId, int storageId) {
        this(deviceId, storageId, CursorHelper.DUMMY_HANDLE_FOR_ROOT);
    }

    Identifier(int deviceId, int storageId, int objectHandle) {
        this(deviceId, storageId, objectHandle, null);
    }

    Identifier(int deviceId, int storageId, int objectHandle, String documentId) {
        mDeviceId = deviceId;
        mStorageId = storageId;
@@ -56,16 +36,6 @@ class Identifier {
        mDocumentId = documentId;
    }

    // TODO: Make the ID persistent.
    String toRootId() {
        return String.format("%d_%d", mDeviceId, mStorageId);
    }

    // TODO: Make the ID persistent.
    String toDocumentId() {
        return String.format("%d_%d_%d", mDeviceId, mStorageId, mObjectHandle);
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Identifier))
@@ -77,6 +47,6 @@ class Identifier {

    @Override
    public int hashCode() {
        return (mDeviceId << 16) ^ (mStorageId << 8) ^ mObjectHandle;
        return Objects.hash(mDeviceId, mStorageId, mObjectHandle, mDocumentId);
    }
}
+10 −28
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.media.MediaFile;
import android.mtp.MtpConstants;
import android.mtp.MtpObjectInfo;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
@@ -67,10 +69,8 @@ import java.util.Map;
 * the database tries to find corresponding rows by using document's name instead of MTP identifier
 * at the next update cycle.
 *
 * TODO: Remove @VisibleForTesting annotation when we start to use this class.
 * TODO: Improve performance by SQL optimization.
 */
@VisibleForTesting
class MtpDatabase {
    private final MtpDatabaseInternal mDatabase;

@@ -111,38 +111,21 @@ class MtpDatabase {
    /**
     * {@link MtpDatabaseInternal#queryChildDocuments}
     */
    @VisibleForTesting
    Cursor queryChildDocuments(String[] columnNames, String parentDocumentId) {
        return queryChildDocuments(columnNames, parentDocumentId, false);
    }

    @VisibleForTesting
    Cursor queryChildDocuments(String[] columnNames, String parentDocumentId, boolean useOldId) {
        final String[] newColumnNames = new String[columnNames.length];

        // TODO: Temporary replace document ID with old format.
        for (int i = 0; i < columnNames.length; i++) {
            if (useOldId && DocumentsContract.Document.COLUMN_DOCUMENT_ID.equals(columnNames[i])) {
                newColumnNames[i] = COLUMN_DEVICE_ID + " || '_' || " + COLUMN_STORAGE_ID +
                        " || '_' || IFNULL(" + COLUMN_OBJECT_HANDLE + ",0) AS " +
                        DocumentsContract.Document.COLUMN_DOCUMENT_ID;
            } else {
                newColumnNames[i] = columnNames[i];
            }
        }

        return mDatabase.queryChildDocuments(newColumnNames, parentDocumentId);
        return mDatabase.queryChildDocuments(columnNames, parentDocumentId);
    }

    /**
     * {@link MtpDatabaseInternal#queryDocument}
     */
    @VisibleForTesting
    Cursor queryDocument(String documentId, String[] projection) {
        return mDatabase.queryDocument(documentId, projection);
    }

    Identifier createIdentifier(String parentDocumentId) {
    /**
     * {@link MtpDatabaseInternal#createIdentifier}
     */
    Identifier createIdentifier(String parentDocumentId) throws FileNotFoundException {
        return mDatabase.createIdentifier(parentDocumentId);
    }

@@ -157,7 +140,6 @@ class MtpDatabase {
     * {@link MtpDatabaseInternal#getParentId}
     * @throws FileNotFoundException
     */
    @VisibleForTesting
    String getParentId(String documentId) throws FileNotFoundException {
        return mDatabase.getParentId(documentId);
    }
@@ -165,7 +147,6 @@ class MtpDatabase {
    /**
     * {@link MtpDatabaseInternal#deleteDocument}
     */
    @VisibleForTesting
    void deleteDocument(String documentId) {
        mDatabase.deleteDocument(documentId);
    }
@@ -174,7 +155,6 @@ class MtpDatabase {
     * {@link MtpDatabaseInternal#putNewDocument}
     * @throws FileNotFoundException
     */
    @VisibleForTesting
    String putNewDocument(int deviceId, String parentDocumentId, MtpObjectInfo info)
            throws FileNotFoundException {
        final ContentValues values = new ContentValues();
@@ -405,7 +385,9 @@ class MtpDatabase {
    private void getChildDocumentValues(
            ContentValues values, int deviceId, String parentId, MtpObjectInfo info) {
        values.clear();
        final String mimeType = CursorHelper.formatTypeToMimeType(info.getFormat());
        final String mimeType = info.getFormat() == MtpConstants.FORMAT_ASSOCIATION ?
                DocumentsContract.Document.MIME_TYPE_DIR :
                MediaFile.getMimeTypeForFormatCode(info.getFormat());
        int flag = 0;
        if (info.getProtectionStatus() == 0) {
            flag |= Document.FLAG_SUPPORTS_DELETE |
+0 −4
Original line number Diff line number Diff line
@@ -129,11 +129,7 @@ class MtpDatabaseConstants {
                            Root.COLUMN_TITLE + "," +
                    TABLE_DOCUMENTS + "." + Document.COLUMN_SUMMARY + " AS " +
                            Root.COLUMN_SUMMARY + "," +
                    // Temporary replace COLUMN_DOCUMENT_ID with old format.
                    TABLE_DOCUMENTS + "." + Document.COLUMN_DOCUMENT_ID + " AS " +
                    Root.COLUMN_DOCUMENT_ID + "_," +
                    TABLE_DOCUMENTS + "." + COLUMN_DEVICE_ID + "|| '_' ||" +
                    TABLE_DOCUMENTS + "." + COLUMN_STORAGE_ID + "||'_0' AS " +
                    Root.COLUMN_DOCUMENT_ID + "," +
                    TABLE_ROOT_EXTRA + "." + Root.COLUMN_AVAILABLE_BYTES + "," +
                    TABLE_ROOT_EXTRA + "." + Root.COLUMN_CAPACITY_BYTES + "," +
Loading