MTP: make MTP work even if unplugged and replugged

Set up a loop to keep trying to open / read the MTP device so that
MTP will work even if the device is unplugged during boot or
unplugged and replugged in.

Change-Id: I0d3a3b7c91ce84a8cbed16caa4b15efee35b3641
diff --git a/mtp/MtpServer.cpp b/mtp/MtpServer.cpp
index 2c6d376..9cd6732 100755
--- a/mtp/MtpServer.cpp
+++ b/mtp/MtpServer.cpp
@@ -96,10 +96,9 @@
 	MTP_EVENT_OBJECT_PROP_CHANGED,
 };
 
-MtpServer::MtpServer(int fd, MtpDatabase* database, bool ptp,
+MtpServer::MtpServer(MtpDatabase* database, bool ptp,
 					int fileGroup, int filePerm, int directoryPerm)
-	:	mFD(fd),
-		mDatabase(database),
+	:	mDatabase(database),
 		mPtp(ptp),
 		mFileGroup(fileGroup),
 		mFilePermission(filePerm),
@@ -110,6 +109,7 @@
 		mSendObjectFormat(0),
 		mSendObjectFileSize(0)
 {
+	mFD = -1;
 }
 
 MtpServer::~MtpServer() {
@@ -183,9 +183,11 @@
 	return (getStorage(id) != NULL);
 }
 
-void MtpServer::run() {
-	int fd = mFD;
+void MtpServer::run(int fd) {
+	if (fd < 0)
+		return;
 
+	mFD = fd;
 	MTPI("MtpServer::run fd: %d\n", fd);
 
 	while (1) {
@@ -275,7 +277,7 @@
 	mObjectEditList.clear();
 
 	if (mSessionOpen)
-		mDatabase->sessionEnded();
+		mDatabase->sessionEnded(); // This doesn't actually do anything but was carry over from AOSP
 	close(fd);
 	mFD = -1;
 }
diff --git a/mtp/MtpServer.h b/mtp/MtpServer.h
index 61f5ccf..9443311 100755
--- a/mtp/MtpServer.h
+++ b/mtp/MtpServer.h
@@ -92,7 +92,7 @@
     android::Vector<ObjectEdit*>  mObjectEditList;
 
 public:
-                        MtpServer(int fd, MtpDatabase* database, bool ptp,
+                        MtpServer(MtpDatabase* database, bool ptp,
                                     int fileGroup, int filePerm, int directoryPerm);
     virtual             ~MtpServer();
 
@@ -102,7 +102,7 @@
     void                addStorage(MtpStorage* storage);
     void                removeStorage(MtpStorage* storage);
 
-    void                run();
+    void                run(int fd);
 
     void                sendObjectAdded(MtpObjectHandle handle);
     void                sendObjectRemoved(MtpObjectHandle handle);
diff --git a/mtp/mtp_MtpServer.cpp b/mtp/mtp_MtpServer.cpp
index b53d07a..8d6038c 100755
--- a/mtp/mtp_MtpServer.cpp
+++ b/mtp/mtp_MtpServer.cpp
@@ -37,23 +37,6 @@
 
 void twmtp_MtpServer::start()
 {
-	if (setup() == 0) {
-		add_storage();
-		MTPD("Starting add / remove mtppipe monitor thread\n");
-		pthread_t thread;
-		ThreadPtr mtpptr = &twmtp_MtpServer::mtppipe_thread;
-		PThreadPtr p = *(PThreadPtr*)&mtpptr;
-		pthread_create(&thread, NULL, p, this);
-		server->run();
-	}
-}
-
-void twmtp_MtpServer::set_storages(storages* mtpstorages) {
-	stores = mtpstorages;
-}
-
-int twmtp_MtpServer::setup()
-{
 	usePtp =  false;
 	MyMtpDatabase* mtpdb = new MyMtpDatabase();
 	/* Sleep for a bit before we open the MTP USB device because some
@@ -64,27 +47,36 @@
 #ifdef USB_MTP_DEVICE
 #define STRINGIFY(x) #x
 #define EXPAND(x) STRINGIFY(x)
+	const char* mtp_device = EXPAND(USB_MTP_DEVICE);
 	MTPI("Using '%s' for MTP device.\n", EXPAND(USB_MTP_DEVICE));
-	int fd = open(EXPAND(USB_MTP_DEVICE), O_RDWR);
 #else
-	int fd = open("/dev/mtp_usb", O_RDWR);
+	const char* mtp_device = "/dev/mtp_usb";
 #endif
-	if (fd >= 0) {
-		MTPD("fd: %d\n", fd);
-		server = new MtpServer(fd, mtpdb, usePtp, 0, 0664, 0775);
-		refserver = server;
-		MTPI("created new mtpserver object\n");
-	} else {
+	int fd = open(mtp_device, O_RDWR);
+	if (fd < 0) {
 		MTPE("could not open MTP driver, errno: %d\n", errno);
-		return -1;
+		return;
 	}
-	return 0;
+	MTPD("fd: %d\n", fd);
+	server = new MtpServer(mtpdb, usePtp, 0, 0664, 0775);
+	refserver = server;
+	MTPI("created new mtpserver object\n");
+	add_storage();
+	MTPD("Starting add / remove mtppipe monitor thread\n");
+	pthread_t thread;
+	ThreadPtr mtpptr = &twmtp_MtpServer::mtppipe_thread;
+	PThreadPtr p = *(PThreadPtr*)&mtpptr;
+	pthread_create(&thread, NULL, p, this);
+	// This loop restarts the MTP process if the device is unplugged and replugged in
+	while (true) {
+		server->run(fd);
+		fd = open(mtp_device, O_RDWR);
+		usleep(800000);
+	}
 }
 
-void twmtp_MtpServer::run()
-{
-	MTPD("running in twmtp\n");
-	server->run();
+void twmtp_MtpServer::set_storages(storages* mtpstorages) {
+	stores = mtpstorages;
 }
 
 void twmtp_MtpServer::cleanup()
@@ -126,7 +118,7 @@
 	android::Mutex sMutex;
 	android::Mutex::Autolock autoLock(sMutex);
 
-	MTPI("adding internal storage\n");
+	MTPD("twmtp_MtpServer::add_storage count of storage devices: %i\n", stores->size());
 	for (unsigned int i = 0; i < stores->size(); ++i) {
 			std::string pathStr = stores->at(i)->mount;
 
diff --git a/mtp/mtp_MtpServer.hpp b/mtp/mtp_MtpServer.hpp
index 622ed6d..99f63d5 100755
--- a/mtp/mtp_MtpServer.hpp
+++ b/mtp/mtp_MtpServer.hpp
@@ -44,8 +44,6 @@
 class twmtp_MtpServer {
 	public:
 		void start();
-		int setup();
-		void run();
 		void cleanup();
 		void send_object_added(int handle);
 		void send_object_removed(int handle);