diff options
author | Andreas Huber <andih@google.com> | 2010-01-28 11:19:57 -0800 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2010-01-28 11:52:43 -0800 |
commit | 256430093679e1d62b54fb0c852126e54d162f6f (patch) | |
tree | 028c49d18e0e77bc69f8967dda61619ee324f7a2 /media/jni | |
parent | 75d76bcf52587e4bfe00b7377d100510a3489674 (diff) | |
download | frameworks_base-256430093679e1d62b54fb0c852126e54d162f6f.zip frameworks_base-256430093679e1d62b54fb0c852126e54d162f6f.tar.gz frameworks_base-256430093679e1d62b54fb0c852126e54d162f6f.tar.bz2 |
API Extension: Support for optionally specifying a map of extra request headers when specifying the uri of media data to be played.
related-to-bug: 2393577
Original change by Andrei Popescu <andreip@google.com>
Diffstat (limited to 'media/jni')
-rw-r--r-- | media/jni/android_media_MediaPlayer.cpp | 95 |
1 files changed, 91 insertions, 4 deletions
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 703afd2..27f5668 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -31,6 +31,8 @@ #include "JNIHelp.h" #include "android_runtime/AndroidRuntime.h" #include "utils/Errors.h" // for status_t +#include "utils/KeyedVector.h" +#include "utils/String8.h" #include "android_util_Binder.h" #include <binder/Parcel.h> @@ -156,8 +158,8 @@ static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStat } static void -android_media_MediaPlayer_setDataSource(JNIEnv *env, jobject thiz, jstring path) -{ +android_media_MediaPlayer_setDataSourceAndHeaders( + JNIEnv *env, jobject thiz, jstring path, jobject headers) { sp<MediaPlayer> mp = getMediaPlayer(env, thiz); if (mp == NULL ) { jniThrowException(env, "java/lang/IllegalStateException", NULL); @@ -174,12 +176,96 @@ android_media_MediaPlayer_setDataSource(JNIEnv *env, jobject thiz, jstring path) jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); return; } + + // headers is a Map<String, String>. + // We build a similar KeyedVector out of it. + KeyedVector<String8, String8> headersVector; + if (headers) { + // Get the Map's entry Set. + jclass mapClass = env->FindClass("java/util/Map"); + + jmethodID entrySet = + env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;"); + + jobject set = env->CallObjectMethod(headers, entrySet); + // Obtain an iterator over the Set + jclass setClass = env->FindClass("java/util/Set"); + + jmethodID iterator = + env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;"); + + jobject iter = env->CallObjectMethod(set, iterator); + // Get the Iterator method IDs + jclass iteratorClass = env->FindClass("java/util/Iterator"); + jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z"); + + jmethodID next = + env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;"); + + // Get the Entry class method IDs + jclass entryClass = env->FindClass("java/util/Map$Entry"); + + jmethodID getKey = + env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;"); + + jmethodID getValue = + env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;"); + + // Iterate over the entry Set + while (env->CallBooleanMethod(iter, hasNext)) { + jobject entry = env->CallObjectMethod(iter, next); + jstring key = (jstring) env->CallObjectMethod(entry, getKey); + jstring value = (jstring) env->CallObjectMethod(entry, getValue); + + const char* keyStr = env->GetStringUTFChars(key, NULL); + if (!keyStr) { // Out of memory + jniThrowException( + env, "java/lang/RuntimeException", "Out of memory"); + return; + } + + const char* valueStr = env->GetStringUTFChars(value, NULL); + if (!valueStr) { // Out of memory + jniThrowException( + env, "java/lang/RuntimeException", "Out of memory"); + return; + } + + headersVector.add(String8(keyStr), String8(valueStr)); + + env->DeleteLocalRef(entry); + env->ReleaseStringUTFChars(key, keyStr); + env->DeleteLocalRef(key); + env->ReleaseStringUTFChars(value, valueStr); + env->DeleteLocalRef(value); + } + + env->DeleteLocalRef(entryClass); + env->DeleteLocalRef(iteratorClass); + env->DeleteLocalRef(iter); + env->DeleteLocalRef(setClass); + env->DeleteLocalRef(set); + env->DeleteLocalRef(mapClass); + } + LOGV("setDataSource: path %s", pathStr); - status_t opStatus = mp->setDataSource(pathStr); + status_t opStatus = + mp->setDataSource( + String8(pathStr), + headers ? &headersVector : NULL); // Make sure that local ref is released before a potential exception env->ReleaseStringUTFChars(path, pathStr); - process_media_player_call( env, thiz, opStatus, "java/io/IOException", "setDataSource failed." ); + + process_media_player_call( + env, thiz, opStatus, "java/io/IOException", + "setDataSource failed." ); +} + +static void +android_media_MediaPlayer_setDataSource(JNIEnv *env, jobject thiz, jstring path) +{ + android_media_MediaPlayer_setDataSourceAndHeaders(env, thiz, path, 0); } static void @@ -610,6 +696,7 @@ android_media_MediaPlayer_snoop(JNIEnv* env, jobject thiz, jobject data, jint ki static JNINativeMethod gMethods[] = { {"setDataSource", "(Ljava/lang/String;)V", (void *)android_media_MediaPlayer_setDataSource}, + {"setDataSource", "(Ljava/lang/String;Ljava/util/Map;)V",(void *)android_media_MediaPlayer_setDataSourceAndHeaders}, {"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD}, {"_setVideoSurface", "()V", (void *)android_media_MediaPlayer_setVideoSurface}, {"prepare", "()V", (void *)android_media_MediaPlayer_prepare}, |