summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2010-06-10 16:34:20 -0400
committerMike Lockwood <lockwood@android.com>2010-06-10 16:58:03 -0400
commit3e072b354d1e1e3ee62d58492f0739139df8aff1 (patch)
tree5c1d39a97b326b210d148dfefb70832ea87e1dab /media
parentfee87d7b4e60d7541aa2cb0d31f5bdf4ca9e6475 (diff)
downloadframeworks_av-3e072b354d1e1e3ee62d58492f0739139df8aff1.zip
frameworks_av-3e072b354d1e1e3ee62d58492f0739139df8aff1.tar.gz
frameworks_av-3e072b354d1e1e3ee62d58492f0739139df8aff1.tar.bz2
MTP: Add support for retrieving thumbnails to MTP content provider.
Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'media')
-rw-r--r--media/mtp/MtpCursor.cpp29
-rw-r--r--media/mtp/MtpCursor.h1
-rw-r--r--media/mtp/MtpDataPacket.cpp37
-rw-r--r--media/mtp/MtpDataPacket.h1
-rw-r--r--media/mtp/MtpDevice.cpp14
-rw-r--r--media/mtp/MtpDevice.h1
6 files changed, 78 insertions, 5 deletions
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);