Some devices are very slow to respond to the sysfs requests. To prevent delaying the main GUI from booting during TWRP startup, we move the sleep delay to just before we open the MTP device and into the MTP thread so that it does not hold up the main TWRP thread. Change-Id: Ic931ef317d0fb7ef4dfdef46a32f68a014ff62c0
208 lines
5.5 KiB
C++
Executable File
208 lines
5.5 KiB
C++
Executable File
/*
|
|
* Copyright (C) 2010 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* Copyright (C) 2014 TeamWin - bigbiff and Dees_Troy mtp database conversion to C++
|
|
*/
|
|
|
|
#include <utils/Log.h>
|
|
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <limits.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <vector>
|
|
#include <utils/threads.h>
|
|
#include <pthread.h>
|
|
|
|
#include "mtp_MtpServer.hpp"
|
|
#include "MtpServer.h"
|
|
#include "MtpStorage.h"
|
|
#include "MtpDebug.h"
|
|
#include "MtpMessage.hpp"
|
|
|
|
#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();
|
|
/* Sleep for a bit before we open the MTP USB device because some
|
|
* devices are not ready due to the kernel not responding to our
|
|
* sysfs requests right away.
|
|
*/
|
|
usleep(800000);
|
|
#ifdef USB_MTP_DEVICE
|
|
#define STRINGIFY(x) #x
|
|
#define EXPAND(x) STRINGIFY(x)
|
|
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);
|
|
#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 {
|
|
MTPE("could not open MTP driver, errno: %d\n", errno);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void twmtp_MtpServer::run()
|
|
{
|
|
MTPD("running in twmtp\n");
|
|
server->run();
|
|
}
|
|
|
|
void twmtp_MtpServer::cleanup()
|
|
{
|
|
android::Mutex sMutex;
|
|
android::Mutex::Autolock autoLock(sMutex);
|
|
|
|
if (server) {
|
|
delete server;
|
|
} else {
|
|
MTPD("server is null in cleanup");
|
|
}
|
|
}
|
|
|
|
void twmtp_MtpServer::send_object_added(int handle)
|
|
{
|
|
android::Mutex sMutex;
|
|
android::Mutex::Autolock autoLock(sMutex);
|
|
|
|
if (server)
|
|
server->sendObjectAdded(handle);
|
|
else
|
|
MTPD("server is null in send_object_added");
|
|
}
|
|
|
|
void twmtp_MtpServer::send_object_removed(int handle)
|
|
{
|
|
android::Mutex sMutex;
|
|
android::Mutex::Autolock autoLock(sMutex);
|
|
|
|
if (server)
|
|
server->sendObjectRemoved(handle);
|
|
else
|
|
MTPD("server is null in send_object_removed");
|
|
}
|
|
|
|
void twmtp_MtpServer::add_storage()
|
|
{
|
|
android::Mutex sMutex;
|
|
android::Mutex::Autolock autoLock(sMutex);
|
|
|
|
MTPI("adding internal storage\n");
|
|
for (unsigned int i = 0; i < stores->size(); ++i) {
|
|
std::string pathStr = stores->at(i)->mount;
|
|
|
|
if (!pathStr.empty()) {
|
|
std::string descriptionStr = stores->at(i)->display;
|
|
int storageID = stores->at(i)->mtpid;
|
|
long reserveSpace = 1;
|
|
bool removable = false;
|
|
uint64_t maxFileSize = stores->at(i)->maxFileSize;
|
|
if (descriptionStr != "") {
|
|
MtpStorage* storage = new MtpStorage(storageID, &pathStr[0], &descriptionStr[0], reserveSpace, removable, maxFileSize, refserver);
|
|
server->addStorage(storage);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void twmtp_MtpServer::remove_storage(int storageId)
|
|
{
|
|
android::Mutex sMutex;
|
|
android::Mutex::Autolock autoLock(sMutex);
|
|
|
|
if (server) {
|
|
MtpStorage* storage = server->getStorage(storageId);
|
|
if (storage) {
|
|
MTPD("twmtp_MtpServer::remove_storage calling removeStorage\n");
|
|
server->removeStorage(storage);
|
|
}
|
|
} else
|
|
MTPD("server is null in remove_storage");
|
|
MTPD("twmtp_MtpServer::remove_storage DONE\n");
|
|
}
|
|
|
|
int twmtp_MtpServer::mtppipe_thread(void)
|
|
{
|
|
if (mtp_read_pipe == -1) {
|
|
MTPD("mtppipe_thread exiting because mtp_read_pipe not set\n");
|
|
return 0;
|
|
}
|
|
MTPD("Starting twmtp_MtpServer::mtppipe_thread\n");
|
|
int read_count;
|
|
struct mtpmsg mtp_message;
|
|
while (1) {
|
|
read_count = ::read(mtp_read_pipe, &mtp_message, sizeof(mtp_message));
|
|
MTPD("read %i from mtppipe\n", read_count);
|
|
if (read_count == sizeof(mtp_message)) {
|
|
if (mtp_message.message_type == MTP_MESSAGE_ADD_STORAGE) {
|
|
MTPI("mtppipe add storage %i '%s'\n", mtp_message.storage_id, mtp_message.path);
|
|
if (mtp_message.storage_id) {
|
|
long reserveSpace = 1;
|
|
bool removable = false;
|
|
MtpStorage* storage = new MtpStorage(mtp_message.storage_id, mtp_message.path, mtp_message.display, reserveSpace, removable, mtp_message.maxFileSize, refserver);
|
|
server->addStorage(storage);
|
|
MTPD("mtppipe done adding storage\n");
|
|
} else {
|
|
MTPE("Invalid storage ID %i specified\n", mtp_message.storage_id);
|
|
}
|
|
} else if (mtp_message.message_type == MTP_MESSAGE_REMOVE_STORAGE) {
|
|
MTPI("mtppipe remove storage %i\n", mtp_message.storage_id);
|
|
remove_storage(mtp_message.storage_id);
|
|
MTPD("mtppipe done removing storage\n");
|
|
} else {
|
|
MTPE("Unknown mtppipe message value: %i\n", mtp_message.message_type);
|
|
}
|
|
} else {
|
|
MTPE("twmtp_MtpServer::mtppipe_thread unexpected read_count %i\n", read_count);
|
|
close(mtp_read_pipe);
|
|
break;
|
|
}
|
|
}
|
|
MTPD("twmtp_MtpServer::mtppipe_thread closing\n");
|
|
return 0;
|
|
}
|
|
|
|
void twmtp_MtpServer::set_read_pipe(int pipe)
|
|
{
|
|
mtp_read_pipe = pipe;
|
|
}
|