summaryrefslogtreecommitdiffstats
path: root/media/jni
diff options
context:
space:
mode:
Diffstat (limited to 'media/jni')
-rw-r--r--media/jni/Android.mk11
-rw-r--r--media/jni/android_media_MediaPlayer.cpp18
-rw-r--r--media/jni/android_media_MtpClient.cpp213
-rw-r--r--media/jni/android_media_MtpCursor.cpp128
-rw-r--r--media/jni/android_media_MtpServer.cpp160
5 files changed, 527 insertions, 3 deletions
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 6eec215..3a7291f 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -12,7 +12,10 @@ LOCAL_SRC_FILES:= \
android_media_MediaMetadataRetriever.cpp \
android_media_ResampleInputStream.cpp \
android_media_MediaProfiles.cpp \
- android_media_AmrInputStream.cpp
+ android_media_AmrInputStream.cpp \
+ android_media_MtpClient.cpp \
+ android_media_MtpCursor.cpp \
+ android_media_MtpServer.cpp \
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
@@ -25,7 +28,8 @@ LOCAL_SHARED_LIBRARIES := \
libcutils \
libsurfaceflinger_client \
libstagefright \
- libcamera_client
+ libcamera_client \
+ libsqlite
ifneq ($(BUILD_WITHOUT_PV),true)
@@ -35,7 +39,7 @@ else
LOCAL_CFLAGS += -DNO_OPENCORE
endif
-LOCAL_STATIC_LIBRARIES :=
+LOCAL_STATIC_LIBRARIES := libmtp libusbhost
LOCAL_C_INCLUDES += \
external/tremor/Tremor \
@@ -44,6 +48,7 @@ LOCAL_C_INCLUDES += \
frameworks/base/media/libstagefright/codecs/amrnb/enc/src \
frameworks/base/media/libstagefright/codecs/amrnb/common \
frameworks/base/media/libstagefright/codecs/amrnb/common/include \
+ frameworks/base/media/mtp \
$(PV_INCLUDES) \
$(JNI_H_INCLUDE) \
$(call include-path-for, corecg graphics)
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index c5250d7..ca88bcc 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -777,6 +777,9 @@ extern int register_android_media_MediaRecorder(JNIEnv *env);
extern int register_android_media_MediaScanner(JNIEnv *env);
extern int register_android_media_ResampleInputStream(JNIEnv *env);
extern int register_android_media_MediaProfiles(JNIEnv *env);
+extern int register_android_media_MtpClient(JNIEnv *env);
+extern int register_android_media_MtpCursor(JNIEnv *env);
+extern int register_android_media_MtpServer(JNIEnv *env);
#ifndef NO_OPENCORE
extern int register_android_media_AmrInputStream(JNIEnv *env);
@@ -830,6 +833,21 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
goto bail;
}
+ if (register_android_media_MtpClient(env) < 0) {
+ LOGE("ERROR: MtpClient native registration failed");
+ goto bail;
+ }
+
+ if (register_android_media_MtpCursor(env) < 0) {
+ LOGE("ERROR: MtpCursor native registration failed");
+ goto bail;
+ }
+
+ if (register_android_media_MtpServer(env) < 0) {
+ LOGE("ERROR: MtpServer native registration failed");
+ goto bail;
+ }
+
/* success -- return valid version number */
result = JNI_VERSION_1_4;
diff --git a/media/jni/android_media_MtpClient.cpp b/media/jni/android_media_MtpClient.cpp
new file mode 100644
index 0000000..5c397a6
--- /dev/null
+++ b/media/jni/android_media_MtpClient.cpp
@@ -0,0 +1,213 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "MtpClientJNI"
+#include "utils/Log.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include "MtpClient.h"
+#include "MtpDevice.h"
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+
+static jmethodID method_deviceAdded;
+static jmethodID method_deviceRemoved;
+static jfieldID field_context;
+
+static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
+ if (env->ExceptionCheck()) {
+ LOGE("An exception was thrown by callback '%s'.", methodName);
+ LOGE_EX(env);
+ env->ExceptionClear();
+ }
+}
+
+class MyClient : public MtpClient {
+private:
+ virtual void deviceAdded(MtpDevice *device);
+ virtual void deviceRemoved(MtpDevice *device);
+
+ jobject mClient;
+ MtpDevice* mEventDevice;
+
+public:
+ MyClient(JNIEnv *env, jobject client);
+ void cleanup(JNIEnv *env);
+};
+
+MtpClient* get_client_from_object(JNIEnv* env, jobject javaClient)
+{
+ return (MtpClient*)env->GetIntField(javaClient, field_context);
+}
+
+
+MyClient::MyClient(JNIEnv *env, jobject client)
+ : mClient(env->NewGlobalRef(client))
+{
+}
+
+void MyClient::cleanup(JNIEnv *env) {
+ env->DeleteGlobalRef(mClient);
+}
+
+void MyClient::deviceAdded(MtpDevice *device) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ const char* name = device->getDeviceName();
+ LOGD("MyClient::deviceAdded %s\n", name);
+
+ env->CallVoidMethod(mClient, method_deviceAdded, device->getID());
+
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+}
+
+void MyClient::deviceRemoved(MtpDevice *device) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ const char* name = device->getDeviceName();
+ LOGD("MyClient::deviceRemoved %s\n", name);
+
+ env->CallVoidMethod(mClient, method_deviceRemoved, device->getID());
+
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+}
+
+// ----------------------------------------------------------------------------
+
+static void
+android_media_MtpClient_setup(JNIEnv *env, jobject thiz)
+{
+ LOGD("setup\n");
+ MyClient* client = new MyClient(env, thiz);
+ client->start();
+ env->SetIntField(thiz, field_context, (int)client);
+}
+
+static void
+android_media_MtpClient_finalize(JNIEnv *env, jobject thiz)
+{
+ LOGD("finalize\n");
+ MyClient *client = (MyClient *)env->GetIntField(thiz, field_context);
+ client->cleanup(env);
+ delete client;
+ env->SetIntField(thiz, field_context, 0);
+}
+
+static jboolean
+android_media_MtpClient_start(JNIEnv *env, jobject thiz)
+{
+ LOGD("start\n");
+ MyClient *client = (MyClient *)env->GetIntField(thiz, field_context);
+ return client->start();
+}
+
+static void
+android_media_MtpClient_stop(JNIEnv *env, jobject thiz)
+{
+ LOGD("stop\n");
+ MyClient *client = (MyClient *)env->GetIntField(thiz, field_context);
+ client->stop();
+}
+
+static jboolean
+android_media_MtpClient_delete_object(JNIEnv *env, jobject thiz,
+ jint device_id, jint object_id)
+{
+ MyClient *client = (MyClient *)env->GetIntField(thiz, field_context);
+ MtpDevice* device = client->getDevice(device_id);
+ if (device)
+ return device->deleteObject(object_id);
+ else
+ return NULL;
+}
+
+static jint
+android_media_MtpClient_get_parent(JNIEnv *env, jobject thiz,
+ jint device_id, jint object_id)
+{
+ MyClient *client = (MyClient *)env->GetIntField(thiz, field_context);
+ MtpDevice* device = client->getDevice(device_id);
+ if (device)
+ return device->getParent(object_id);
+ else
+ return -1;
+}
+
+static jint
+android_media_MtpClient_get_storage_id(JNIEnv *env, jobject thiz,
+ jint device_id, jint object_id)
+{
+ MyClient *client = (MyClient *)env->GetIntField(thiz, field_context);
+ MtpDevice* device = client->getDevice(device_id);
+ if (device)
+ return device->getStorageID(object_id);
+ else
+ return -1;
+}
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gMethods[] = {
+ {"native_setup", "()V", (void *)android_media_MtpClient_setup},
+ {"native_finalize", "()V", (void *)android_media_MtpClient_finalize},
+ {"native_start", "()Z", (void *)android_media_MtpClient_start},
+ {"native_stop", "()V", (void *)android_media_MtpClient_stop},
+ {"native_delete_object", "(II)Z", (void *)android_media_MtpClient_delete_object},
+ {"native_get_parent", "(II)I", (void *)android_media_MtpClient_get_parent},
+ {"native_get_storage_id", "(II)I", (void *)android_media_MtpClient_get_storage_id},
+};
+
+static const char* const kClassPathName = "android/media/MtpClient";
+
+int register_android_media_MtpClient(JNIEnv *env)
+{
+ jclass clazz;
+
+ LOGD("register_android_media_MtpClient\n");
+
+ clazz = env->FindClass("android/media/MtpClient");
+ if (clazz == NULL) {
+ LOGE("Can't find android/media/MtpClient");
+ return -1;
+ }
+ method_deviceAdded = env->GetMethodID(clazz, "deviceAdded", "(I)V");
+ if (method_deviceAdded == NULL) {
+ LOGE("Can't find deviceAdded");
+ return -1;
+ }
+ method_deviceRemoved = env->GetMethodID(clazz, "deviceRemoved", "(I)V");
+ if (method_deviceRemoved == NULL) {
+ LOGE("Can't find deviceRemoved");
+ return -1;
+ }
+ field_context = env->GetFieldID(clazz, "mNativeContext", "I");
+ if (field_context == NULL) {
+ LOGE("Can't find MtpClient.mNativeContext");
+ return -1;
+ }
+
+ return AndroidRuntime::registerNativeMethods(env,
+ "android/media/MtpClient", gMethods, NELEM(gMethods));
+}
diff --git a/media/jni/android_media_MtpCursor.cpp b/media/jni/android_media_MtpCursor.cpp
new file mode 100644
index 0000000..470fa05
--- /dev/null
+++ b/media/jni/android_media_MtpCursor.cpp
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "MtpCursorJNI"
+#include "utils/Log.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+#include "binder/CursorWindow.h"
+
+#include "MtpClient.h"
+#include "MtpCursor.h"
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+
+static jfieldID field_context;
+
+// From android_media_MtpClient.cpp
+MtpClient * get_client_from_object(JNIEnv * env, jobject javaClient);
+
+// ----------------------------------------------------------------------------
+
+static bool ExceptionCheck(void* env)
+{
+ return ((JNIEnv *)env)->ExceptionCheck();
+}
+
+static void
+android_media_MtpCursor_setup(JNIEnv *env, jobject thiz, jobject javaClient,
+ jint queryType, jint deviceID, jint storageID, jint objectID, jintArray javaColumns)
+{
+ LOGD("android_media_MtpCursor_setup queryType: %d deviceID: %d storageID: %d objectID: %d\n",
+ queryType, deviceID, storageID, objectID);
+
+ int* columns = NULL;
+ int columnCount = 0;
+ if (javaColumns) {
+ columns = env->GetIntArrayElements(javaColumns, 0);
+ columnCount = env->GetArrayLength(javaColumns);
+ }
+
+ MtpClient* client = get_client_from_object(env, javaClient);
+ MtpCursor* cursor = new MtpCursor(client, queryType,
+ deviceID, storageID, objectID, columnCount, columns);
+
+ if (columns)
+ env->ReleaseIntArrayElements(javaColumns, columns, 0);
+ env->SetIntField(thiz, field_context, (int)cursor);
+}
+
+static void
+android_media_MtpCursor_finalize(JNIEnv *env, jobject thiz)
+{
+ LOGD("finalize\n");
+ MtpCursor *cursor = (MtpCursor *)env->GetIntField(thiz, field_context);
+ delete cursor;
+}
+
+static jint
+android_media_MtpCursor_fill_window(JNIEnv *env, jobject thiz, jobject javaWindow, jint startPos)
+{
+ CursorWindow* window = get_window_from_object(env, javaWindow);
+ if (!window) {
+ LOGE("Invalid CursorWindow");
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "Bad CursorWindow");
+ return 0;
+ }
+ MtpCursor *cursor = (MtpCursor *)env->GetIntField(thiz, field_context);
+
+ return cursor->fillWindow(window, startPos);
+}
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gMethods[] = {
+ {"native_setup", "(Landroid/media/MtpClient;IIII[I)V",
+ (void *)android_media_MtpCursor_setup},
+ {"native_finalize", "()V", (void *)android_media_MtpCursor_finalize},
+ {"native_fill_window", "(Landroid/database/CursorWindow;I)I",
+ (void *)android_media_MtpCursor_fill_window},
+
+};
+
+static const char* const kClassPathName = "android/media/MtpCursor";
+
+int register_android_media_MtpCursor(JNIEnv *env)
+{
+ jclass clazz;
+
+ LOGD("register_android_media_MtpCursor\n");
+
+ clazz = env->FindClass("android/media/MtpCursor");
+ if (clazz == NULL) {
+ LOGE("Can't find android/media/MtpCursor");
+ return -1;
+ }
+ field_context = env->GetFieldID(clazz, "mNativeContext", "I");
+ if (field_context == NULL) {
+ LOGE("Can't find MtpCursor.mNativeContext");
+ return -1;
+ }
+
+ return AndroidRuntime::registerNativeMethods(env,
+ "android/media/MtpCursor", gMethods, NELEM(gMethods));
+}
diff --git a/media/jni/android_media_MtpServer.cpp b/media/jni/android_media_MtpServer.cpp
new file mode 100644
index 0000000..355a5eb
--- /dev/null
+++ b/media/jni/android_media_MtpServer.cpp
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "MtpServerJNI"
+#include "utils/Log.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <utils/threads.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include "MtpServer.h"
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+
+static jfieldID field_context;
+
+
+// ----------------------------------------------------------------------------
+
+static bool ExceptionCheck(void* env)
+{
+ return ((JNIEnv *)env)->ExceptionCheck();
+}
+
+class MtpThread : public Thread {
+private:
+ String8 mStoragePath;
+ String8 mDatabasePath;
+ bool mDone;
+ bool mScannedOnce;
+
+public:
+ MtpThread(const char* storagePath, const char* databasePath)
+ : mStoragePath(storagePath), mDatabasePath(databasePath), mDone(false), mScannedOnce(false)
+ {
+ }
+
+ virtual bool threadLoop() {
+ int fd = open("/dev/mtp_usb", O_RDWR);
+ printf("open returned %d\n", fd);
+ if (fd < 0) {
+ LOGE("could not open MTP driver\n");
+ return false;
+ }
+
+ MtpServer* server = new MtpServer(fd, mDatabasePath);
+ server->addStorage(mStoragePath);
+
+ // temporary
+ LOGD("MtpThread server->scanStorage");
+ server->scanStorage();
+ LOGD("MtpThread server->run");
+ server->run();
+ close(fd);
+ delete server;
+
+ bool done = mDone;
+ if (done)
+ delete this;
+ LOGD("threadLoop returning %s", (done ? "false" : "true"));
+ return !done;
+ }
+
+ void setDone() { mDone = true; }
+};
+
+static void
+android_media_MtpServer_setup(JNIEnv *env, jobject thiz, jstring storagePath, jstring databasePath)
+{
+ LOGD("setup\n");
+
+ const char *storagePathStr = env->GetStringUTFChars(storagePath, NULL);
+ const char *databasePathStr = env->GetStringUTFChars(databasePath, NULL);
+
+ MtpThread* thread = new MtpThread(storagePathStr, databasePathStr);
+ env->SetIntField(thiz, field_context, (int)thread);
+
+ env->ReleaseStringUTFChars(storagePath, storagePathStr);
+ env->ReleaseStringUTFChars(databasePath, databasePathStr);
+}
+
+static void
+android_media_MtpServer_finalize(JNIEnv *env, jobject thiz)
+{
+ LOGD("finalize\n");
+}
+
+
+static void
+android_media_MtpServer_start(JNIEnv *env, jobject thiz)
+{
+ LOGD("start\n");
+ MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
+ thread->run("MtpThread");
+}
+
+static void
+android_media_MtpServer_stop(JNIEnv *env, jobject thiz)
+{
+ LOGD("stop\n");
+ MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
+ if (thread) {
+ thread->setDone();
+ env->SetIntField(thiz, field_context, 0);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gMethods[] = {
+ {"native_setup", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)android_media_MtpServer_setup},
+ {"native_finalize", "()V", (void *)android_media_MtpServer_finalize},
+ {"native_start", "()V", (void *)android_media_MtpServer_start},
+ {"native_stop", "()V", (void *)android_media_MtpServer_stop},
+};
+
+static const char* const kClassPathName = "android/media/MtpServer";
+
+int register_android_media_MtpServer(JNIEnv *env)
+{
+ jclass clazz;
+
+ LOGD("register_android_media_MtpServer\n");
+
+ clazz = env->FindClass("android/media/MtpServer");
+ if (clazz == NULL) {
+ LOGE("Can't find android/media/MtpServer");
+ return -1;
+ }
+ field_context = env->GetFieldID(clazz, "mNativeContext", "I");
+ if (field_context == NULL) {
+ LOGE("Can't find MtpServer.mNativeContext");
+ return -1;
+ }
+
+ return AndroidRuntime::registerNativeMethods(env,
+ "android/media/MtpServer", gMethods, NELEM(gMethods));
+}