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

Commit 1b03920c authored by Ethan Yonker's avatar Ethan Yonker Committed by Dees Troy
Browse files

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
parent 1a7ba975
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -96,10 +96,9 @@ static const MtpEventCode kSupportedEventCodes[] = {
	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 @@ MtpServer::MtpServer(int fd, MtpDatabase* database, bool ptp,
		mSendObjectFormat(0),
		mSendObjectFileSize(0)
{
	mFD = -1;
}

MtpServer::~MtpServer() {
@@ -183,9 +183,11 @@ bool MtpServer::hasStorage(MtpStorageID id) {
	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 @@ void MtpServer::run() {
	mObjectEditList.clear();

	if (mSessionOpen)
		mDatabase->sessionEnded();
		mDatabase->sessionEnded(); // This doesn't actually do anything but was carry over from AOSP
	close(fd);
	mFD = -1;
}
+2 −2
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ private:
    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 @@ public:
    void                addStorage(MtpStorage* storage);
    void                removeStorage(MtpStorage* storage);

    void                run();
    void                run(int fd);

    void                sendObjectAdded(MtpObjectHandle handle);
    void                sendObjectRemoved(MtpObjectHandle handle);
+24 −32
Original line number Diff line number Diff line
@@ -36,23 +36,6 @@
#include <string>

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();
@@ -64,27 +47,36 @@ int twmtp_MtpServer::setup()
#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) {
	int fd = open(mtp_device, O_RDWR);
	if (fd < 0) {
		MTPE("could not open MTP driver, errno: %d\n", errno);
		return;
	}
	MTPD("fd: %d\n", fd);
		server = new MtpServer(fd, mtpdb, usePtp, 0, 0664, 0775);
	server = new MtpServer(mtpdb, usePtp, 0, 0664, 0775);
	refserver = server;
	MTPI("created new mtpserver object\n");
	} else {
		MTPE("could not open MTP driver, errno: %d\n", errno);
		return -1;
	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);
	}
	return 0;
}

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 @@ void twmtp_MtpServer::add_storage()
	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;

+0 −2
Original line number Diff line number Diff line
@@ -44,8 +44,6 @@ typedef std::vector<storage*> storages;
class twmtp_MtpServer {
	public:
		void start();
		int setup();
		void run();
		void cleanup();
		void send_object_added(int handle);
		void send_object_removed(int handle);
+26 −24
Original line number Diff line number Diff line
@@ -1945,7 +1945,6 @@ bool TWPartitionManager::Enable_MTP(void) {
	}
	//Launch MTP Responder
	LOGINFO("Starting MTP\n");
	int count = 0;

	int mtppipe[2];

@@ -1968,24 +1967,16 @@ bool TWPartitionManager::Enable_MTP(void) {
		TWFunc::write_file("/sys/class/android_usb/android0/idProduct", productstr);
		property_set("sys.usb.config", "mtp,adb");
	}
	std::vector<TWPartition*>::iterator iter;
	/* To enable MTP debug, use the twrp command line feature to
	 * twrp set tw_mtp_debug 1
	 */
	twrpMtp *mtp = new twrpMtp(DataManager::GetIntValue("tw_mtp_debug"));
	for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
		if ((*iter)->Is_Storage && (*iter)->Is_Present && (*iter)->Mount(false)) {
			printf("twrp addStorage %s, mtpstorageid: %u, maxFileSize: %lld\n", (*iter)->Storage_Path.c_str(), (*iter)->MTP_Storage_ID, (*iter)->Get_Max_FileSize());
			mtp->addStorage((*iter)->Storage_Name, (*iter)->Storage_Path, (*iter)->MTP_Storage_ID, (*iter)->Get_Max_FileSize());
			count++;
		}
	}
	if (count) {
	mtppid = mtp->forkserver(mtppipe);
	if (mtppid) {
		close(mtppipe[0]); // Host closes read side
		mtp_write_fd = mtppipe[1];
		DataManager::SetValue("tw_mtp_enabled", 1);
		Add_All_MTP_Storage();
		return true;
	} else {
		close(mtppipe[0]);
@@ -1993,11 +1984,6 @@ bool TWPartitionManager::Enable_MTP(void) {
		LOGERR("Failed to enable MTP\n");
		return false;
	}
	} else {
		close(mtppipe[0]);
		close(mtppipe[1]);
	}
	LOGERR("No valid storage partitions found for MTP.\n");
#else
	LOGERR("MTP support not included\n");
#endif
@@ -2005,6 +1991,22 @@ bool TWPartitionManager::Enable_MTP(void) {
	return false;
}

void TWPartitionManager::Add_All_MTP_Storage(void) {
#ifdef TW_HAS_MTP
	std::vector<TWPartition*>::iterator iter;

	if (!mtppid)
		return; // MTP is not enabled

	for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
		if ((*iter)->Is_Storage && (*iter)->Is_Present && (*iter)->Mount(false))
			Add_Remove_MTP_Storage((*iter), MTP_MESSAGE_ADD_STORAGE);
	}
#else
	return;
#endif
}

bool TWPartitionManager::Disable_MTP(void) {
	char old_value[PROPERTY_VALUE_MAX];
	property_get("sys.usb.config", old_value, "error");
@@ -2082,7 +2084,7 @@ bool TWPartitionManager::Add_Remove_MTP_Storage(TWPartition* Part, int message_t
			mtp_message.path = Part->Storage_Path.c_str();
			mtp_message.display = Part->Storage_Name.c_str();
			mtp_message.maxFileSize = Part->Get_Max_FileSize();
			LOGINFO("sending message to add %i '%s'\n", Part->MTP_Storage_ID, mtp_message.path);
			LOGINFO("sending message to add %i '%s' '%s'\n", mtp_message.storage_id, mtp_message.path, mtp_message.display);
			if (write(mtp_write_fd, &mtp_message, sizeof(mtp_message)) <= 0) {
				LOGINFO("error sending message to add storage %i\n", Part->MTP_Storage_ID);
				return false;
Loading