diff options
Diffstat (limited to 'media/jni')
| -rw-r--r-- | media/jni/Android.mk | 11 | ||||
| -rw-r--r-- | media/jni/android_media_MediaPlayer.cpp | 18 | ||||
| -rw-r--r-- | media/jni/android_media_MtpClient.cpp | 213 | ||||
| -rw-r--r-- | media/jni/android_media_MtpCursor.cpp | 128 | ||||
| -rw-r--r-- | media/jni/android_media_MtpServer.cpp | 160 |
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)); +} |
