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

Commit 2ce504f9 authored by Daichi Hirono's avatar Daichi Hirono Committed by Android (Google) Code Review
Browse files

Merge "Add getPartialObject method to MtpDevice."

parents 56c95c9b 4a7cea88
Loading
Loading
Loading
Loading
+53 −11
Original line number Diff line number Diff line
@@ -53,13 +53,17 @@ static bool isMtpDevice(uint16_t vendor, uint16_t product) {

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);
    if (!device) {
@@ -611,7 +615,7 @@ MtpProperty* MtpDevice::getObjectPropDesc(MtpObjectProperty code, MtpObjectForma

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::readObject(MtpObjectHandle handle, int fd) {

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 @@ bool MtpDevice::readObjectInternal(MtpObjectHandle handle,
        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 @@ bool MtpDevice::readObjectInternal(MtpObjectHandle handle,
    }

    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 @@ bool MtpDevice::readObjectInternal(MtpObjectHandle handle,
            // 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 @@ bool MtpDevice::readObjectInternal(MtpObjectHandle handle,
        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) {
+24 −8
Original line number Diff line number Diff line
@@ -68,8 +68,11 @@ private:
    Mutex                   mEventMutexForInterrupt;

public:
    typedef bool (*ReadObjectCallback)(void* data, int offset, int length, void* clientData);
                            MtpDevice(struct usb_device* device, int interface,
    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);
@@ -105,10 +108,16 @@ public:
    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 @@ public:

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();