Add getPartialObject method to MtpDevice.
The CL adds getPartialObject operation to MtpDevice (host side
implementation).
BUG=26284424
Change-Id: Ia8f41b0ebb7dfb4572729eacb5902f21360c8db1
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index 23e432e..30843a7 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -53,12 +53,16 @@
namespace {
-bool writeToFd(void* data, int /* unused_offset */, int length, void* clientData) {
+bool writeToFd(void* data, uint32_t /* unused_offset */, uint32_t length, void* clientData) {
const int fd = *static_cast<int*>(clientData);
- return write(fd, data, length) == length;
+ const ssize_t result = write(fd, data, length);
+ if (result < 0) {
+ return false;
+ }
+ return static_cast<uint32_t>(result) == length;
}
-}
+} // namespace
MtpDevice* MtpDevice::open(const char* deviceName, int fd) {
struct usb_device *device = usb_device_new(deviceName, fd);
@@ -611,7 +615,7 @@
bool MtpDevice::readObject(MtpObjectHandle handle,
ReadObjectCallback callback,
- size_t expectedLength,
+ uint32_t expectedLength,
void* clientData) {
return readObjectInternal(handle, callback, &expectedLength, clientData);
}
@@ -643,7 +647,7 @@
bool MtpDevice::readObjectInternal(MtpObjectHandle handle,
ReadObjectCallback callback,
- const size_t* expectedLength,
+ const uint32_t* expectedLength,
void* clientData) {
Mutex::Autolock autoLock(mMutex);
@@ -654,11 +658,23 @@
return false;
}
+ return readData(callback, expectedLength, nullptr, clientData);
+}
+
+bool MtpDevice::readData(ReadObjectCallback callback,
+ const uint32_t* expectedLength,
+ uint32_t* writtenSize,
+ void* clientData) {
if (!mData.readDataHeader(mRequestIn1)) {
ALOGE("Failed to read header.");
return false;
}
+ if (mData.getContainerType() == MTP_CONTAINER_TYPE_RESPONSE) {
+ mResponse.copyFrom(mData);
+ return mResponse.getResponseCode() == MTP_RESPONSE_OK ? 0 : -1;
+ }
+
// If object size 0 byte, the remote device can reply response packet
// without sending any data packets.
if (mData.getContainerType() == MTP_CONTAINER_TYPE_RESPONSE) {
@@ -667,13 +683,16 @@
}
const uint32_t fullLength = mData.getContainerLength();
- if ((!expectedLength && fullLength < MTP_CONTAINER_HEADER_SIZE) ||
- (expectedLength && *expectedLength + MTP_CONTAINER_HEADER_SIZE != fullLength)) {
+ if (fullLength < MTP_CONTAINER_HEADER_SIZE) {
+ ALOGE("fullLength is too short: %d", fullLength);
+ return false;
+ }
+ const uint32_t length = fullLength - MTP_CONTAINER_HEADER_SIZE;
+ if (expectedLength && length != *expectedLength) {
ALOGE("readObject error length: %d", fullLength);
return false;
}
- const uint32_t length = fullLength - MTP_CONTAINER_HEADER_SIZE;
uint32_t offset = 0;
bool writingError = false;
@@ -718,8 +737,8 @@
// Queue up a read request.
const size_t remaining = length - nextOffset;
req = (req == mRequestIn1 ? mRequestIn2 : mRequestIn1);
- req->buffer_length =
- remaining > MTP_BUFFER_SIZE ? static_cast<size_t>(MTP_BUFFER_SIZE) : remaining;
+ req->buffer_length = remaining > MTP_BUFFER_SIZE ?
+ static_cast<size_t>(MTP_BUFFER_SIZE) : remaining;
if (mData.readDataAsync(req) != 0) {
ALOGE("readDataAsync failed");
return false;
@@ -736,7 +755,30 @@
offset = nextOffset;
}
- return readResponse() == MTP_RESPONSE_OK && !writingError;
+ if (writtenSize) {
+ *writtenSize = length;
+ }
+
+ return readResponse() == MTP_RESPONSE_OK;
+}
+
+bool MtpDevice::readPartialObject(MtpObjectHandle handle,
+ uint32_t offset,
+ uint32_t size,
+ uint32_t *writtenSize,
+ ReadObjectCallback callback,
+ void* clientData) {
+ Mutex::Autolock autoLock(mMutex);
+
+ mRequest.reset();
+ mRequest.setParameter(1, handle);
+ mRequest.setParameter(2, offset);
+ mRequest.setParameter(3, size);
+ if (!sendRequest(MTP_OPERATION_GET_PARTIAL_OBJECT)) {
+ ALOGE("Failed to send a read request.");
+ return false;
+ }
+ return readData(callback, NULL /* expected size */, writtenSize, clientData);
}
bool MtpDevice::sendRequest(MtpOperationCode operation) {
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index 87b3b90..60f08ba 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -68,11 +68,14 @@
Mutex mEventMutexForInterrupt;
public:
- typedef bool (*ReadObjectCallback)(void* data, int offset, int length, void* clientData);
- MtpDevice(struct usb_device* device, int interface,
- const struct usb_endpoint_descriptor *ep_in,
- const struct usb_endpoint_descriptor *ep_out,
- const struct usb_endpoint_descriptor *ep_intr);
+ typedef bool (*ReadObjectCallback)
+ (void* data, uint32_t offset, uint32_t length, void* clientData);
+
+ MtpDevice(struct usb_device* device,
+ int interface,
+ const struct usb_endpoint_descriptor *ep_in,
+ const struct usb_endpoint_descriptor *ep_out,
+ const struct usb_endpoint_descriptor *ep_intr);
static MtpDevice* open(const char* deviceName, int fd);
@@ -105,10 +108,16 @@
MtpProperty* getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format);
bool readObject(MtpObjectHandle handle, ReadObjectCallback callback,
- size_t objectSize, void* clientData);
+ uint32_t objectSize, void* clientData);
bool readObject(MtpObjectHandle handle, const char* destPath, int group,
int perm);
bool readObject(MtpObjectHandle handle, int fd);
+ bool readPartialObject(MtpObjectHandle handle,
+ uint32_t offset,
+ uint32_t size,
+ uint32_t *writtenSize,
+ ReadObjectCallback callback,
+ void* clientData);
// Starts a request to read MTP event from MTP device. It returns a request handle that
// can be used for blocking read or cancel. If other thread has already been processing an
// event returns -1.
@@ -124,8 +133,15 @@
private:
// If |objectSize| is not NULL, it checks object size before reading data bytes.
- bool readObjectInternal(MtpObjectHandle handle, ReadObjectCallback callback,
- const size_t* objectSize, void* clientData);
+ bool readObjectInternal(MtpObjectHandle handle,
+ ReadObjectCallback callback,
+ const uint32_t* objectSize,
+ void* clientData);
+ // If |objectSize| is not NULL, it checks object size before reading data bytes.
+ bool readData(ReadObjectCallback callback,
+ const uint32_t* objectSize,
+ uint32_t* writtenData,
+ void* clientData);
bool sendRequest(MtpOperationCode operation);
bool sendData();
bool readData();