MTP: Remove race condition in initial device enumeration for host mode.

Change-Id: Iee01aaae3f8cca4234daa289bef6631da4d6c2b6
Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/media/mtp/MtpClient.cpp b/media/mtp/MtpClient.cpp
index b4c47af..8d10c27 100644
--- a/media/mtp/MtpClient.cpp
+++ b/media/mtp/MtpClient.cpp
@@ -27,7 +27,6 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
-#include <utils/threads.h>
 
 #include <usbhost/usbhost.h>
 #include <linux/version.h>
@@ -67,6 +66,8 @@
 }
 
 bool MtpClient::start() {
+    Mutex::Autolock autoLock(mMutex);
+
     if (mThread)
         return true;
 
@@ -76,6 +77,8 @@
 
     mThread = new MtpClientThread(this);
     mThread->run("MtpClientThread");
+    // wait for the thread to do initial device discovery before returning
+    mThreadStartCondition.wait(mMutex);
 
     return true;
 }
@@ -84,6 +87,15 @@
     mDone = true;
 }
 
+MtpDevice* MtpClient::getDevice(int id) {
+    for (int i = 0; i < mDeviceList.size(); i++) {
+        MtpDevice* device = mDeviceList[i];
+        if (device->getID() == id)
+            return device;
+    }
+    return NULL;
+}
+
 bool MtpClient::usbDeviceAdded(const char *devname) {
     struct usb_descriptor_header* desc;
     struct usb_descriptor_iter iter;
@@ -159,15 +171,6 @@
     return mDone;
 }
 
-MtpDevice* MtpClient::getDevice(int id) {
-    for (int i = 0; i < mDeviceList.size(); i++) {
-        MtpDevice* device = mDeviceList[i];
-        if (device->getID() == id)
-            return device;
-    }
-    return NULL;
-}
-
 bool MtpClient::usbDeviceRemoved(const char *devname) {
     for (int i = 0; i < mDeviceList.size(); i++) {
         MtpDevice* device = mDeviceList[i];
@@ -182,8 +185,14 @@
     return mDone;
 }
 
+bool MtpClient::usbDiscoveryDone() {
+    Mutex::Autolock autoLock(mMutex);
+    mThreadStartCondition.signal();
+    return mDone;
+}
+
 bool MtpClient::threadLoop() {
-    usb_host_run(mUsbHostContext, usb_device_added, usb_device_removed, this);
+    usb_host_run(mUsbHostContext, usb_device_added, usb_device_removed, usb_discovery_done, this);
     return false;
 }
 
@@ -197,4 +206,9 @@
     return ((MtpClient *)client_data)->usbDeviceRemoved(devname);
 }
 
+int MtpClient::usb_discovery_done(void* client_data) {
+    LOGD("usb_discovery_done\n");
+    return ((MtpClient *)client_data)->usbDiscoveryDone();
+}
+
 }  // namespace android