diff options
author | Mike Lockwood <lockwood@android.com> | 2010-06-10 16:34:20 -0400 |
---|---|---|
committer | Mike Lockwood <lockwood@android.com> | 2010-06-10 16:58:03 -0400 |
commit | dda568609232cdf82a2f050b0d0727627f49d448 (patch) | |
tree | e32882418b245595dff859cee72e219eeccf4c3b | |
parent | a9aaf8ffcecf294c8da9785b5c5e1f055ee4d245 (diff) | |
download | frameworks_base-dda568609232cdf82a2f050b0d0727627f49d448.zip frameworks_base-dda568609232cdf82a2f050b0d0727627f49d448.tar.gz frameworks_base-dda568609232cdf82a2f050b0d0727627f49d448.tar.bz2 |
MTP: Add support for retrieving thumbnails to MTP content provider.
Signed-off-by: Mike Lockwood <lockwood@android.com>
-rw-r--r-- | core/java/android/provider/Mtp.java | 6 | ||||
-rw-r--r-- | media/java/android/media/MtpCursor.java | 2 | ||||
-rw-r--r-- | media/mtp/MtpCursor.cpp | 29 | ||||
-rw-r--r-- | media/mtp/MtpCursor.h | 1 | ||||
-rw-r--r-- | media/mtp/MtpDataPacket.cpp | 37 | ||||
-rw-r--r-- | media/mtp/MtpDataPacket.h | 1 | ||||
-rw-r--r-- | media/mtp/MtpDevice.cpp | 14 | ||||
-rw-r--r-- | media/mtp/MtpDevice.h | 1 |
8 files changed, 86 insertions, 5 deletions
diff --git a/core/java/android/provider/Mtp.java b/core/java/android/provider/Mtp.java index ec2698f..3906d23 100644 --- a/core/java/android/provider/Mtp.java +++ b/core/java/android/provider/Mtp.java @@ -152,6 +152,12 @@ public final class Mtp public static final String THUMB_HEIGHT = "thumb_height"; /** + * The object's thumbnail. + * <P>Type: BLOB</P> + */ + public static final String THUMB = "thumb"; + + /** * The width of the object in pixels. * <P>Type: INTEGER</P> */ diff --git a/media/java/android/media/MtpCursor.java b/media/java/android/media/MtpCursor.java index baf3c12..cf3bc09 100644 --- a/media/java/android/media/MtpCursor.java +++ b/media/java/android/media/MtpCursor.java @@ -159,6 +159,7 @@ public final class MtpCursor extends AbstractWindowedCursor { private static final int OBJECT_DATE_CREATED = 218; private static final int OBJECT_DATE_MODIFIED = 219; private static final int OBJECT_KEYWORDS = 220; + private static final int OBJECT_THUMB = 221; private static HashMap<String, Integer> sDeviceProjectionMap; private static HashMap<String, Integer> sStorageProjectionMap; @@ -196,6 +197,7 @@ public final class MtpCursor extends AbstractWindowedCursor { sObjectProjectionMap.put(Mtp.Object.DATE_CREATED, new Integer(OBJECT_DATE_CREATED)); sObjectProjectionMap.put(Mtp.Object.DATE_MODIFIED, new Integer(OBJECT_DATE_MODIFIED)); sObjectProjectionMap.put(Mtp.Object.KEYWORDS, new Integer(OBJECT_KEYWORDS)); + sObjectProjectionMap.put(Mtp.Object.THUMB, new Integer(OBJECT_THUMB)); sObjectProjectionMap.put(Mtp.Object.NAME, new Integer(OBJECT_NAME)); } diff --git a/media/mtp/MtpCursor.cpp b/media/mtp/MtpCursor.cpp index 42d9e38..d63a5bf 100644 --- a/media/mtp/MtpCursor.cpp +++ b/media/mtp/MtpCursor.cpp @@ -62,6 +62,7 @@ namespace android { #define OBJECT_DATE_CREATED 218 #define OBJECT_DATE_MODIFIED 219 #define OBJECT_KEYWORDS 220 +#define OBJECT_THUMB 221 MtpCursor::MtpCursor(MtpClient* client, int queryType, int deviceID, int storageID, int objectID, int columnCount, int* columns) @@ -364,6 +365,10 @@ bool MtpCursor::fillObject(CursorWindow* window, MtpDevice* device, if (!putString(window, objectInfo->mKeywords, row, i)) goto fail; break; + case OBJECT_THUMB: + if (!putThumbnail(window, objectID, row, i)) + goto fail; + break; default: LOGE("fillStorage: unknown column %d\n", mColumns[i]); goto fail; @@ -421,4 +426,28 @@ bool MtpCursor::putString(CursorWindow* window, const char* text, int row, int c return true; } +bool MtpCursor::putThumbnail(CursorWindow* window, int objectID, int row, int column) { + MtpDevice* device = mClient->getDevice(mDeviceID); + int size; + void* thumbnail = device->getThumbnail(objectID, size); + + LOGD("putThumbnail: %p, size: %d\n", thumbnail, size); + int offset = window->alloc(size); + if (!offset) { + window->freeLastRow(); + LOGE("Failed allocating %u bytes for thumbnail", size); + return false; + } + if (size > 0) + window->copyIn(offset, (const uint8_t*)thumbnail, size); + + // This must be updated after the call to alloc(), since that + // may move the field around in the window + field_slot_t * fieldSlot = window->getFieldSlot(row, column); + fieldSlot->type = FIELD_TYPE_BLOB; + fieldSlot->data.buffer.offset = offset; + fieldSlot->data.buffer.size = size; + return true; +} + } // namespace android diff --git a/media/mtp/MtpCursor.h b/media/mtp/MtpCursor.h index 422f0c9..d51c052 100644 --- a/media/mtp/MtpCursor.h +++ b/media/mtp/MtpCursor.h @@ -68,6 +68,7 @@ private: bool prepareRow(CursorWindow* window); bool putLong(CursorWindow* window, int value, int row, int column); bool putString(CursorWindow* window, const char* text, int row, int column); + bool putThumbnail(CursorWindow* window, int objectID, int row, int column); }; }; // namespace android diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp index f96284c..d12425a 100644 --- a/media/mtp/MtpDataPacket.cpp +++ b/media/mtp/MtpDataPacket.cpp @@ -361,11 +361,24 @@ int MtpDataPacket::writeDataHeader(int fd, uint32_t length) { #ifdef MTP_HOST int MtpDataPacket::read(struct usb_endpoint *ep) { // first read the header - int ret = transfer(ep, mBuffer, mBufferSize); -printf("MtpDataPacket::transfer returned %d\n", ret); - if (ret >= 0) - mPacketSize = ret; - return ret; + int length = transfer(ep, mBuffer, mBufferSize); + if (length > MTP_CONTAINER_HEADER_SIZE) { + // look at the length field to see if the data spans multiple packets + uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET); + while (totalLength > length) { + allocate(length + mAllocationIncrement); + int ret = transfer(ep, mBuffer + length, mAllocationIncrement); + if (ret >= 0) + length += ret; + else { + length = ret; + break; + } + } + } + if (length >= 0) + mPacketSize = length; + return length; } int MtpDataPacket::write(struct usb_endpoint *ep) { @@ -382,4 +395,18 @@ int MtpDataPacket::write(struct usb_endpoint *ep) { #endif // MTP_HOST +void* MtpDataPacket::getData(int& outLength) const { + int length = mPacketSize - MTP_CONTAINER_HEADER_SIZE; + if (length > 0) { + void* result = malloc(length); + if (result) { + memcpy(result, mBuffer + MTP_CONTAINER_HEADER_SIZE, length); + outLength = length; + return result; + } + } + outLength = 0; + return NULL; +} + } // namespace android diff --git a/media/mtp/MtpDataPacket.h b/media/mtp/MtpDataPacket.h index 4e743b2..146ef64 100644 --- a/media/mtp/MtpDataPacket.h +++ b/media/mtp/MtpDataPacket.h @@ -99,6 +99,7 @@ public: #endif inline bool hasData() const { return mPacketSize > MTP_CONTAINER_HEADER_SIZE; } + void* getData(int& outLength) const; }; }; // namespace android diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp index 5c39628..ee35217 100644 --- a/media/mtp/MtpDevice.cpp +++ b/media/mtp/MtpDevice.cpp @@ -194,6 +194,20 @@ MtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) { return NULL; } +void* MtpDevice::getThumbnail(MtpObjectHandle handle, int& outLength) { + mRequest.reset(); + mRequest.setParameter(1, handle); + if (sendRequest(MTP_OPERATION_GET_THUMB) && readData()) { + MtpResponseCode ret = readResponse(); + if (ret == MTP_RESPONSE_OK) { + return mData.getData(outLength); + } + } + outLength = 0; + return NULL; + +} + MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) { mRequest.reset(); mRequest.setParameter(1, code); diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h index 226b247..0ee930f 100644 --- a/media/mtp/MtpDevice.h +++ b/media/mtp/MtpDevice.h @@ -70,6 +70,7 @@ public: MtpStorageInfo* getStorageInfo(MtpStorageID storageID); MtpObjectHandleList* getObjectHandles(MtpStorageID storageID, MtpObjectFormat format, MtpObjectHandle parent); MtpObjectInfo* getObjectInfo(MtpObjectHandle handle); + void* getThumbnail(MtpObjectHandle handle, int& outLength); MtpProperty* getDevicePropDesc(MtpDeviceProperty code); |