diff options
Diffstat (limited to 'mtp/mtp_MtpServer.cpp')
-rw-r--r-- | mtp/mtp_MtpServer.cpp | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/mtp/mtp_MtpServer.cpp b/mtp/mtp_MtpServer.cpp new file mode 100644 index 000000000..8d6038c77 --- /dev/null +++ b/mtp/mtp_MtpServer.cpp @@ -0,0 +1,199 @@ +/* + * 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() +{ + 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) + const char* mtp_device = EXPAND(USB_MTP_DEVICE); + MTPI("Using '%s' for MTP device.\n", EXPAND(USB_MTP_DEVICE)); +#else + const char* mtp_device = "/dev/mtp_usb"; +#endif + 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(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::set_storages(storages* mtpstorages) { + stores = mtpstorages; +} + +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); + + 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; + + 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; +} |