Loading media/mtp/MtpDevice.cpp +39 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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 media/mtp/MtpDevice.h +21 −2 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -31,6 +32,7 @@ struct usb_endpoint_descriptor; namespace android { class MtpDeviceInfo; class MtpEventPacket; class MtpObjectInfo; class MtpStorageInfo; Loading @@ -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); Loading Loading @@ -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. Loading @@ -111,7 +131,6 @@ private: bool readData(); bool writeDataHeader(MtpOperationCode operation, int dataLength); MtpResponseCode readResponse(); }; }; // namespace android Loading media/mtp/MtpEventPacket.cpp +17 −8 Original line number Diff line number Diff line Loading @@ -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 media/mtp/MtpEventPacket.h +2 −1 Original line number Diff line number Diff line Loading @@ -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(); } Loading media/mtp/MtpPacket.h +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include "MtpTypes.h" struct usb_device; struct usb_request; namespace android { Loading Loading
media/mtp/MtpDevice.cpp +39 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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
media/mtp/MtpDevice.h +21 −2 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -31,6 +32,7 @@ struct usb_endpoint_descriptor; namespace android { class MtpDeviceInfo; class MtpEventPacket; class MtpObjectInfo; class MtpStorageInfo; Loading @@ -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); Loading Loading @@ -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. Loading @@ -111,7 +131,6 @@ private: bool readData(); bool writeDataHeader(MtpOperationCode operation, int dataLength); MtpResponseCode readResponse(); }; }; // namespace android Loading
media/mtp/MtpEventPacket.cpp +17 −8 Original line number Diff line number Diff line Loading @@ -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
media/mtp/MtpEventPacket.h +2 −1 Original line number Diff line number Diff line Loading @@ -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(); } Loading
media/mtp/MtpPacket.h +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include "MtpTypes.h" struct usb_device; struct usb_request; namespace android { Loading