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

Commit 8a7ffae0 authored by Daichi Hirono's avatar Daichi Hirono
Browse files

Add functions to read MTP events from MTP devices.

BUG=23368533

Change-Id: I2003dda961339677caf56e57ae90cf6df7bd7430
parent 7bafd606
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 {