MTP: Remove an unnecessary thread from the MtpClient class.
Now a single thread is used for passing USB host events up to MtpClient.
Change-Id: I0e3a277956cb3d1036da122ea10acb03a27844d6
Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/media/mtp/MtpClient.cpp b/media/mtp/MtpClient.cpp
index fbf1c77..b4c47af 100644
--- a/media/mtp/MtpClient.cpp
+++ b/media/mtp/MtpClient.cpp
@@ -27,6 +27,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
+#include <utils/threads.h>
#include <usbhost/usbhost.h>
#include <linux/version.h>
@@ -38,34 +39,59 @@
namespace android {
+class MtpClientThread : public Thread {
+private:
+ MtpClient* mClient;
+
+public:
+ MtpClientThread(MtpClient* client)
+ : mClient(client)
+ {
+ }
+
+ virtual bool threadLoop() {
+ return mClient->threadLoop();
+ }
+};
+
+
MtpClient::MtpClient()
- : mStarted(false)
+ : mThread(NULL),
+ mUsbHostContext(NULL),
+ mDone(false)
{
}
MtpClient::~MtpClient() {
+ usb_host_cleanup(mUsbHostContext);
}
bool MtpClient::start() {
- if (mStarted)
+ if (mThread)
return true;
- if (usb_host_init(usb_device_added, usb_device_removed, this)) {
- LOGE("MtpClient::start failed\n");
+ mUsbHostContext = usb_host_init();
+ if (!mUsbHostContext)
return false;
- }
- mStarted = true;
+
+ mThread = new MtpClientThread(this);
+ mThread->run("MtpClientThread");
+
return true;
}
-void MtpClient::usbDeviceAdded(const char *devname) {
+void MtpClient::stop() {
+ mDone = true;
+}
+
+bool MtpClient::usbDeviceAdded(const char *devname) {
struct usb_descriptor_header* desc;
struct usb_descriptor_iter iter;
struct usb_device *device = usb_device_open(devname);
if (!device) {
LOGE("usb_device_open failed\n");
- return;
+ return mDone;
}
usb_descriptor_iter_init(device, &iter);
@@ -90,7 +116,7 @@
ep = (struct usb_endpoint_descriptor *)usb_descriptor_iter_next(&iter);
if (!ep || ep->bDescriptorType != USB_DT_ENDPOINT) {
LOGE("endpoints not found\n");
- return;
+ return mDone;
}
if (ep->bmAttributes == USB_ENDPOINT_XFER_BULK) {
if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
@@ -104,7 +130,7 @@
}
if (!ep_in_desc || !ep_out_desc || !ep_intr_desc) {
LOGE("endpoints not found\n");
- return;
+ return mDone;
}
struct usb_endpoint *ep_in = usb_endpoint_open(device, ep_in_desc);
@@ -116,7 +142,7 @@
usb_endpoint_close(ep_in);
usb_endpoint_close(ep_out);
usb_endpoint_close(ep_intr);
- return;
+ return mDone;
}
MtpDevice* mtpDevice = new MtpDevice(device, interface->bInterfaceNumber,
@@ -124,12 +150,13 @@
mDeviceList.add(mtpDevice);
mtpDevice->initialize();
deviceAdded(mtpDevice);
- return;
+ return mDone;
}
}
}
usb_device_close(device);
+ return mDone;
}
MtpDevice* MtpClient::getDevice(int id) {
@@ -141,7 +168,7 @@
return NULL;
}
-void MtpClient::usbDeviceRemoved(const char *devname) {
+bool MtpClient::usbDeviceRemoved(const char *devname) {
for (int i = 0; i < mDeviceList.size(); i++) {
MtpDevice* device = mDeviceList[i];
if (!strcmp(devname, device->getDeviceName())) {
@@ -152,16 +179,22 @@
break;
}
}
+ return mDone;
}
-void MtpClient::usb_device_added(const char *devname, void* client_data) {
+bool MtpClient::threadLoop() {
+ usb_host_run(mUsbHostContext, usb_device_added, usb_device_removed, this);
+ return false;
+}
+
+int MtpClient::usb_device_added(const char *devname, void* client_data) {
LOGD("usb_device_added %s\n", devname);
- ((MtpClient *)client_data)->usbDeviceAdded(devname);
+ return ((MtpClient *)client_data)->usbDeviceAdded(devname);
}
-void MtpClient::usb_device_removed(const char *devname, void* client_data) {
+int MtpClient::usb_device_removed(const char *devname, void* client_data) {
LOGD("usb_device_removed %s\n", devname);
- ((MtpClient *)client_data)->usbDeviceRemoved(devname);
+ return ((MtpClient *)client_data)->usbDeviceRemoved(devname);
}
} // namespace android
diff --git a/media/mtp/MtpClient.h b/media/mtp/MtpClient.h
index d87c226..907a80b 100644
--- a/media/mtp/MtpClient.h
+++ b/media/mtp/MtpClient.h
@@ -19,18 +19,25 @@
#include "MtpTypes.h"
+struct usb_host_context;
+
namespace android {
+class MtpClientThread;
+
class MtpClient {
private:
- MtpDeviceList mDeviceList;
- bool mStarted;
+ MtpDeviceList mDeviceList;
+ MtpClientThread* mThread;
+ struct usb_host_context* mUsbHostContext;
+ bool mDone;
public:
MtpClient();
virtual ~MtpClient();
bool start();
+ void stop();
inline MtpDeviceList& getDeviceList() { return mDeviceList; }
MtpDevice* getDevice(int id);
@@ -40,10 +47,14 @@
virtual void deviceRemoved(MtpDevice *device) = 0;
private:
- void usbDeviceAdded(const char *devname);
- void usbDeviceRemoved(const char *devname);
- static void usb_device_added(const char *devname, void* client_data);
- static void usb_device_removed(const char *devname, void* client_data);
+ // these return true if we should stop monitoring USB and clean up
+ bool usbDeviceAdded(const char *devname);
+ bool usbDeviceRemoved(const char *devname);
+
+ friend class MtpClientThread;
+ bool threadLoop();
+ static int usb_device_added(const char *devname, void* client_data);
+ static int usb_device_removed(const char *devname, void* client_data);
};
}; // namespace android