blob: 7c607ea367180032aa0b6d5f6c9ec9b57e176e82 [file] [log] [blame]
James Dongc371a022011-04-06 12:16:07 -07001/*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002**
3** Copyright 2007, The Android Open Source Project
4**
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
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
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.
16*/
17
18//#define LOG_NDEBUG 0
19#define LOG_TAG "MediaPlayer-JNI"
20#include "utils/Log.h"
21
22#include <media/mediaplayer.h>
Nicolas Catania20cb94e2009-05-12 23:25:55 -070023#include <media/MediaPlayerInterface.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024#include <stdio.h>
25#include <assert.h>
26#include <limits.h>
27#include <unistd.h>
28#include <fcntl.h>
29#include <utils/threads.h>
30#include "jni.h"
31#include "JNIHelp.h"
32#include "android_runtime/AndroidRuntime.h"
Ted Bonkenburg1ee60112011-07-26 09:51:18 -070033#include "android_runtime/android_view_Surface.h"
The Android Open Source Project4df24232009-03-05 14:34:35 -080034#include "utils/Errors.h" // for status_t
Andreas Huber25643002010-01-28 11:19:57 -080035#include "utils/KeyedVector.h"
36#include "utils/String8.h"
James Dong79f407c2011-05-05 12:50:04 -070037#include "android_media_Utils.h"
38
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080039#include "android_os_Parcel.h"
Nicolas Catania20cb94e2009-05-12 23:25:55 -070040#include "android_util_Binder.h"
41#include <binder/Parcel.h>
Andy McFaddend47f7d82012-12-18 09:48:38 -080042#include <gui/IGraphicBufferProducer.h>
Mathias Agopian8335f1c2012-02-25 18:48:35 -080043#include <gui/Surface.h>
Gloria Wangd211f412011-02-19 18:37:57 -080044#include <binder/IPCThreadState.h>
45#include <binder/IServiceManager.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046
47// ----------------------------------------------------------------------------
48
49using namespace android;
50
51// ----------------------------------------------------------------------------
52
53struct fields_t {
54 jfieldID context;
Ted Bonkenburg1ee60112011-07-26 09:51:18 -070055 jfieldID surface_texture;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056
57 jmethodID post_event;
Andreas Huberd5f9fa52013-05-28 14:39:39 -070058
59 jmethodID proxyConfigGetHost;
60 jmethodID proxyConfigGetPort;
61 jmethodID proxyConfigGetExclusionList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062};
63static fields_t fields;
64
65static Mutex sLock;
66
67// ----------------------------------------------------------------------------
68// ref-counted object for callbacks
69class JNIMediaPlayerListener: public MediaPlayerListener
70{
71public:
72 JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
73 ~JNIMediaPlayerListener();
Gloria Wang162ee492011-04-11 17:23:27 -070074 virtual void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075private:
76 JNIMediaPlayerListener();
77 jclass mClass; // Reference to MediaPlayer class
78 jobject mObject; // Weak ref to MediaPlayer Java object to call on
79};
80
81JNIMediaPlayerListener::JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
82{
83
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);
87 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +000088 ALOGE("Can't find android/media/MediaPlayer");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 jniThrowException(env, "java/lang/Exception", NULL);
90 return;
91 }
92 mClass = (jclass)env->NewGlobalRef(clazz);
93
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);
97}
98
99JNIMediaPlayerListener::~JNIMediaPlayerListener()
100{
101 // remove global references
102 JNIEnv *env = AndroidRuntime::getJNIEnv();
103 env->DeleteGlobalRef(mObject);
104 env->DeleteGlobalRef(mClass);
105}
106
Gloria Wang162ee492011-04-11 17:23:27 -0700107void JNIMediaPlayerListener::notify(int msg, int ext1, int ext2, const Parcel *obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108{
109 JNIEnv *env = AndroidRuntime::getJNIEnv();
Gloria Wang162ee492011-04-11 17:23:27 -0700110 if (obj && obj->dataSize() > 0) {
Insun Kang333c0992012-07-10 12:47:03 +0900111 jobject jParcel = createJavaParcelObject(env);
112 if (jParcel != NULL) {
113 Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
Insun Kang89020972012-05-01 14:13:19 +0900114 nativeParcel->setData(obj->data(), obj->dataSize());
Gloria Wang162ee492011-04-11 17:23:27 -0700115 env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
Insun Kang333c0992012-07-10 12:47:03 +0900116 msg, ext1, ext2, jParcel);
Gloria Wang162ee492011-04-11 17:23:27 -0700117 }
118 } else {
119 env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
120 msg, ext1, ext2, NULL);
121 }
Insun Kang89020972012-05-01 14:13:19 +0900122 if (env->ExceptionCheck()) {
123 ALOGW("An exception occurred while notifying an event.");
124 LOGW_EX(env);
125 env->ExceptionClear();
126 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127}
128
129// ----------------------------------------------------------------------------
130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131static sp<MediaPlayer> getMediaPlayer(JNIEnv* env, jobject thiz)
132{
133 Mutex::Autolock l(sLock);
134 MediaPlayer* const p = (MediaPlayer*)env->GetIntField(thiz, fields.context);
135 return sp<MediaPlayer>(p);
136}
137
138static sp<MediaPlayer> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaPlayer>& player)
139{
140 Mutex::Autolock l(sLock);
141 sp<MediaPlayer> old = (MediaPlayer*)env->GetIntField(thiz, fields.context);
142 if (player.get()) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800143 player->incStrong((void*)setMediaPlayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 }
145 if (old != 0) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800146 old->decStrong((void*)setMediaPlayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 }
148 env->SetIntField(thiz, fields.context, (int)player.get());
149 return old;
150}
151
Nicolas Catania32f82772009-06-11 16:33:49 -0700152// 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154// opStatus is not OK, this method throws the given exception to the client
155// application.
156static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStatus, const char* exception, const char *message)
157{
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);
162 }
163 } else { // Throw exception!
164 if ( opStatus == (status_t) INVALID_OPERATION ) {
165 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Dave Burkefc301b02011-08-30 14:39:17 +0100166 } else if ( opStatus == (status_t) PERMISSION_DENIED ) {
167 jniThrowException(env, "java/lang/SecurityException", NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 } 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);
172 } else {
173 char msg[256];
174 // append the status code to the message
175 sprintf(msg, "%s: status=0x%X", message, opStatus);
176 jniThrowException( env, exception, msg);
177 }
178 }
179 }
180}
181
182static void
Andreas Huber25643002010-01-28 11:19:57 -0800183android_media_MediaPlayer_setDataSourceAndHeaders(
James Dong17524dc2011-05-04 13:41:58 -0700184 JNIEnv *env, jobject thiz, jstring path,
185 jobjectArray keys, jobjectArray values) {
186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
188 if (mp == NULL ) {
189 jniThrowException(env, "java/lang/IllegalStateException", NULL);
190 return;
191 }
192
193 if (path == NULL) {
194 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
195 return;
196 }
197
James Dongc371a022011-04-06 12:16:07 -0700198 const char *tmp = env->GetStringUTFChars(path, NULL);
199 if (tmp == NULL) { // Out of memory
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 return;
201 }
Steve Block71f2cf12011-10-20 11:56:00 +0100202 ALOGV("setDataSource: path %s", tmp);
Andreas Huber25643002010-01-28 11:19:57 -0800203
James Dongc371a022011-04-06 12:16:07 -0700204 String8 pathStr(tmp);
205 env->ReleaseStringUTFChars(path, tmp);
206 tmp = NULL;
207
James Dong17524dc2011-05-04 13:41:58 -0700208 // We build a KeyedVector out of the key and val arrays
Andreas Huber25643002010-01-28 11:19:57 -0800209 KeyedVector<String8, String8> headersVector;
James Dong79f407c2011-05-05 12:50:04 -0700210 if (!ConvertKeyValueArraysToKeyedVector(
211 env, keys, values, &headersVector)) {
212 return;
Andreas Huber25643002010-01-28 11:19:57 -0800213 }
214
Andreas Huber25643002010-01-28 11:19:57 -0800215 status_t opStatus =
216 mp->setDataSource(
James Dongc371a022011-04-06 12:16:07 -0700217 pathStr,
James Dong79f407c2011-05-05 12:50:04 -0700218 headersVector.size() > 0? &headersVector : NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219
Andreas Huber25643002010-01-28 11:19:57 -0800220 process_media_player_call(
221 env, thiz, opStatus, "java/io/IOException",
222 "setDataSource failed." );
223}
224
225static void
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
227{
228 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
229 if (mp == NULL ) {
230 jniThrowException(env, "java/lang/IllegalStateException", NULL);
231 return;
232 }
233
234 if (fileDescriptor == NULL) {
235 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
236 return;
237 }
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700238 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
Steve Block71f2cf12011-10-20 11:56:00 +0100239 ALOGV("setDataSourceFD: fd %d", fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
241}
242
Andy McFaddend47f7d82012-12-18 09:48:38 -0800243static sp<IGraphicBufferProducer>
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700244getVideoSurfaceTexture(JNIEnv* env, jobject thiz) {
Andy McFaddend47f7d82012-12-18 09:48:38 -0800245 IGraphicBufferProducer * const p = (IGraphicBufferProducer*)env->GetIntField(thiz, fields.surface_texture);
246 return sp<IGraphicBufferProducer>(p);
Dave Sparks8b0b1742009-05-29 09:01:20 -0700247}
248
249static void
Gloria Wangd59310d2011-09-14 13:59:45 -0700250decVideoSurfaceRef(JNIEnv *env, jobject thiz)
251{
Gloria Wange828beb2011-09-15 15:28:43 -0700252 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
253 if (mp == NULL) {
254 return;
255 }
256
Andy McFaddend47f7d82012-12-18 09:48:38 -0800257 sp<IGraphicBufferProducer> old_st = getVideoSurfaceTexture(env, thiz);
Gloria Wangd59310d2011-09-14 13:59:45 -0700258 if (old_st != NULL) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800259 old_st->decStrong((void*)decVideoSurfaceRef);
Gloria Wangd59310d2011-09-14 13:59:45 -0700260 }
261}
262
263static void
James Dong43ef9132011-08-12 11:33:27 -0700264setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface, jboolean mediaPlayerMustBeAlive)
Dave Sparks8b0b1742009-05-29 09:01:20 -0700265{
266 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
James Dong43ef9132011-08-12 11:33:27 -0700267 if (mp == NULL) {
268 if (mediaPlayerMustBeAlive) {
269 jniThrowException(env, "java/lang/IllegalStateException", NULL);
270 }
Dave Sparks8b0b1742009-05-29 09:01:20 -0700271 return;
272 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700273
Gloria Wangd59310d2011-09-14 13:59:45 -0700274 decVideoSurfaceRef(env, thiz);
275
Andy McFaddend47f7d82012-12-18 09:48:38 -0800276 sp<IGraphicBufferProducer> new_st;
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700277 if (jsurface) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700278 sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
Jamie Gennisf76afc82011-10-14 19:06:55 -0700279 if (surface != NULL) {
Mathias Agopian52800612013-02-14 17:11:20 -0800280 new_st = surface->getIGraphicBufferProducer();
James Dong097922b2012-10-04 09:16:40 -0700281 if (new_st == NULL) {
282 jniThrowException(env, "java/lang/IllegalArgumentException",
283 "The surface does not have a binding SurfaceTexture!");
284 return;
285 }
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800286 new_st->incStrong((void*)decVideoSurfaceRef);
Jamie Gennisf76afc82011-10-14 19:06:55 -0700287 } else {
288 jniThrowException(env, "java/lang/IllegalArgumentException",
289 "The surface has been released");
290 return;
291 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700292 }
Gloria Wangd59310d2011-09-14 13:59:45 -0700293
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700294 env->SetIntField(thiz, fields.surface_texture, (int)new_st.get());
295
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);
Dave Sparks8b0b1742009-05-29 09:01:20 -0700301}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302
303static void
James Dong43ef9132011-08-12 11:33:27 -0700304android_media_MediaPlayer_setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface)
305{
306 setVideoSurface(env, thiz, jsurface, true /* mediaPlayerMustBeAlive */);
307}
308
309static void
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz)
311{
312 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
313 if (mp == NULL ) {
314 jniThrowException(env, "java/lang/IllegalStateException", NULL);
315 return;
316 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700317
318 // Handle the case where the display surface was set before the mp was
319 // initialized. We try again to make it stick.
Andy McFaddend47f7d82012-12-18 09:48:38 -0800320 sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700321 mp->setVideoSurfaceTexture(st);
322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
324}
325
326static void
327android_media_MediaPlayer_prepareAsync(JNIEnv *env, jobject thiz)
328{
329 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
330 if (mp == NULL ) {
331 jniThrowException(env, "java/lang/IllegalStateException", NULL);
332 return;
333 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700334
335 // Handle the case where the display surface was set before the mp was
336 // initialized. We try again to make it stick.
Andy McFaddend47f7d82012-12-18 09:48:38 -0800337 sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700338 mp->setVideoSurfaceTexture(st);
339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
341}
342
343static void
344android_media_MediaPlayer_start(JNIEnv *env, jobject thiz)
345{
Steve Block71f2cf12011-10-20 11:56:00 +0100346 ALOGV("start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
348 if (mp == NULL ) {
349 jniThrowException(env, "java/lang/IllegalStateException", NULL);
350 return;
351 }
352 process_media_player_call( env, thiz, mp->start(), NULL, NULL );
353}
354
355static void
356android_media_MediaPlayer_stop(JNIEnv *env, jobject thiz)
357{
Steve Block71f2cf12011-10-20 11:56:00 +0100358 ALOGV("stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
360 if (mp == NULL ) {
361 jniThrowException(env, "java/lang/IllegalStateException", NULL);
362 return;
363 }
Nicolas Catania32f82772009-06-11 16:33:49 -0700364 process_media_player_call( env, thiz, mp->stop(), NULL, NULL );
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365}
366
367static void
368android_media_MediaPlayer_pause(JNIEnv *env, jobject thiz)
369{
Steve Block71f2cf12011-10-20 11:56:00 +0100370 ALOGV("pause");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
372 if (mp == NULL ) {
373 jniThrowException(env, "java/lang/IllegalStateException", NULL);
374 return;
375 }
376 process_media_player_call( env, thiz, mp->pause(), NULL, NULL );
377}
378
379static jboolean
380android_media_MediaPlayer_isPlaying(JNIEnv *env, jobject thiz)
381{
382 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
383 if (mp == NULL ) {
384 jniThrowException(env, "java/lang/IllegalStateException", NULL);
385 return false;
386 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800387 const jboolean is_playing = mp->isPlaying();
388
Steve Block71f2cf12011-10-20 11:56:00 +0100389 ALOGV("isPlaying: %d", is_playing);
The Android Open Source Project4df24232009-03-05 14:34:35 -0800390 return is_playing;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391}
392
393static void
394android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, int msec)
395{
396 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
397 if (mp == NULL ) {
398 jniThrowException(env, "java/lang/IllegalStateException", NULL);
399 return;
400 }
Steve Block71f2cf12011-10-20 11:56:00 +0100401 ALOGV("seekTo: %d(msec)", msec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 process_media_player_call( env, thiz, mp->seekTo(msec), NULL, NULL );
403}
404
405static int
406android_media_MediaPlayer_getVideoWidth(JNIEnv *env, jobject thiz)
407{
408 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
409 if (mp == NULL ) {
410 jniThrowException(env, "java/lang/IllegalStateException", NULL);
411 return 0;
412 }
413 int w;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800414 if (0 != mp->getVideoWidth(&w)) {
Steve Block3762c312012-01-06 19:20:56 +0000415 ALOGE("getVideoWidth failed");
The Android Open Source Project4df24232009-03-05 14:34:35 -0800416 w = 0;
417 }
Steve Block71f2cf12011-10-20 11:56:00 +0100418 ALOGV("getVideoWidth: %d", w);
The Android Open Source Project4df24232009-03-05 14:34:35 -0800419 return w;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420}
421
422static int
423android_media_MediaPlayer_getVideoHeight(JNIEnv *env, jobject thiz)
424{
425 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
426 if (mp == NULL ) {
427 jniThrowException(env, "java/lang/IllegalStateException", NULL);
428 return 0;
429 }
430 int h;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800431 if (0 != mp->getVideoHeight(&h)) {
Steve Block3762c312012-01-06 19:20:56 +0000432 ALOGE("getVideoHeight failed");
The Android Open Source Project4df24232009-03-05 14:34:35 -0800433 h = 0;
434 }
Steve Block71f2cf12011-10-20 11:56:00 +0100435 ALOGV("getVideoHeight: %d", h);
The Android Open Source Project4df24232009-03-05 14:34:35 -0800436 return h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437}
438
439
440static int
441android_media_MediaPlayer_getCurrentPosition(JNIEnv *env, jobject thiz)
442{
443 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
444 if (mp == NULL ) {
445 jniThrowException(env, "java/lang/IllegalStateException", NULL);
446 return 0;
447 }
448 int msec;
449 process_media_player_call( env, thiz, mp->getCurrentPosition(&msec), NULL, NULL );
Steve Block71f2cf12011-10-20 11:56:00 +0100450 ALOGV("getCurrentPosition: %d (msec)", msec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 return msec;
452}
453
454static int
455android_media_MediaPlayer_getDuration(JNIEnv *env, jobject thiz)
456{
457 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
458 if (mp == NULL ) {
459 jniThrowException(env, "java/lang/IllegalStateException", NULL);
460 return 0;
461 }
462 int msec;
463 process_media_player_call( env, thiz, mp->getDuration(&msec), NULL, NULL );
Steve Block71f2cf12011-10-20 11:56:00 +0100464 ALOGV("getDuration: %d (msec)", msec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 return msec;
466}
467
468static void
469android_media_MediaPlayer_reset(JNIEnv *env, jobject thiz)
470{
Steve Block71f2cf12011-10-20 11:56:00 +0100471 ALOGV("reset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
473 if (mp == NULL ) {
474 jniThrowException(env, "java/lang/IllegalStateException", NULL);
475 return;
476 }
477 process_media_player_call( env, thiz, mp->reset(), NULL, NULL );
478}
479
480static void
481android_media_MediaPlayer_setAudioStreamType(JNIEnv *env, jobject thiz, int streamtype)
482{
Steve Block71f2cf12011-10-20 11:56:00 +0100483 ALOGV("setAudioStreamType: %d", streamtype);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
485 if (mp == NULL ) {
486 jniThrowException(env, "java/lang/IllegalStateException", NULL);
487 return;
488 }
Glenn Kastenbc1d77b2012-01-12 16:38:12 -0800489 process_media_player_call( env, thiz, mp->setAudioStreamType((audio_stream_type_t) streamtype) , NULL, NULL );
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490}
491
492static void
493android_media_MediaPlayer_setLooping(JNIEnv *env, jobject thiz, jboolean looping)
494{
Steve Block71f2cf12011-10-20 11:56:00 +0100495 ALOGV("setLooping: %d", looping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
497 if (mp == NULL ) {
498 jniThrowException(env, "java/lang/IllegalStateException", NULL);
499 return;
500 }
501 process_media_player_call( env, thiz, mp->setLooping(looping), NULL, NULL );
502}
503
504static jboolean
505android_media_MediaPlayer_isLooping(JNIEnv *env, jobject thiz)
506{
Steve Block71f2cf12011-10-20 11:56:00 +0100507 ALOGV("isLooping");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
509 if (mp == NULL ) {
510 jniThrowException(env, "java/lang/IllegalStateException", NULL);
511 return false;
512 }
513 return mp->isLooping();
514}
515
516static void
517android_media_MediaPlayer_setVolume(JNIEnv *env, jobject thiz, float leftVolume, float rightVolume)
518{
Steve Block71f2cf12011-10-20 11:56:00 +0100519 ALOGV("setVolume: left %f right %f", leftVolume, rightVolume);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
521 if (mp == NULL ) {
522 jniThrowException(env, "java/lang/IllegalStateException", NULL);
523 return;
524 }
525 process_media_player_call( env, thiz, mp->setVolume(leftVolume, rightVolume), NULL, NULL );
526}
527
528// FIXME: deprecated
529static jobject
530android_media_MediaPlayer_getFrameAt(JNIEnv *env, jobject thiz, jint msec)
531{
532 return NULL;
533}
534
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700535
536// Sends the request and reply parcels to the media player via the
537// binder interface.
538static jint
539android_media_MediaPlayer_invoke(JNIEnv *env, jobject thiz,
540 jobject java_request, jobject java_reply)
541{
542 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
543 if (media_player == NULL ) {
544 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700545 return UNKNOWN_ERROR;
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700546 }
547
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700548 Parcel *request = parcelForJavaObject(env, java_request);
549 Parcel *reply = parcelForJavaObject(env, java_reply);
550
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700551 // Don't use process_media_player_call which use the async loop to
552 // report errors, instead returns the status.
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700553 return media_player->invoke(*request, reply);
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700554}
555
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700556// Sends the new filter to the client.
557static jint
558android_media_MediaPlayer_setMetadataFilter(JNIEnv *env, jobject thiz, jobject request)
559{
560 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
561 if (media_player == NULL ) {
562 jniThrowException(env, "java/lang/IllegalStateException", NULL);
563 return UNKNOWN_ERROR;
564 }
565
566 Parcel *filter = parcelForJavaObject(env, request);
567
Nicolas Catania5d55c712009-07-09 09:21:33 -0700568 if (filter == NULL ) {
569 jniThrowException(env, "java/lang/RuntimeException", "Filter is null");
570 return UNKNOWN_ERROR;
571 }
572
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700573 return media_player->setMetadataFilter(*filter);
574}
575
Nicolas Catania5d55c712009-07-09 09:21:33 -0700576static jboolean
577android_media_MediaPlayer_getMetadata(JNIEnv *env, jobject thiz, jboolean update_only,
578 jboolean apply_filter, jobject reply)
579{
580 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
581 if (media_player == NULL ) {
582 jniThrowException(env, "java/lang/IllegalStateException", NULL);
583 return false;
584 }
585
586 Parcel *metadata = parcelForJavaObject(env, reply);
587
588 if (metadata == NULL ) {
589 jniThrowException(env, "java/lang/RuntimeException", "Reply parcel is null");
590 return false;
591 }
592
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;
599}
600
Marco Nelissen4935d052009-08-03 11:12:58 -0700601// 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.
604static void
605android_media_MediaPlayer_native_init(JNIEnv *env)
606{
607 jclass clazz;
608
609 clazz = env->FindClass("android/media/MediaPlayer");
610 if (clazz == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700611 return;
612 }
613
614 fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
615 if (fields.context == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700616 return;
617 }
618
619 fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
620 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
621 if (fields.post_event == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700622 return;
623 }
624
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700625 fields.surface_texture = env->GetFieldID(clazz, "mNativeSurfaceTexture", "I");
626 if (fields.surface_texture == NULL) {
Glenn Kastencc562a32011-02-08 17:26:17 -0800627 return;
628 }
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700629
630 clazz = env->FindClass("android/net/ProxyProperties");
631 if (clazz == NULL) {
632 return;
633 }
634
635 fields.proxyConfigGetHost =
636 env->GetMethodID(clazz, "getHost", "()Ljava/lang/String;");
637
638 fields.proxyConfigGetPort =
639 env->GetMethodID(clazz, "getPort", "()I");
640
641 fields.proxyConfigGetExclusionList =
642 env->GetMethodID(clazz, "getExclusionList", "()Ljava/lang/String;");
Marco Nelissen4935d052009-08-03 11:12:58 -0700643}
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645static void
646android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
647{
Steve Block71f2cf12011-10-20 11:56:00 +0100648 ALOGV("native_setup");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 sp<MediaPlayer> mp = new MediaPlayer();
650 if (mp == NULL) {
651 jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
652 return;
653 }
654
655 // create new listener and give it to MediaPlayer
656 sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
657 mp->setListener(listener);
658
659 // Stow our new C++ MediaPlayer in an opaque field in the Java object.
660 setMediaPlayer(env, thiz, mp);
661}
662
663static void
664android_media_MediaPlayer_release(JNIEnv *env, jobject thiz)
665{
Steve Block71f2cf12011-10-20 11:56:00 +0100666 ALOGV("release");
Gloria Wangd59310d2011-09-14 13:59:45 -0700667 decVideoSurfaceRef(env, thiz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 sp<MediaPlayer> mp = setMediaPlayer(env, thiz, 0);
669 if (mp != NULL) {
670 // this prevents native callbacks after the object is released
671 mp->setListener(0);
672 mp->disconnect();
673 }
674}
675
676static void
677android_media_MediaPlayer_native_finalize(JNIEnv *env, jobject thiz)
678{
Steve Block71f2cf12011-10-20 11:56:00 +0100679 ALOGV("native_finalize");
Marco Nelissen8dc20842011-09-28 09:21:11 -0700680 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
681 if (mp != NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +0000682 ALOGW("MediaPlayer finalized without being released");
Marco Nelissen8dc20842011-09-28 09:21:11 -0700683 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 android_media_MediaPlayer_release(env, thiz);
685}
686
Eric Laurent619346f2010-06-21 09:27:30 -0700687static void android_media_MediaPlayer_set_audio_session_id(JNIEnv *env, jobject thiz, jint sessionId) {
Steve Block71f2cf12011-10-20 11:56:00 +0100688 ALOGV("set_session_id(): %d", sessionId);
Eric Laurent619346f2010-06-21 09:27:30 -0700689 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
690 if (mp == NULL ) {
691 jniThrowException(env, "java/lang/IllegalStateException", NULL);
692 return;
693 }
694 process_media_player_call( env, thiz, mp->setAudioSessionId(sessionId), NULL, NULL );
695}
696
697static jint android_media_MediaPlayer_get_audio_session_id(JNIEnv *env, jobject thiz) {
Steve Block71f2cf12011-10-20 11:56:00 +0100698 ALOGV("get_session_id()");
Eric Laurent619346f2010-06-21 09:27:30 -0700699 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
700 if (mp == NULL ) {
701 jniThrowException(env, "java/lang/IllegalStateException", NULL);
702 return 0;
703 }
704
705 return mp->getAudioSessionId();
706}
707
Eric Laurent7070b362010-07-16 07:43:46 -0700708static void
709android_media_MediaPlayer_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level)
710{
Steve Block71f2cf12011-10-20 11:56:00 +0100711 ALOGV("setAuxEffectSendLevel: level %f", level);
Eric Laurent7070b362010-07-16 07:43:46 -0700712 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
713 if (mp == NULL ) {
714 jniThrowException(env, "java/lang/IllegalStateException", NULL);
715 return;
716 }
717 process_media_player_call( env, thiz, mp->setAuxEffectSendLevel(level), NULL, NULL );
718}
719
720static void android_media_MediaPlayer_attachAuxEffect(JNIEnv *env, jobject thiz, jint effectId) {
Steve Block71f2cf12011-10-20 11:56:00 +0100721 ALOGV("attachAuxEffect(): %d", effectId);
Eric Laurent7070b362010-07-16 07:43:46 -0700722 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
723 if (mp == NULL ) {
724 jniThrowException(env, "java/lang/IllegalStateException", NULL);
725 return;
726 }
727 process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL );
728}
729
Gloria Wangd211f412011-02-19 18:37:57 -0800730static jint
731android_media_MediaPlayer_pullBatteryData(JNIEnv *env, jobject thiz, jobject java_reply)
732{
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;
738 }
739
740 Parcel *reply = parcelForJavaObject(env, java_reply);
741
742 return service->pullBatteryData(reply);
743}
744
John Grossman720aa282012-02-22 15:38:35 -0800745static jint
746android_media_MediaPlayer_setRetransmitEndpoint(JNIEnv *env, jobject thiz,
747 jstring addrString, jint port) {
748 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
749 if (mp == NULL ) {
750 jniThrowException(env, "java/lang/IllegalStateException", NULL);
751 return INVALID_OPERATION;
752 }
753
754 const char *cAddrString = NULL;
755
756 if (NULL != addrString) {
757 cAddrString = env->GetStringUTFChars(addrString, NULL);
758 if (cAddrString == NULL) { // Out of memory
759 return NO_MEMORY;
760 }
761 }
762 ALOGV("setRetransmitEndpoint: %s:%d",
763 cAddrString ? cAddrString : "(null)", port);
764
765 status_t ret;
766 if (cAddrString && (port > 0xFFFF)) {
767 ret = BAD_VALUE;
768 } else {
769 ret = mp->setRetransmitEndpoint(cAddrString,
770 static_cast<uint16_t>(port));
771 }
772
773 if (NULL != addrString) {
774 env->ReleaseStringUTFChars(addrString, cAddrString);
775 }
776
777 if (ret == INVALID_OPERATION ) {
778 jniThrowException(env, "java/lang/IllegalStateException", NULL);
779 }
780
781 return ret;
782}
783
Gloria Wangd01ec6e2011-04-25 17:28:22 -0700784static jboolean
785android_media_MediaPlayer_setParameter(JNIEnv *env, jobject thiz, jint key, jobject java_request)
786{
Steve Block71f2cf12011-10-20 11:56:00 +0100787 ALOGV("setParameter: key %d", key);
Gloria Wangd01ec6e2011-04-25 17:28:22 -0700788 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
789 if (mp == NULL ) {
790 jniThrowException(env, "java/lang/IllegalStateException", NULL);
791 return false;
792 }
793
794 Parcel *request = parcelForJavaObject(env, java_request);
795 status_t err = mp->setParameter(key, *request);
796 if (err == OK) {
797 return true;
798 } else {
799 return false;
800 }
801}
802
803static void
804android_media_MediaPlayer_getParameter(JNIEnv *env, jobject thiz, jint key, jobject java_reply)
805{
Steve Block71f2cf12011-10-20 11:56:00 +0100806 ALOGV("getParameter: key %d", key);
Gloria Wangd01ec6e2011-04-25 17:28:22 -0700807 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
808 if (mp == NULL ) {
809 jniThrowException(env, "java/lang/IllegalStateException", NULL);
810 return;
811 }
812
813 Parcel *reply = parcelForJavaObject(env, java_reply);
814 process_media_player_call(env, thiz, mp->getParameter(key, reply), NULL, NULL );
815}
816
Marco Nelissen84b83202012-02-28 16:07:44 -0800817static void
818android_media_MediaPlayer_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject java_player)
819{
820 ALOGV("setNextMediaPlayer");
821 sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
822 if (thisplayer == NULL) {
823 jniThrowException(env, "java/lang/IllegalStateException", "This player not initialized");
824 return;
825 }
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");
829 return;
830 }
831
832 if (nextplayer == thisplayer) {
833 jniThrowException(env, "java/lang/IllegalArgumentException", "Next player can't be self");
834 return;
835 }
836 // tie the two players together
837 process_media_player_call(
838 env, thiz, thisplayer->setNextMediaPlayer(nextplayer),
839 "java/lang/IllegalArgumentException",
840 "setNextMediaPlayer failed." );
841 ;
842}
843
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700844static void
845android_media_MediaPlayer_updateProxyConfig(
846 JNIEnv *env, jobject thiz, jobject proxyProps)
847{
848 ALOGV("updateProxyConfig");
849 sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
850 if (thisplayer == NULL) {
851 return;
852 }
853
854 if (proxyProps == NULL) {
855 thisplayer->updateProxyConfig(
856 NULL /* host */, 0 /* port */, NULL /* exclusionList */);
857 } else {
858 jstring hostObj = (jstring)env->CallObjectMethod(
859 proxyProps, fields.proxyConfigGetHost);
860
861 const char *host = env->GetStringUTFChars(hostObj, NULL);
862
863 int port = env->CallIntMethod(proxyProps, fields.proxyConfigGetPort);
864
865 jstring exclusionListObj = (jstring)env->CallObjectMethod(
866 proxyProps, fields.proxyConfigGetExclusionList);
867
868 const char *exclusionList =
869 env->GetStringUTFChars(exclusionListObj, NULL);
870
871 if (host != NULL && exclusionListObj != NULL) {
872 thisplayer->updateProxyConfig(host, port, exclusionList);
873 }
874
875 if (exclusionList != NULL) {
876 env->ReleaseStringUTFChars(exclusionListObj, exclusionList);
877 exclusionList = NULL;
878 }
879
880 if (host != NULL) {
881 env->ReleaseStringUTFChars(hostObj, host);
882 host = NULL;
883 }
884 }
885}
886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887// ----------------------------------------------------------------------------
888
889static JNINativeMethod gMethods[] = {
James Dong17524dc2011-05-04 13:41:58 -0700890 {
891 "_setDataSource",
892 "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
893 (void *)android_media_MediaPlayer_setDataSourceAndHeaders
894 },
895
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700896 {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700897 {"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 {"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},
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700916 {"native_invoke", "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700917 {"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter},
Nicolas Catania5d55c712009-07-09 09:21:33 -0700918 {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata},
Marco Nelissen4935d052009-08-03 11:12:58 -0700919 {"native_init", "()V", (void *)android_media_MediaPlayer_native_init},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 {"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup},
921 {"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
Eric Laurent619346f2010-06-21 09:27:30 -0700922 {"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id},
923 {"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id},
Eric Laurent7070b362010-07-16 07:43:46 -0700924 {"setAuxEffectSendLevel", "(F)V", (void *)android_media_MediaPlayer_setAuxEffectSendLevel},
925 {"attachAuxEffect", "(I)V", (void *)android_media_MediaPlayer_attachAuxEffect},
Gloria Wangd211f412011-02-19 18:37:57 -0800926 {"native_pullBatteryData", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_pullBatteryData},
Gloria Wangd01ec6e2011-04-25 17:28:22 -0700927 {"setParameter", "(ILandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_setParameter},
928 {"getParameter", "(ILandroid/os/Parcel;)V", (void *)android_media_MediaPlayer_getParameter},
John Grossman720aa282012-02-22 15:38:35 -0800929 {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I", (void *)android_media_MediaPlayer_setRetransmitEndpoint},
Marco Nelissen84b83202012-02-28 16:07:44 -0800930 {"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer},
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700931 {"updateProxyConfig", "(Landroid/net/ProxyProperties;)V", (void *)android_media_MediaPlayer_updateProxyConfig},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932};
933
934static const char* const kClassPathName = "android/media/MediaPlayer";
935
Marco Nelissen4935d052009-08-03 11:12:58 -0700936// This function only registers the native methods
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937static int register_android_media_MediaPlayer(JNIEnv *env)
938{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 return AndroidRuntime::registerNativeMethods(env,
940 "android/media/MediaPlayer", gMethods, NELEM(gMethods));
941}
942
Andreas Huber8240d922012-04-04 14:06:32 -0700943extern int register_android_media_Crypto(JNIEnv *env);
Jeff Tinker8a0c80f2013-02-08 10:20:44 -0800944extern int register_android_media_Drm(JNIEnv *env);
Andreas Huber88572f72012-02-21 11:47:18 -0800945extern int register_android_media_MediaCodec(JNIEnv *env);
946extern int register_android_media_MediaExtractor(JNIEnv *env);
Andreas Huber5a04bf32012-03-29 16:41:38 -0700947extern int register_android_media_MediaCodecList(JNIEnv *env);
Andreas Huberbfb9fb12009-12-03 11:31:19 -0800948extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
ztenghui68ccf102013-02-13 14:07:02 -0800949extern int register_android_media_MediaMuxer(JNIEnv *env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950extern int register_android_media_MediaRecorder(JNIEnv *env);
951extern int register_android_media_MediaScanner(JNIEnv *env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952extern int register_android_media_ResampleInputStream(JNIEnv *env);
James Dongc3711942010-01-19 17:45:38 -0800953extern int register_android_media_MediaProfiles(JNIEnv *env);
Andreas Huberbfb9fb12009-12-03 11:31:19 -0800954extern int register_android_media_AmrInputStream(JNIEnv *env);
Mike Lockwood0cd01362010-12-30 11:54:33 -0500955extern int register_android_mtp_MtpDatabase(JNIEnv *env);
Mike Lockwood8182e722010-12-30 15:38:45 -0500956extern int register_android_mtp_MtpDevice(JNIEnv *env);
Mike Lockwood0cd01362010-12-30 11:54:33 -0500957extern int register_android_mtp_MtpServer(JNIEnv *env);
Andreas Huberbfb9fb12009-12-03 11:31:19 -0800958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959jint JNI_OnLoad(JavaVM* vm, void* reserved)
960{
961 JNIEnv* env = NULL;
962 jint result = -1;
963
964 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
Steve Block3762c312012-01-06 19:20:56 +0000965 ALOGE("ERROR: GetEnv failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 goto bail;
967 }
968 assert(env != NULL);
969
970 if (register_android_media_MediaPlayer(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000971 ALOGE("ERROR: MediaPlayer native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800972 goto bail;
973 }
974
975 if (register_android_media_MediaRecorder(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000976 ALOGE("ERROR: MediaRecorder native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 goto bail;
978 }
979
980 if (register_android_media_MediaScanner(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000981 ALOGE("ERROR: MediaScanner native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 goto bail;
983 }
984
985 if (register_android_media_MediaMetadataRetriever(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000986 ALOGE("ERROR: MediaMetadataRetriever native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 goto bail;
988 }
989
990 if (register_android_media_AmrInputStream(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000991 ALOGE("ERROR: AmrInputStream native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 goto bail;
993 }
994
995 if (register_android_media_ResampleInputStream(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000996 ALOGE("ERROR: ResampleInputStream native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800997 goto bail;
998 }
999
James Dongc3711942010-01-19 17:45:38 -08001000 if (register_android_media_MediaProfiles(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001001 ALOGE("ERROR: MediaProfiles native registration failed");
James Dongc3711942010-01-19 17:45:38 -08001002 goto bail;
1003 }
1004
Mike Lockwood0cd01362010-12-30 11:54:33 -05001005 if (register_android_mtp_MtpDatabase(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001006 ALOGE("ERROR: MtpDatabase native registration failed");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001007 goto bail;
1008 }
1009
Mike Lockwood8182e722010-12-30 15:38:45 -05001010 if (register_android_mtp_MtpDevice(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001011 ALOGE("ERROR: MtpDevice native registration failed");
Mike Lockwood8182e722010-12-30 15:38:45 -05001012 goto bail;
1013 }
1014
Mike Lockwood0cd01362010-12-30 11:54:33 -05001015 if (register_android_mtp_MtpServer(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001016 ALOGE("ERROR: MtpServer native registration failed");
Mike Lockwood81ea83d2010-06-30 17:49:41 -04001017 goto bail;
1018 }
1019
Andreas Huber88572f72012-02-21 11:47:18 -08001020 if (register_android_media_MediaCodec(env) < 0) {
1021 ALOGE("ERROR: MediaCodec native registration failed");
1022 goto bail;
1023 }
1024
1025 if (register_android_media_MediaExtractor(env) < 0) {
1026 ALOGE("ERROR: MediaCodec native registration failed");
1027 goto bail;
1028 }
1029
ztenghui68ccf102013-02-13 14:07:02 -08001030 if (register_android_media_MediaMuxer(env) < 0) {
1031 ALOGE("ERROR: MediaMuxer native registration failed");
1032 goto bail;
1033 }
1034
Andreas Huber5a04bf32012-03-29 16:41:38 -07001035 if (register_android_media_MediaCodecList(env) < 0) {
1036 ALOGE("ERROR: MediaCodec native registration failed");
1037 goto bail;
1038 }
1039
Andreas Huber8240d922012-04-04 14:06:32 -07001040 if (register_android_media_Crypto(env) < 0) {
1041 ALOGE("ERROR: MediaCodec native registration failed");
1042 goto bail;
1043 }
1044
Jeff Tinker8a0c80f2013-02-08 10:20:44 -08001045 if (register_android_media_Drm(env) < 0) {
1046 ALOGE("ERROR: MediaDrm native registration failed");
1047 goto bail;
1048 }
1049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001050 /* success -- return valid version number */
1051 result = JNI_VERSION_1_4;
1052
1053bail:
1054 return result;
1055}
1056
1057// KTHXBYE