blob: 33051362e0aa7ba6d960a95d78b2baa46b1f3670 [file] [log] [blame]
Mike Lockwood98ef64e2010-06-29 16:42:13 -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
17#define LOG_TAG "MtpServerJNI"
18#include "utils/Log.h"
19
20#include <stdio.h>
21#include <assert.h>
22#include <limits.h>
23#include <unistd.h>
24#include <fcntl.h>
25#include <utils/threads.h>
26
27#include "jni.h"
28#include "JNIHelp.h"
29#include "android_runtime/AndroidRuntime.h"
Mike Lockwooddad69272010-07-02 15:15:07 -040030#include "private/android_filesystem_config.h"
Mike Lockwood98ef64e2010-06-29 16:42:13 -040031
32#include "MtpServer.h"
33
Mike Lockwood81ea83d2010-06-30 17:49:41 -040034using namespace android;
Mike Lockwood98ef64e2010-06-29 16:42:13 -040035
36// ----------------------------------------------------------------------------
37
38static jfieldID field_context;
Mike Lockwood23ee42f2010-08-03 15:17:55 -040039static Mutex sMutex;
Mike Lockwood98ef64e2010-06-29 16:42:13 -040040
Mike Lockwoodd21eac92010-07-03 00:44:05 -040041// in android_media_MtpDatabase.cpp
42extern MtpDatabase* getMtpDatabase(JNIEnv *env, jobject database);
Mike Lockwood98ef64e2010-06-29 16:42:13 -040043
44// ----------------------------------------------------------------------------
45
Mike Lockwoodff164a72010-07-15 15:01:17 -040046#ifdef HAVE_ANDROID_OS
47
Mike Lockwood98ef64e2010-06-29 16:42:13 -040048static bool ExceptionCheck(void* env)
49{
50 return ((JNIEnv *)env)->ExceptionCheck();
51}
52
53class MtpThread : public Thread {
54private:
Mike Lockwoodd21eac92010-07-03 00:44:05 -040055 MtpDatabase* mDatabase;
Mike Lockwoodbe125a52010-07-12 18:54:16 -040056 MtpServer* mServer;
Mike Lockwood23ee42f2010-08-03 15:17:55 -040057 String8 mStoragePath;
Mike Lockwood23ee42f2010-08-03 15:17:55 -040058 jobject mJavaServer;
Mike Lockwood98ef64e2010-06-29 16:42:13 -040059
60public:
Mike Lockwood23ee42f2010-08-03 15:17:55 -040061 MtpThread(MtpDatabase* database, const char* storagePath, jobject javaServer)
62 : mDatabase(database),
63 mServer(NULL),
64 mStoragePath(storagePath),
Mike Lockwood23ee42f2010-08-03 15:17:55 -040065 mJavaServer(javaServer)
Mike Lockwood98ef64e2010-06-29 16:42:13 -040066 {
67 }
68
69 virtual bool threadLoop() {
Mike Lockwood2b2bff52010-08-18 12:32:26 -040070 int fd = open("/dev/mtp_usb", O_RDWR);
71 printf("open returned %d\n", fd);
72 if (fd < 0) {
73 LOGE("could not open MTP driver\n");
74 return false;
Mike Lockwood98ef64e2010-06-29 16:42:13 -040075 }
76
Mike Lockwood23ee42f2010-08-03 15:17:55 -040077 sMutex.lock();
Mike Lockwood2b2bff52010-08-18 12:32:26 -040078 mServer = new MtpServer(fd, mDatabase, AID_SDCARD_RW, 0664, 0775);
79 mServer->addStorage(mStoragePath);
80 sMutex.unlock();
81
82 LOGD("MtpThread mServer->run");
83 mServer->run();
84 close(fd);
85
86 sMutex.lock();
87 delete mServer;
88 mServer = NULL;
89
Mike Lockwood23ee42f2010-08-03 15:17:55 -040090 JNIEnv* env = AndroidRuntime::getJNIEnv();
91 env->SetIntField(mJavaServer, field_context, 0);
92 env->DeleteGlobalRef(mJavaServer);
93 sMutex.unlock();
Mike Lockwood98ef64e2010-06-29 16:42:13 -040094
Mike Lockwood23ee42f2010-08-03 15:17:55 -040095 LOGD("threadLoop returning");
96 return false;
Mike Lockwood98ef64e2010-06-29 16:42:13 -040097 }
98
Mike Lockwoodbe125a52010-07-12 18:54:16 -040099 void sendObjectAdded(MtpObjectHandle handle) {
Mike Lockwood23ee42f2010-08-03 15:17:55 -0400100 sMutex.lock();
Mike Lockwoodbe125a52010-07-12 18:54:16 -0400101 if (mServer)
102 mServer->sendObjectAdded(handle);
103 else
104 LOGE("sendObjectAdded called while disconnected\n");
Mike Lockwood23ee42f2010-08-03 15:17:55 -0400105 sMutex.unlock();
Mike Lockwoodbe125a52010-07-12 18:54:16 -0400106 }
107
108 void sendObjectRemoved(MtpObjectHandle handle) {
Mike Lockwood23ee42f2010-08-03 15:17:55 -0400109 sMutex.lock();
Mike Lockwoodbe125a52010-07-12 18:54:16 -0400110 if (mServer)
111 mServer->sendObjectRemoved(handle);
112 else
113 LOGE("sendObjectRemoved called while disconnected\n");
Mike Lockwood23ee42f2010-08-03 15:17:55 -0400114 sMutex.unlock();
Mike Lockwoodbe125a52010-07-12 18:54:16 -0400115 }
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400116};
117
Mike Lockwoodff164a72010-07-15 15:01:17 -0400118#endif // HAVE_ANDROID_OS
119
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400120static void
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400121android_media_MtpServer_setup(JNIEnv *env, jobject thiz, jobject javaDatabase, jstring storagePath)
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400122{
Mike Lockwoodff164a72010-07-15 15:01:17 -0400123#ifdef HAVE_ANDROID_OS
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400124 LOGD("setup\n");
125
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400126 MtpDatabase* database = getMtpDatabase(env, javaDatabase);
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400127 const char *storagePathStr = env->GetStringUTFChars(storagePath, NULL);
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400128
Mike Lockwood23ee42f2010-08-03 15:17:55 -0400129 MtpThread* thread = new MtpThread(database, storagePathStr, env->NewGlobalRef(thiz));
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400130 env->SetIntField(thiz, field_context, (int)thread);
131
132 env->ReleaseStringUTFChars(storagePath, storagePathStr);
Mike Lockwoodff164a72010-07-15 15:01:17 -0400133#endif
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400134}
135
136static void
137android_media_MtpServer_finalize(JNIEnv *env, jobject thiz)
138{
139 LOGD("finalize\n");
140}
141
142
143static void
144android_media_MtpServer_start(JNIEnv *env, jobject thiz)
145{
Mike Lockwoodff164a72010-07-15 15:01:17 -0400146#ifdef HAVE_ANDROID_OS
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400147 LOGD("start\n");
148 MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
149 thread->run("MtpThread");
Mike Lockwoodff164a72010-07-15 15:01:17 -0400150#endif // HAVE_ANDROID_OS
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400151}
152
153static void
154android_media_MtpServer_stop(JNIEnv *env, jobject thiz)
155{
Mike Lockwoodff164a72010-07-15 15:01:17 -0400156#ifdef HAVE_ANDROID_OS
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400157 LOGD("stop\n");
Mike Lockwoodff164a72010-07-15 15:01:17 -0400158#endif
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400159}
160
Mike Lockwoodbe125a52010-07-12 18:54:16 -0400161static void
162android_media_MtpServer_send_object_added(JNIEnv *env, jobject thiz, jint handle)
163{
Mike Lockwoodff164a72010-07-15 15:01:17 -0400164#ifdef HAVE_ANDROID_OS
Mike Lockwoodbe125a52010-07-12 18:54:16 -0400165 LOGD("send_object_added %d\n", handle);
166 MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
167 if (thread)
168 thread->sendObjectAdded(handle);
169 else
170 LOGE("sendObjectAdded called while disconnected\n");
Mike Lockwoodff164a72010-07-15 15:01:17 -0400171#endif
Mike Lockwoodbe125a52010-07-12 18:54:16 -0400172}
173
174static void
175android_media_MtpServer_send_object_removed(JNIEnv *env, jobject thiz, jint handle)
176{
Mike Lockwoodff164a72010-07-15 15:01:17 -0400177#ifdef HAVE_ANDROID_OS
Mike Lockwoodbe125a52010-07-12 18:54:16 -0400178 LOGD("send_object_removed %d\n", handle);
179 MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
180 if (thread)
181 thread->sendObjectRemoved(handle);
182 else
183 LOGE("sendObjectRemoved called while disconnected\n");
Mike Lockwoodff164a72010-07-15 15:01:17 -0400184#endif
Mike Lockwoodbe125a52010-07-12 18:54:16 -0400185}
186
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400187// ----------------------------------------------------------------------------
188
189static JNINativeMethod gMethods[] = {
Mike Lockwoodbe125a52010-07-12 18:54:16 -0400190 {"native_setup", "(Landroid/media/MtpDatabase;Ljava/lang/String;)V",
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400191 (void *)android_media_MtpServer_setup},
Mike Lockwoodbe125a52010-07-12 18:54:16 -0400192 {"native_finalize", "()V", (void *)android_media_MtpServer_finalize},
193 {"native_start", "()V", (void *)android_media_MtpServer_start},
194 {"native_stop", "()V", (void *)android_media_MtpServer_stop},
195 {"native_send_object_added", "(I)V", (void *)android_media_MtpServer_send_object_added},
196 {"native_send_object_removed", "(I)V", (void *)android_media_MtpServer_send_object_removed},
Mike Lockwood98ef64e2010-06-29 16:42:13 -0400197};
198
199static const char* const kClassPathName = "android/media/MtpServer";
200
201int register_android_media_MtpServer(JNIEnv *env)
202{
203 jclass clazz;
204
205 LOGD("register_android_media_MtpServer\n");
206
207 clazz = env->FindClass("android/media/MtpServer");
208 if (clazz == NULL) {
209 LOGE("Can't find android/media/MtpServer");
210 return -1;
211 }
212 field_context = env->GetFieldID(clazz, "mNativeContext", "I");
213 if (field_context == NULL) {
214 LOGE("Can't find MtpServer.mNativeContext");
215 return -1;
216 }
217
218 return AndroidRuntime::registerNativeMethods(env,
219 "android/media/MtpServer", gMethods, NELEM(gMethods));
220}