3 ** Copyright 2007, The Android Open Source Project
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
9 ** http://www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
18 //#define LOG_NDEBUG 0
19 #define LOG_TAG "MediaPlayer-JNI"
20 #include "utils/Log.h"
22 #include <media/mediaplayer.h>
23 #include <media/MediaPlayerInterface.h>
29 #include <utils/threads.h>
32 #include "android_runtime/AndroidRuntime.h"
33 #include "android_runtime/android_view_Surface.h"
34 #include "utils/Errors.h" // for status_t
35 #include "utils/KeyedVector.h"
36 #include "utils/String8.h"
37 #include "android_media_Utils.h"
39 #include "android_os_Parcel.h"
40 #include "android_util_Binder.h"
41 #include <binder/Parcel.h>
42 #include <gui/IGraphicBufferProducer.h>
43 #include <gui/Surface.h>
44 #include <binder/IPCThreadState.h>
45 #include <binder/IServiceManager.h>
47 // ----------------------------------------------------------------------------
49 using namespace android;
51 // ----------------------------------------------------------------------------
55 jfieldID surface_texture;
59 jmethodID proxyConfigGetHost;
60 jmethodID proxyConfigGetPort;
61 jmethodID proxyConfigGetExclusionList;
63 static fields_t fields;
67 // ----------------------------------------------------------------------------
68 // ref-counted object for callbacks
69 class JNIMediaPlayerListener: public MediaPlayerListener
72 JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
73 ~JNIMediaPlayerListener();
74 virtual void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL);
76 JNIMediaPlayerListener();
77 jclass mClass; // Reference to MediaPlayer class
78 jobject mObject; // Weak ref to MediaPlayer Java object to call on
81 JNIMediaPlayerListener::JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
84 // Hold onto the MediaPlayer class for use in calling the static method
85 // that posts events to the application thread.
86 jclass clazz = env->GetObjectClass(thiz);
88 ALOGE("Can't find android/media/MediaPlayer");
89 jniThrowException(env, "java/lang/Exception", NULL);
92 mClass = (jclass)env->NewGlobalRef(clazz);
94 // We use a weak reference so the MediaPlayer object can be garbage collected.
95 // The reference is only used as a proxy for callbacks.
96 mObject = env->NewGlobalRef(weak_thiz);
99 JNIMediaPlayerListener::~JNIMediaPlayerListener()
101 // remove global references
102 JNIEnv *env = AndroidRuntime::getJNIEnv();
103 env->DeleteGlobalRef(mObject);
104 env->DeleteGlobalRef(mClass);
107 void JNIMediaPlayerListener::notify(int msg, int ext1, int ext2, const Parcel *obj)
109 JNIEnv *env = AndroidRuntime::getJNIEnv();
110 if (obj && obj->dataSize() > 0) {
111 jobject jParcel = createJavaParcelObject(env);
112 if (jParcel != NULL) {
113 Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
114 nativeParcel->setData(obj->data(), obj->dataSize());
115 env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
116 msg, ext1, ext2, jParcel);
119 env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
120 msg, ext1, ext2, NULL);
122 if (env->ExceptionCheck()) {
123 ALOGW("An exception occurred while notifying an event.");
125 env->ExceptionClear();
129 // ----------------------------------------------------------------------------
131 static sp<MediaPlayer> getMediaPlayer(JNIEnv* env, jobject thiz)
133 Mutex::Autolock l(sLock);
134 MediaPlayer* const p = (MediaPlayer*)env->GetIntField(thiz, fields.context);
135 return sp<MediaPlayer>(p);
138 static sp<MediaPlayer> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaPlayer>& player)
140 Mutex::Autolock l(sLock);
141 sp<MediaPlayer> old = (MediaPlayer*)env->GetIntField(thiz, fields.context);
143 player->incStrong((void*)setMediaPlayer);
146 old->decStrong((void*)setMediaPlayer);
148 env->SetIntField(thiz, fields.context, (int)player.get());
152 // If exception is NULL and opStatus is not OK, this method sends an error
153 // event to the client application; otherwise, if exception is not NULL and
154 // opStatus is not OK, this method throws the given exception to the client
156 static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStatus, const char* exception, const char *message)
158 if (exception == NULL) { // Don't throw exception. Instead, send an event.
159 if (opStatus != (status_t) OK) {
160 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
161 if (mp != 0) mp->notify(MEDIA_ERROR, opStatus, 0);
163 } else { // Throw exception!
164 if ( opStatus == (status_t) INVALID_OPERATION ) {
165 jniThrowException(env, "java/lang/IllegalStateException", NULL);
166 } else if ( opStatus == (status_t) PERMISSION_DENIED ) {
167 jniThrowException(env, "java/lang/SecurityException", NULL);
168 } else if ( opStatus != (status_t) OK ) {
169 if (strlen(message) > 230) {
170 // if the message is too long, don't bother displaying the status code
171 jniThrowException( env, exception, message);
174 // append the status code to the message
175 sprintf(msg, "%s: status=0x%X", message, opStatus);
176 jniThrowException( env, exception, msg);
183 android_media_MediaPlayer_setDataSourceAndHeaders(
184 JNIEnv *env, jobject thiz, jstring path,
185 jobjectArray keys, jobjectArray values) {
187 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
189 jniThrowException(env, "java/lang/IllegalStateException", NULL);
194 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
198 const char *tmp = env->GetStringUTFChars(path, NULL);
199 if (tmp == NULL) { // Out of memory
202 ALOGV("setDataSource: path %s", tmp);
204 String8 pathStr(tmp);
205 env->ReleaseStringUTFChars(path, tmp);
208 // We build a KeyedVector out of the key and val arrays
209 KeyedVector<String8, String8> headersVector;
210 if (!ConvertKeyValueArraysToKeyedVector(
211 env, keys, values, &headersVector)) {
218 headersVector.size() > 0? &headersVector : NULL);
220 process_media_player_call(
221 env, thiz, opStatus, "java/io/IOException",
222 "setDataSource failed." );
226 android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
228 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
230 jniThrowException(env, "java/lang/IllegalStateException", NULL);
234 if (fileDescriptor == NULL) {
235 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
238 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
239 ALOGV("setDataSourceFD: fd %d", fd);
240 process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
243 static sp<IGraphicBufferProducer>
244 getVideoSurfaceTexture(JNIEnv* env, jobject thiz) {
245 IGraphicBufferProducer * const p = (IGraphicBufferProducer*)env->GetIntField(thiz, fields.surface_texture);
246 return sp<IGraphicBufferProducer>(p);
250 decVideoSurfaceRef(JNIEnv *env, jobject thiz)
252 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
257 sp<IGraphicBufferProducer> old_st = getVideoSurfaceTexture(env, thiz);
258 if (old_st != NULL) {
259 old_st->decStrong((void*)decVideoSurfaceRef);
264 setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface, jboolean mediaPlayerMustBeAlive)
266 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
268 if (mediaPlayerMustBeAlive) {
269 jniThrowException(env, "java/lang/IllegalStateException", NULL);
274 decVideoSurfaceRef(env, thiz);
276 sp<IGraphicBufferProducer> new_st;
278 sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
279 if (surface != NULL) {
280 new_st = surface->getIGraphicBufferProducer();
281 if (new_st == NULL) {
282 jniThrowException(env, "java/lang/IllegalArgumentException",
283 "The surface does not have a binding SurfaceTexture!");
286 new_st->incStrong((void*)decVideoSurfaceRef);
288 jniThrowException(env, "java/lang/IllegalArgumentException",
289 "The surface has been released");
294 env->SetIntField(thiz, fields.surface_texture, (int)new_st.get());
296 // This will fail if the media player has not been initialized yet. This
297 // can be the case if setDisplay() on MediaPlayer.java has been called
298 // before setDataSource(). The redundant call to setVideoSurfaceTexture()
299 // in prepare/prepareAsync covers for this case.
300 mp->setVideoSurfaceTexture(new_st);
304 android_media_MediaPlayer_setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface)
306 setVideoSurface(env, thiz, jsurface, true /* mediaPlayerMustBeAlive */);
310 android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz)
312 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
314 jniThrowException(env, "java/lang/IllegalStateException", NULL);
318 // Handle the case where the display surface was set before the mp was
319 // initialized. We try again to make it stick.
320 sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
321 mp->setVideoSurfaceTexture(st);
323 process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
327 android_media_MediaPlayer_prepareAsync(JNIEnv *env, jobject thiz)
329 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
331 jniThrowException(env, "java/lang/IllegalStateException", NULL);
335 // Handle the case where the display surface was set before the mp was
336 // initialized. We try again to make it stick.
337 sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
338 mp->setVideoSurfaceTexture(st);
340 process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
344 android_media_MediaPlayer_start(JNIEnv *env, jobject thiz)
347 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
349 jniThrowException(env, "java/lang/IllegalStateException", NULL);
352 process_media_player_call( env, thiz, mp->start(), NULL, NULL );
356 android_media_MediaPlayer_stop(JNIEnv *env, jobject thiz)
359 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
361 jniThrowException(env, "java/lang/IllegalStateException", NULL);
364 process_media_player_call( env, thiz, mp->stop(), NULL, NULL );
368 android_media_MediaPlayer_pause(JNIEnv *env, jobject thiz)
371 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
373 jniThrowException(env, "java/lang/IllegalStateException", NULL);
376 process_media_player_call( env, thiz, mp->pause(), NULL, NULL );
380 android_media_MediaPlayer_isPlaying(JNIEnv *env, jobject thiz)
382 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
384 jniThrowException(env, "java/lang/IllegalStateException", NULL);
387 const jboolean is_playing = mp->isPlaying();
389 ALOGV("isPlaying: %d", is_playing);
394 android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, int msec)
396 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
398 jniThrowException(env, "java/lang/IllegalStateException", NULL);
401 ALOGV("seekTo: %d(msec)", msec);
402 process_media_player_call( env, thiz, mp->seekTo(msec), NULL, NULL );
406 android_media_MediaPlayer_getVideoWidth(JNIEnv *env, jobject thiz)
408 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
410 jniThrowException(env, "java/lang/IllegalStateException", NULL);
414 if (0 != mp->getVideoWidth(&w)) {
415 ALOGE("getVideoWidth failed");
418 ALOGV("getVideoWidth: %d", w);
423 android_media_MediaPlayer_getVideoHeight(JNIEnv *env, jobject thiz)
425 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
427 jniThrowException(env, "java/lang/IllegalStateException", NULL);
431 if (0 != mp->getVideoHeight(&h)) {
432 ALOGE("getVideoHeight failed");
435 ALOGV("getVideoHeight: %d", h);
441 android_media_MediaPlayer_getCurrentPosition(JNIEnv *env, jobject thiz)
443 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
445 jniThrowException(env, "java/lang/IllegalStateException", NULL);
449 process_media_player_call( env, thiz, mp->getCurrentPosition(&msec), NULL, NULL );
450 ALOGV("getCurrentPosition: %d (msec)", msec);
455 android_media_MediaPlayer_getDuration(JNIEnv *env, jobject thiz)
457 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
459 jniThrowException(env, "java/lang/IllegalStateException", NULL);
463 process_media_player_call( env, thiz, mp->getDuration(&msec), NULL, NULL );
464 ALOGV("getDuration: %d (msec)", msec);
469 android_media_MediaPlayer_reset(JNIEnv *env, jobject thiz)
472 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
474 jniThrowException(env, "java/lang/IllegalStateException", NULL);
477 process_media_player_call( env, thiz, mp->reset(), NULL, NULL );
481 android_media_MediaPlayer_setAudioStreamType(JNIEnv *env, jobject thiz, int streamtype)
483 ALOGV("setAudioStreamType: %d", streamtype);
484 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
486 jniThrowException(env, "java/lang/IllegalStateException", NULL);
489 process_media_player_call( env, thiz, mp->setAudioStreamType((audio_stream_type_t) streamtype) , NULL, NULL );
493 android_media_MediaPlayer_setLooping(JNIEnv *env, jobject thiz, jboolean looping)
495 ALOGV("setLooping: %d", looping);
496 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
498 jniThrowException(env, "java/lang/IllegalStateException", NULL);
501 process_media_player_call( env, thiz, mp->setLooping(looping), NULL, NULL );
505 android_media_MediaPlayer_isLooping(JNIEnv *env, jobject thiz)
508 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
510 jniThrowException(env, "java/lang/IllegalStateException", NULL);
513 return mp->isLooping();
517 android_media_MediaPlayer_setVolume(JNIEnv *env, jobject thiz, float leftVolume, float rightVolume)
519 ALOGV("setVolume: left %f right %f", leftVolume, rightVolume);
520 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
522 jniThrowException(env, "java/lang/IllegalStateException", NULL);
525 process_media_player_call( env, thiz, mp->setVolume(leftVolume, rightVolume), NULL, NULL );
530 android_media_MediaPlayer_getFrameAt(JNIEnv *env, jobject thiz, jint msec)
536 // Sends the request and reply parcels to the media player via the
539 android_media_MediaPlayer_invoke(JNIEnv *env, jobject thiz,
540 jobject java_request, jobject java_reply)
542 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
543 if (media_player == NULL ) {
544 jniThrowException(env, "java/lang/IllegalStateException", NULL);
545 return UNKNOWN_ERROR;
548 Parcel *request = parcelForJavaObject(env, java_request);
549 Parcel *reply = parcelForJavaObject(env, java_reply);
551 // Don't use process_media_player_call which use the async loop to
552 // report errors, instead returns the status.
553 return media_player->invoke(*request, reply);
556 // Sends the new filter to the client.
558 android_media_MediaPlayer_setMetadataFilter(JNIEnv *env, jobject thiz, jobject request)
560 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
561 if (media_player == NULL ) {
562 jniThrowException(env, "java/lang/IllegalStateException", NULL);
563 return UNKNOWN_ERROR;
566 Parcel *filter = parcelForJavaObject(env, request);
568 if (filter == NULL ) {
569 jniThrowException(env, "java/lang/RuntimeException", "Filter is null");
570 return UNKNOWN_ERROR;
573 return media_player->setMetadataFilter(*filter);
577 android_media_MediaPlayer_getMetadata(JNIEnv *env, jobject thiz, jboolean update_only,
578 jboolean apply_filter, jobject reply)
580 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
581 if (media_player == NULL ) {
582 jniThrowException(env, "java/lang/IllegalStateException", NULL);
586 Parcel *metadata = parcelForJavaObject(env, reply);
588 if (metadata == NULL ) {
589 jniThrowException(env, "java/lang/RuntimeException", "Reply parcel is null");
593 metadata->freeData();
594 // On return metadata is positioned at the beginning of the
595 // metadata. Note however that the parcel actually starts with the
596 // return code so you should not rewind the parcel using
597 // setDataPosition(0).
598 return media_player->getMetadata(update_only, apply_filter, metadata) == OK;
601 // This function gets some field IDs, which in turn causes class initialization.
602 // It is called from a static block in MediaPlayer, which won't run until the
603 // first time an instance of this class is used.
605 android_media_MediaPlayer_native_init(JNIEnv *env)
609 clazz = env->FindClass("android/media/MediaPlayer");
614 fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
615 if (fields.context == NULL) {
619 fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
620 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
621 if (fields.post_event == NULL) {
625 fields.surface_texture = env->GetFieldID(clazz, "mNativeSurfaceTexture", "I");
626 if (fields.surface_texture == NULL) {
630 clazz = env->FindClass("android/net/ProxyProperties");
635 fields.proxyConfigGetHost =
636 env->GetMethodID(clazz, "getHost", "()Ljava/lang/String;");
638 fields.proxyConfigGetPort =
639 env->GetMethodID(clazz, "getPort", "()I");
641 fields.proxyConfigGetExclusionList =
642 env->GetMethodID(clazz, "getExclusionList", "()Ljava/lang/String;");
646 android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
648 ALOGV("native_setup");
649 sp<MediaPlayer> mp = new MediaPlayer();
651 jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
655 // create new listener and give it to MediaPlayer
656 sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
657 mp->setListener(listener);
659 // Stow our new C++ MediaPlayer in an opaque field in the Java object.
660 setMediaPlayer(env, thiz, mp);
664 android_media_MediaPlayer_release(JNIEnv *env, jobject thiz)
667 decVideoSurfaceRef(env, thiz);
668 sp<MediaPlayer> mp = setMediaPlayer(env, thiz, 0);
670 // this prevents native callbacks after the object is released
677 android_media_MediaPlayer_native_finalize(JNIEnv *env, jobject thiz)
679 ALOGV("native_finalize");
680 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
682 ALOGW("MediaPlayer finalized without being released");
684 android_media_MediaPlayer_release(env, thiz);
687 static void android_media_MediaPlayer_set_audio_session_id(JNIEnv *env, jobject thiz, jint sessionId) {
688 ALOGV("set_session_id(): %d", sessionId);
689 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
691 jniThrowException(env, "java/lang/IllegalStateException", NULL);
694 process_media_player_call( env, thiz, mp->setAudioSessionId(sessionId), NULL, NULL );
697 static jint android_media_MediaPlayer_get_audio_session_id(JNIEnv *env, jobject thiz) {
698 ALOGV("get_session_id()");
699 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
701 jniThrowException(env, "java/lang/IllegalStateException", NULL);
705 return mp->getAudioSessionId();
709 android_media_MediaPlayer_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level)
711 ALOGV("setAuxEffectSendLevel: level %f", level);
712 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
714 jniThrowException(env, "java/lang/IllegalStateException", NULL);
717 process_media_player_call( env, thiz, mp->setAuxEffectSendLevel(level), NULL, NULL );
720 static void android_media_MediaPlayer_attachAuxEffect(JNIEnv *env, jobject thiz, jint effectId) {
721 ALOGV("attachAuxEffect(): %d", effectId);
722 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
724 jniThrowException(env, "java/lang/IllegalStateException", NULL);
727 process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL );
731 android_media_MediaPlayer_pullBatteryData(JNIEnv *env, jobject thiz, jobject java_reply)
733 sp<IBinder> binder = defaultServiceManager()->getService(String16("media.player"));
734 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
735 if (service.get() == NULL) {
736 jniThrowException(env, "java/lang/RuntimeException", "cannot get MediaPlayerService");
737 return UNKNOWN_ERROR;
740 Parcel *reply = parcelForJavaObject(env, java_reply);
742 return service->pullBatteryData(reply);
746 android_media_MediaPlayer_setRetransmitEndpoint(JNIEnv *env, jobject thiz,
747 jstring addrString, jint port) {
748 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
750 jniThrowException(env, "java/lang/IllegalStateException", NULL);
751 return INVALID_OPERATION;
754 const char *cAddrString = NULL;
756 if (NULL != addrString) {
757 cAddrString = env->GetStringUTFChars(addrString, NULL);
758 if (cAddrString == NULL) { // Out of memory
762 ALOGV("setRetransmitEndpoint: %s:%d",
763 cAddrString ? cAddrString : "(null)", port);
766 if (cAddrString && (port > 0xFFFF)) {
769 ret = mp->setRetransmitEndpoint(cAddrString,
770 static_cast<uint16_t>(port));
773 if (NULL != addrString) {
774 env->ReleaseStringUTFChars(addrString, cAddrString);
777 if (ret == INVALID_OPERATION ) {
778 jniThrowException(env, "java/lang/IllegalStateException", NULL);
785 android_media_MediaPlayer_setParameter(JNIEnv *env, jobject thiz, jint key, jobject java_request)
787 ALOGV("setParameter: key %d", key);
788 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
790 jniThrowException(env, "java/lang/IllegalStateException", NULL);
794 Parcel *request = parcelForJavaObject(env, java_request);
795 status_t err = mp->setParameter(key, *request);
804 android_media_MediaPlayer_getParameter(JNIEnv *env, jobject thiz, jint key, jobject java_reply)
806 ALOGV("getParameter: key %d", key);
807 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
809 jniThrowException(env, "java/lang/IllegalStateException", NULL);
813 Parcel *reply = parcelForJavaObject(env, java_reply);
814 process_media_player_call(env, thiz, mp->getParameter(key, reply), NULL, NULL );
818 android_media_MediaPlayer_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject java_player)
820 ALOGV("setNextMediaPlayer");
821 sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
822 if (thisplayer == NULL) {
823 jniThrowException(env, "java/lang/IllegalStateException", "This player not initialized");
826 sp<MediaPlayer> nextplayer = (java_player == NULL) ? NULL : getMediaPlayer(env, java_player);
827 if (nextplayer == NULL && java_player != NULL) {
828 jniThrowException(env, "java/lang/IllegalStateException", "That player not initialized");
832 if (nextplayer == thisplayer) {
833 jniThrowException(env, "java/lang/IllegalArgumentException", "Next player can't be self");
836 // tie the two players together
837 process_media_player_call(
838 env, thiz, thisplayer->setNextMediaPlayer(nextplayer),
839 "java/lang/IllegalArgumentException",
840 "setNextMediaPlayer failed." );
845 android_media_MediaPlayer_updateProxyConfig(
846 JNIEnv *env, jobject thiz, jobject proxyProps)
848 ALOGV("updateProxyConfig");
849 sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
850 if (thisplayer == NULL) {
854 if (proxyProps == NULL) {
855 thisplayer->updateProxyConfig(
856 NULL /* host */, 0 /* port */, NULL /* exclusionList */);
858 jstring hostObj = (jstring)env->CallObjectMethod(
859 proxyProps, fields.proxyConfigGetHost);
861 const char *host = env->GetStringUTFChars(hostObj, NULL);
863 int port = env->CallIntMethod(proxyProps, fields.proxyConfigGetPort);
865 jstring exclusionListObj = (jstring)env->CallObjectMethod(
866 proxyProps, fields.proxyConfigGetExclusionList);
868 const char *exclusionList =
869 env->GetStringUTFChars(exclusionListObj, NULL);
871 if (host != NULL && exclusionListObj != NULL) {
872 thisplayer->updateProxyConfig(host, port, exclusionList);
875 if (exclusionList != NULL) {
876 env->ReleaseStringUTFChars(exclusionListObj, exclusionList);
877 exclusionList = NULL;
881 env->ReleaseStringUTFChars(hostObj, host);
887 // ----------------------------------------------------------------------------
889 static JNINativeMethod gMethods[] = {
892 "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
893 (void *)android_media_MediaPlayer_setDataSourceAndHeaders
896 {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
897 {"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface},
898 {"prepare", "()V", (void *)android_media_MediaPlayer_prepare},
899 {"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync},
900 {"_start", "()V", (void *)android_media_MediaPlayer_start},
901 {"_stop", "()V", (void *)android_media_MediaPlayer_stop},
902 {"getVideoWidth", "()I", (void *)android_media_MediaPlayer_getVideoWidth},
903 {"getVideoHeight", "()I", (void *)android_media_MediaPlayer_getVideoHeight},
904 {"seekTo", "(I)V", (void *)android_media_MediaPlayer_seekTo},
905 {"_pause", "()V", (void *)android_media_MediaPlayer_pause},
906 {"isPlaying", "()Z", (void *)android_media_MediaPlayer_isPlaying},
907 {"getCurrentPosition", "()I", (void *)android_media_MediaPlayer_getCurrentPosition},
908 {"getDuration", "()I", (void *)android_media_MediaPlayer_getDuration},
909 {"_release", "()V", (void *)android_media_MediaPlayer_release},
910 {"_reset", "()V", (void *)android_media_MediaPlayer_reset},
911 {"setAudioStreamType", "(I)V", (void *)android_media_MediaPlayer_setAudioStreamType},
912 {"setLooping", "(Z)V", (void *)android_media_MediaPlayer_setLooping},
913 {"isLooping", "()Z", (void *)android_media_MediaPlayer_isLooping},
914 {"setVolume", "(FF)V", (void *)android_media_MediaPlayer_setVolume},
915 {"getFrameAt", "(I)Landroid/graphics/Bitmap;", (void *)android_media_MediaPlayer_getFrameAt},
916 {"native_invoke", "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
917 {"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter},
918 {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata},
919 {"native_init", "()V", (void *)android_media_MediaPlayer_native_init},
920 {"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup},
921 {"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
922 {"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id},
923 {"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id},
924 {"setAuxEffectSendLevel", "(F)V", (void *)android_media_MediaPlayer_setAuxEffectSendLevel},
925 {"attachAuxEffect", "(I)V", (void *)android_media_MediaPlayer_attachAuxEffect},
926 {"native_pullBatteryData", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_pullBatteryData},
927 {"setParameter", "(ILandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_setParameter},
928 {"getParameter", "(ILandroid/os/Parcel;)V", (void *)android_media_MediaPlayer_getParameter},
929 {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I", (void *)android_media_MediaPlayer_setRetransmitEndpoint},
930 {"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer},
931 {"updateProxyConfig", "(Landroid/net/ProxyProperties;)V", (void *)android_media_MediaPlayer_updateProxyConfig},
934 static const char* const kClassPathName = "android/media/MediaPlayer";
936 // This function only registers the native methods
937 static int register_android_media_MediaPlayer(JNIEnv *env)
939 return AndroidRuntime::registerNativeMethods(env,
940 "android/media/MediaPlayer", gMethods, NELEM(gMethods));
943 extern int register_android_media_Crypto(JNIEnv *env);
944 extern int register_android_media_Drm(JNIEnv *env);
945 extern int register_android_media_MediaCodec(JNIEnv *env);
946 extern int register_android_media_MediaExtractor(JNIEnv *env);
947 extern int register_android_media_MediaCodecList(JNIEnv *env);
948 extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
949 extern int register_android_media_MediaMuxer(JNIEnv *env);
950 extern int register_android_media_MediaRecorder(JNIEnv *env);
951 extern int register_android_media_MediaScanner(JNIEnv *env);
952 extern int register_android_media_ResampleInputStream(JNIEnv *env);
953 extern int register_android_media_MediaProfiles(JNIEnv *env);
954 extern int register_android_media_AmrInputStream(JNIEnv *env);
955 extern int register_android_mtp_MtpDatabase(JNIEnv *env);
956 extern int register_android_mtp_MtpDevice(JNIEnv *env);
957 extern int register_android_mtp_MtpServer(JNIEnv *env);
959 jint JNI_OnLoad(JavaVM* vm, void* reserved)
964 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
965 ALOGE("ERROR: GetEnv failed\n");
970 if (register_android_media_MediaPlayer(env) < 0) {
971 ALOGE("ERROR: MediaPlayer native registration failed\n");
975 if (register_android_media_MediaRecorder(env) < 0) {
976 ALOGE("ERROR: MediaRecorder native registration failed\n");
980 if (register_android_media_MediaScanner(env) < 0) {
981 ALOGE("ERROR: MediaScanner native registration failed\n");
985 if (register_android_media_MediaMetadataRetriever(env) < 0) {
986 ALOGE("ERROR: MediaMetadataRetriever native registration failed\n");
990 if (register_android_media_AmrInputStream(env) < 0) {
991 ALOGE("ERROR: AmrInputStream native registration failed\n");
995 if (register_android_media_ResampleInputStream(env) < 0) {
996 ALOGE("ERROR: ResampleInputStream native registration failed\n");
1000 if (register_android_media_MediaProfiles(env) < 0) {
1001 ALOGE("ERROR: MediaProfiles native registration failed");
1005 if (register_android_mtp_MtpDatabase(env) < 0) {
1006 ALOGE("ERROR: MtpDatabase native registration failed");
1010 if (register_android_mtp_MtpDevice(env) < 0) {
1011 ALOGE("ERROR: MtpDevice native registration failed");
1015 if (register_android_mtp_MtpServer(env) < 0) {
1016 ALOGE("ERROR: MtpServer native registration failed");
1020 if (register_android_media_MediaCodec(env) < 0) {
1021 ALOGE("ERROR: MediaCodec native registration failed");
1025 if (register_android_media_MediaExtractor(env) < 0) {
1026 ALOGE("ERROR: MediaCodec native registration failed");
1030 if (register_android_media_MediaMuxer(env) < 0) {
1031 ALOGE("ERROR: MediaMuxer native registration failed");
1035 if (register_android_media_MediaCodecList(env) < 0) {
1036 ALOGE("ERROR: MediaCodec native registration failed");
1040 if (register_android_media_Crypto(env) < 0) {
1041 ALOGE("ERROR: MediaCodec native registration failed");
1045 if (register_android_media_Drm(env) < 0) {
1046 ALOGE("ERROR: MediaDrm native registration failed");
1050 /* success -- return valid version number */
1051 result = JNI_VERSION_1_4;