blob: b53d07a8f229b97eee952ba7f12c8122db10c3d4 [file] [log] [blame]
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -04001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * Copyright (C) 2014 TeamWin - bigbiff and Dees_Troy mtp database conversion to C++
17 */
18
19#include <utils/Log.h>
20
21#include <stdio.h>
22#include <assert.h>
23#include <limits.h>
24#include <unistd.h>
25#include <fcntl.h>
26#include <vector>
27#include <utils/threads.h>
Ethan Yonker726a0202014-12-16 20:01:38 -060028#include <pthread.h>
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040029
30#include "mtp_MtpServer.hpp"
31#include "MtpServer.h"
32#include "MtpStorage.h"
33#include "MtpDebug.h"
Ethan Yonker726a0202014-12-16 20:01:38 -060034#include "MtpMessage.hpp"
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040035
36#include <string>
37
38void twmtp_MtpServer::start()
39{
Ethan Yonker20fd25c2014-09-03 14:04:43 -050040 if (setup() == 0) {
41 add_storage();
Ethan Yonker726a0202014-12-16 20:01:38 -060042 MTPD("Starting add / remove mtppipe monitor thread\n");
43 pthread_t thread;
44 ThreadPtr mtpptr = &twmtp_MtpServer::mtppipe_thread;
45 PThreadPtr p = *(PThreadPtr*)&mtpptr;
46 pthread_create(&thread, NULL, p, this);
Ethan Yonker20fd25c2014-09-03 14:04:43 -050047 server->run();
48 }
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040049}
50
51void twmtp_MtpServer::set_storages(storages* mtpstorages) {
52 stores = mtpstorages;
53}
54
Ethan Yonker20fd25c2014-09-03 14:04:43 -050055int twmtp_MtpServer::setup()
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040056{
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040057 usePtp = false;
58 MyMtpDatabase* mtpdb = new MyMtpDatabase();
Ethan Yonkerabb5c4e2014-12-29 09:44:05 -060059 /* Sleep for a bit before we open the MTP USB device because some
60 * devices are not ready due to the kernel not responding to our
61 * sysfs requests right away.
62 */
63 usleep(800000);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040064#ifdef USB_MTP_DEVICE
Ethan Yonkera1f38052014-09-11 08:28:51 -050065#define STRINGIFY(x) #x
66#define EXPAND(x) STRINGIFY(x)
67 MTPI("Using '%s' for MTP device.\n", EXPAND(USB_MTP_DEVICE));
68 int fd = open(EXPAND(USB_MTP_DEVICE), O_RDWR);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040069#else
70 int fd = open("/dev/mtp_usb", O_RDWR);
71#endif
72 if (fd >= 0) {
73 MTPD("fd: %d\n", fd);
74 server = new MtpServer(fd, mtpdb, usePtp, 0, 0664, 0775);
75 refserver = server;
76 MTPI("created new mtpserver object\n");
77 } else {
Ethan Yonker20fd25c2014-09-03 14:04:43 -050078 MTPE("could not open MTP driver, errno: %d\n", errno);
79 return -1;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040080 }
Ethan Yonker20fd25c2014-09-03 14:04:43 -050081 return 0;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040082}
83
84void twmtp_MtpServer::run()
85{
86 MTPD("running in twmtp\n");
87 server->run();
88}
89
90void twmtp_MtpServer::cleanup()
91{
92 android::Mutex sMutex;
93 android::Mutex::Autolock autoLock(sMutex);
94
95 if (server) {
96 delete server;
97 } else {
98 MTPD("server is null in cleanup");
99 }
100}
101
102void twmtp_MtpServer::send_object_added(int handle)
103{
104 android::Mutex sMutex;
105 android::Mutex::Autolock autoLock(sMutex);
106
107 if (server)
108 server->sendObjectAdded(handle);
109 else
110 MTPD("server is null in send_object_added");
111}
112
113void twmtp_MtpServer::send_object_removed(int handle)
114{
115 android::Mutex sMutex;
116 android::Mutex::Autolock autoLock(sMutex);
117
118 if (server)
119 server->sendObjectRemoved(handle);
120 else
121 MTPD("server is null in send_object_removed");
122}
123
124void twmtp_MtpServer::add_storage()
125{
126 android::Mutex sMutex;
127 android::Mutex::Autolock autoLock(sMutex);
128
129 MTPI("adding internal storage\n");
130 for (unsigned int i = 0; i < stores->size(); ++i) {
131 std::string pathStr = stores->at(i)->mount;
132
133 if (!pathStr.empty()) {
134 std::string descriptionStr = stores->at(i)->display;
135 int storageID = stores->at(i)->mtpid;
136 long reserveSpace = 1;
137 bool removable = false;
bigbiff0c532032014-12-21 13:41:26 -0500138 uint64_t maxFileSize = stores->at(i)->maxFileSize;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400139 if (descriptionStr != "") {
140 MtpStorage* storage = new MtpStorage(storageID, &pathStr[0], &descriptionStr[0], reserveSpace, removable, maxFileSize, refserver);
141 server->addStorage(storage);
142 }
143 }
144 }
145}
146
147void twmtp_MtpServer::remove_storage(int storageId)
148{
149 android::Mutex sMutex;
150 android::Mutex::Autolock autoLock(sMutex);
151
152 if (server) {
153 MtpStorage* storage = server->getStorage(storageId);
154 if (storage) {
Ethan Yonker726a0202014-12-16 20:01:38 -0600155 MTPD("twmtp_MtpServer::remove_storage calling removeStorage\n");
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400156 server->removeStorage(storage);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400157 }
158 } else
159 MTPD("server is null in remove_storage");
Ethan Yonker726a0202014-12-16 20:01:38 -0600160 MTPD("twmtp_MtpServer::remove_storage DONE\n");
161}
162
163int twmtp_MtpServer::mtppipe_thread(void)
164{
165 if (mtp_read_pipe == -1) {
166 MTPD("mtppipe_thread exiting because mtp_read_pipe not set\n");
167 return 0;
168 }
169 MTPD("Starting twmtp_MtpServer::mtppipe_thread\n");
170 int read_count;
171 struct mtpmsg mtp_message;
172 while (1) {
173 read_count = ::read(mtp_read_pipe, &mtp_message, sizeof(mtp_message));
174 MTPD("read %i from mtppipe\n", read_count);
175 if (read_count == sizeof(mtp_message)) {
176 if (mtp_message.message_type == MTP_MESSAGE_ADD_STORAGE) {
177 MTPI("mtppipe add storage %i '%s'\n", mtp_message.storage_id, mtp_message.path);
Ethan Yonker4bfabab2014-12-29 09:15:37 -0600178 if (mtp_message.storage_id) {
179 long reserveSpace = 1;
180 bool removable = false;
181 MtpStorage* storage = new MtpStorage(mtp_message.storage_id, mtp_message.path, mtp_message.display, reserveSpace, removable, mtp_message.maxFileSize, refserver);
182 server->addStorage(storage);
183 MTPD("mtppipe done adding storage\n");
184 } else {
185 MTPE("Invalid storage ID %i specified\n", mtp_message.storage_id);
186 }
Ethan Yonker726a0202014-12-16 20:01:38 -0600187 } else if (mtp_message.message_type == MTP_MESSAGE_REMOVE_STORAGE) {
188 MTPI("mtppipe remove storage %i\n", mtp_message.storage_id);
189 remove_storage(mtp_message.storage_id);
190 MTPD("mtppipe done removing storage\n");
191 } else {
192 MTPE("Unknown mtppipe message value: %i\n", mtp_message.message_type);
193 }
194 } else {
195 MTPE("twmtp_MtpServer::mtppipe_thread unexpected read_count %i\n", read_count);
196 close(mtp_read_pipe);
197 break;
198 }
199 }
200 MTPD("twmtp_MtpServer::mtppipe_thread closing\n");
201 return 0;
202}
203
204void twmtp_MtpServer::set_read_pipe(int pipe)
205{
206 mtp_read_pipe = pipe;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400207}