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

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

Merge "Add functions to read MTP events from MTP devices."

parents 5a965bb1 8a7ffae0
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
@@ -204,7 +204,9 @@ MtpDevice::MtpDevice(struct usb_device* device, int interface,
        mDeviceInfo(NULL),
        mSessionID(0),
        mTransactionID(0),
        mReceivedResponse(false)
        mReceivedResponse(false),
        mProcessingEvent(false),
        mCurrentEventHandle(0)
{
    mRequestIn1 = usb_request_new(device, ep_in);
    mRequestIn2 = usb_request_new(device, ep_in);
@@ -794,4 +796,40 @@ MtpResponseCode MtpDevice::readResponse() {
    }
}

int MtpDevice::submitEventRequest() {
    if (mEventMutex.tryLock()) {
        // An event is being reaped on another thread.
        return -1;
    }
    if (mProcessingEvent) {
        // An event request was submitted, but no reapEventRequest called so far.
        return -1;
    }
    Mutex::Autolock autoLock(mEventMutexForInterrupt);
    mEventPacket.sendRequest(mRequestIntr);
    const int currentHandle = ++mCurrentEventHandle;
    mProcessingEvent = true;
    mEventMutex.unlock();
    return currentHandle;
}

int MtpDevice::reapEventRequest(int handle) {
    Mutex::Autolock autoLock(mEventMutex);
    if (!mProcessingEvent || mCurrentEventHandle != handle) {
        return -1;
    }
    mProcessingEvent = false;
    const int readSize = mEventPacket.readResponse(mRequestIntr->dev);
    const int result = mEventPacket.getEventCode();
    return readSize == 0 ? 0 : result;
}

void MtpDevice::discardEventRequest(int handle) {
    Mutex::Autolock autoLock(mEventMutexForInterrupt);
    if (mCurrentEventHandle != handle) {
        return;
    }
    usb_request_cancel(mRequestIntr);
}

}  // namespace android
+21 −2
Original line number Diff line number Diff line
@@ -17,8 +17,9 @@
#ifndef _MTP_DEVICE_H
#define _MTP_DEVICE_H

#include "MtpRequestPacket.h"
#include "MtpEventPacket.h"
#include "MtpDataPacket.h"
#include "MtpRequestPacket.h"
#include "MtpResponsePacket.h"
#include "MtpTypes.h"

@@ -31,6 +32,7 @@ struct usb_endpoint_descriptor;
namespace android {

class MtpDeviceInfo;
class MtpEventPacket;
class MtpObjectInfo;
class MtpStorageInfo;

@@ -53,11 +55,17 @@ private:
    MtpRequestPacket        mRequest;
    MtpDataPacket           mData;
    MtpResponsePacket       mResponse;
    MtpEventPacket          mEventPacket;

    // set to true if we received a response packet instead of a data packet
    bool                    mReceivedResponse;
    bool                    mProcessingEvent;
    int                     mCurrentEventHandle;

    // to ensure only one MTP transaction at a time
    Mutex                   mMutex;
    Mutex                   mEventMutex;
    Mutex                   mEventMutexForInterrupt;

public:
    typedef bool (*ReadObjectCallback)(void* data, int offset, int length, void* clientData);
@@ -101,6 +109,18 @@ public:
    bool                    readObject(MtpObjectHandle handle, const char* destPath, int group,
                                    int perm);
    bool                    readObject(MtpObjectHandle handle, int fd);
    // 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.
    int                     submitEventRequest();
    // Waits for MTP event from the device and returns MTP event code. It blocks the current thread
    // until it receives an event from the device. |handle| should be a request handle returned
    // by |submitEventRequest|. Returns 0 for cancellations. Returns -1 for errors.
    int                     reapEventRequest(int handle);
    // Cancels an event request. |handle| should be request handle returned by
    // |submitEventRequest|. If there is a thread blocked by |reapEventRequest| with the same
    // |handle|, the thread will resume.
    void                    discardEventRequest(int handle);

private:
    // If |objectSize| is not NULL, it checks object size before reading data bytes.
@@ -111,7 +131,6 @@ private:
    bool                    readData();
    bool                    writeDataHeader(MtpOperationCode operation, int dataLength);
    MtpResponseCode         readResponse();

};

}; // namespace android
+17 −8
Original line number Diff line number Diff line
@@ -54,17 +54,26 @@ int MtpEventPacket::write(int fd) {
#endif

#ifdef MTP_HOST
int MtpEventPacket::read(struct usb_request *request) {
int MtpEventPacket::sendRequest(struct usb_request *request) {
    request->buffer = mBuffer;
    request->buffer_length = mBufferSize;
    int ret = transfer(request);
     if (ret >= 0)
        mPacketSize = ret;
    else
    mPacketSize = 0;
    return ret;
    if (usb_request_queue(request)) {
        ALOGE("usb_endpoint_queue failed, errno: %d", errno);
        return -1;
    }
    return 0;
}

int MtpEventPacket::readResponse(struct usb_device *device) {
    struct usb_request* const req = usb_request_wait(device);
    if (req) {
        mPacketSize = req->actual_length;
        return req->actual_length;
    } else {
        return -1;
    }
}
#endif

}  // namespace android
+2 −1
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@ public:

#ifdef MTP_HOST
    // read our buffer with the given request
    int                 read(struct usb_request *request);
    int                 sendRequest(struct usb_request *request);
    int                 readResponse(struct usb_device *device);
#endif

    inline MtpEventCode     getEventCode() const { return getContainerCode(); }
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include "MtpTypes.h"

struct usb_device;
struct usb_request;

namespace android {