Add metadata support to MTP docs provider.

Remove convenience method from DocumentsProvider, clients to use MetadataReader directly.
Concentrate mimetype checking in MetadataReader.isSupportedType.
Update FileSystemProvider to use MetadataReader directly.

Test: Updated mtp tests. Other functioanlity manually verified.
Change-Id: Ie1e3d3092b53107f6c980c18b1451290dd2a9653
This commit is contained in:
Steve McKay
2017-08-01 15:02:50 -07:00
parent 200ae37936
commit 5a10ff1828
7 changed files with 82 additions and 58 deletions

View File

@@ -34,6 +34,7 @@ import android.mtp.MtpConstants;
import android.mtp.MtpObjectInfo;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.MetadataReader;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
@@ -900,6 +901,9 @@ class MtpDatabase {
protectionState == MtpConstants.PROTECTION_STATUS_NONE) {
flag |= Document.FLAG_DIR_SUPPORTS_CREATE;
}
if (MetadataReader.isSupportedMimeType(mimeType)) {
flag |= Document.FLAG_SUPPORTS_METADATA;
}
if (thumbnailSize > 0) {
flag |= Document.FLAG_SUPPORTS_THUMBNAIL;
}

View File

@@ -16,6 +16,7 @@
package com.android.mtp;
import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
@@ -37,11 +38,12 @@ import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.os.ProxyFileDescriptorCallback;
import android.os.storage.StorageManager;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Path;
import android.provider.DocumentsContract.Root;
import android.provider.DocumentsContract;
import android.provider.DocumentsProvider;
import android.provider.MetadataReader;
import android.provider.Settings;
import android.system.ErrnoException;
import android.system.OsConstants;
@@ -50,14 +52,16 @@ import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import libcore.io.IoUtils;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import libcore.io.IoUtils;
/**
* DocumentsProvider for MTP devices.
@@ -107,7 +111,7 @@ public class MtpDocumentsProvider extends DocumentsProvider {
mResources = getContext().getResources();
mMtpManager = new MtpManager(getContext());
mResolver = getContext().getContentResolver();
mDeviceToolkits = new HashMap<Integer, DeviceToolkit>();
mDeviceToolkits = new HashMap<>();
mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_FILE);
mRootScanner = new RootScanner(mResolver, mMtpManager, mDatabase);
mIntentSender = new ServiceIntentSender(getContext());
@@ -151,7 +155,7 @@ public class MtpDocumentsProvider extends DocumentsProvider {
mResources = resources;
mMtpManager = mtpManager;
mResolver = resolver;
mDeviceToolkits = new HashMap<Integer, DeviceToolkit>();
mDeviceToolkits = new HashMap<>();
mDatabase = database;
mRootScanner = new RootScanner(mResolver, mMtpManager, mDatabase);
mIntentSender = intentSender;
@@ -548,6 +552,29 @@ public class MtpDocumentsProvider extends DocumentsProvider {
}
}
@Override
public @Nullable Bundle getDocumentMetadata(String docId) throws FileNotFoundException {
String mimeType = getDocumentType(docId);
if (!MetadataReader.isSupportedMimeType(mimeType)) {
return null;
}
InputStream stream = null;
try {
stream = new ParcelFileDescriptor.AutoCloseInputStream(
openDocument(docId, "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);
}
}
void openDevice(int deviceId) throws IOException {
synchronized (mDeviceListLock) {
if (mDeviceToolkits.containsKey(deviceId)) {

View File

@@ -237,7 +237,8 @@ public class MtpDatabaseTest extends AndroidTestCase {
assertEquals(
COLUMN_FLAGS,
DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
DocumentsContract.Document.FLAG_SUPPORTS_WRITE,
DocumentsContract.Document.FLAG_SUPPORTS_WRITE |
DocumentsContract.Document.FLAG_SUPPORTS_METADATA,
cursor.getInt(9));
assertEquals(2 * 1024 * 1024, getInt(cursor, COLUMN_SIZE));
assertEquals(

View File

@@ -329,7 +329,8 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
assertEquals(
DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
DocumentsContract.Document.FLAG_SUPPORTS_WRITE |
DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL,
DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL |
DocumentsContract.Document.FLAG_SUPPORTS_METADATA,
cursor.getInt(4));
assertEquals(1024 * 1024 * 5, cursor.getInt(5));
}
@@ -474,7 +475,8 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
assertEquals("image/jpeg", cursor.getString(1));
assertEquals("image.jpg", cursor.getString(2));
assertEquals(0, cursor.getLong(3));
assertEquals(Document.FLAG_SUPPORTS_THUMBNAIL, cursor.getInt(4));
assertEquals(Document.FLAG_SUPPORTS_THUMBNAIL
| Document.FLAG_SUPPORTS_METADATA, cursor.getInt(4));
assertEquals(1024 * 1024 * 5, cursor.getInt(5));
cursor.close();