blob: 9d0d5a6eef78a803fa33c72f121533ebb170868b [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"
Ruben Brunk87eac992013-09-09 17:44:59 -070034#include "android_runtime/Log.h"
The Android Open Source Project4df24232009-03-05 14:34:35 -080035#include "utils/Errors.h" // for status_t
Andreas Huber25643002010-01-28 11:19:57 -080036#include "utils/KeyedVector.h"
37#include "utils/String8.h"
James Dong79f407c2011-05-05 12:50:04 -070038#include "android_media_Utils.h"
39
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080040#include "android_os_Parcel.h"
Nicolas Catania20cb94e2009-05-12 23:25:55 -070041#include "android_util_Binder.h"
42#include <binder/Parcel.h>
Andy McFaddend47f7d82012-12-18 09:48:38 -080043#include <gui/IGraphicBufferProducer.h>
Mathias Agopian8335f1c2012-02-25 18:48:35 -080044#include <gui/Surface.h>
Gloria Wangd211f412011-02-19 18:37:57 -080045#include <binder/IPCThreadState.h>
46#include <binder/IServiceManager.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
48// ----------------------------------------------------------------------------
49
50using namespace android;
51
52// ----------------------------------------------------------------------------
53
54struct fields_t {
55 jfieldID context;
Ted Bonkenburg1ee60112011-07-26 09:51:18 -070056 jfieldID surface_texture;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057
58 jmethodID post_event;
Andreas Huberd5f9fa52013-05-28 14:39:39 -070059
60 jmethodID proxyConfigGetHost;
61 jmethodID proxyConfigGetPort;
62 jmethodID proxyConfigGetExclusionList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063};
64static fields_t fields;
65
66static Mutex sLock;
67
68// ----------------------------------------------------------------------------
69// ref-counted object for callbacks
70class JNIMediaPlayerListener: public MediaPlayerListener
71{
72public:
73 JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
74 ~JNIMediaPlayerListener();
Gloria Wang162ee492011-04-11 17:23:27 -070075 virtual void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076private:
77 JNIMediaPlayerListener();
78 jclass mClass; // Reference to MediaPlayer class
79 jobject mObject; // Weak ref to MediaPlayer Java object to call on
80};
81
82JNIMediaPlayerListener::JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
83{
84
85 // Hold onto the MediaPlayer class for use in calling the static method
86 // that posts events to the application thread.
87 jclass clazz = env->GetObjectClass(thiz);
88 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +000089 ALOGE("Can't find android/media/MediaPlayer");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 jniThrowException(env, "java/lang/Exception", NULL);
91 return;
92 }
93 mClass = (jclass)env->NewGlobalRef(clazz);
94
95 // We use a weak reference so the MediaPlayer object can be garbage collected.
96 // The reference is only used as a proxy for callbacks.
97 mObject = env->NewGlobalRef(weak_thiz);
98}
99
100JNIMediaPlayerListener::~JNIMediaPlayerListener()
101{
102 // remove global references
103 JNIEnv *env = AndroidRuntime::getJNIEnv();
104 env->DeleteGlobalRef(mObject);
105 env->DeleteGlobalRef(mClass);
106}
107
Gloria Wang162ee492011-04-11 17:23:27 -0700108void JNIMediaPlayerListener::notify(int msg, int ext1, int ext2, const Parcel *obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109{
110 JNIEnv *env = AndroidRuntime::getJNIEnv();
Gloria Wang162ee492011-04-11 17:23:27 -0700111 if (obj && obj->dataSize() > 0) {
Insun Kang333c0992012-07-10 12:47:03 +0900112 jobject jParcel = createJavaParcelObject(env);
113 if (jParcel != NULL) {
114 Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
Insun Kang89020972012-05-01 14:13:19 +0900115 nativeParcel->setData(obj->data(), obj->dataSize());
Gloria Wang162ee492011-04-11 17:23:27 -0700116 env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
Insun Kang333c0992012-07-10 12:47:03 +0900117 msg, ext1, ext2, jParcel);
Elliott Hughes99f75212013-11-13 15:10:40 -0800118 env->DeleteLocalRef(jParcel);
Gloria Wang162ee492011-04-11 17:23:27 -0700119 }
120 } else {
121 env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
122 msg, ext1, ext2, NULL);
123 }
Insun Kang89020972012-05-01 14:13:19 +0900124 if (env->ExceptionCheck()) {
125 ALOGW("An exception occurred while notifying an event.");
126 LOGW_EX(env);
127 env->ExceptionClear();
128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129}
130
131// ----------------------------------------------------------------------------
132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133static sp<MediaPlayer> getMediaPlayer(JNIEnv* env, jobject thiz)
134{
135 Mutex::Autolock l(sLock);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000136 MediaPlayer* const p = (MediaPlayer*)env->GetLongField(thiz, fields.context);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 return sp<MediaPlayer>(p);
138}
139
140static sp<MediaPlayer> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaPlayer>& player)
141{
142 Mutex::Autolock l(sLock);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000143 sp<MediaPlayer> old = (MediaPlayer*)env->GetLongField(thiz, fields.context);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 if (player.get()) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800145 player->incStrong((void*)setMediaPlayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 }
147 if (old != 0) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800148 old->decStrong((void*)setMediaPlayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000150 env->SetLongField(thiz, fields.context, (jlong)player.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 return old;
152}
153
Nicolas Catania32f82772009-06-11 16:33:49 -0700154// If exception is NULL and opStatus is not OK, this method sends an error
155// event to the client application; otherwise, if exception is not NULL and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156// opStatus is not OK, this method throws the given exception to the client
157// application.
158static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStatus, const char* exception, const char *message)
159{
160 if (exception == NULL) { // Don't throw exception. Instead, send an event.
161 if (opStatus != (status_t) OK) {
162 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
163 if (mp != 0) mp->notify(MEDIA_ERROR, opStatus, 0);
164 }
165 } else { // Throw exception!
166 if ( opStatus == (status_t) INVALID_OPERATION ) {
167 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Dave Burkefc301b02011-08-30 14:39:17 +0100168 } else if ( opStatus == (status_t) PERMISSION_DENIED ) {
169 jniThrowException(env, "java/lang/SecurityException", NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 } else if ( opStatus != (status_t) OK ) {
171 if (strlen(message) > 230) {
172 // if the message is too long, don't bother displaying the status code
173 jniThrowException( env, exception, message);
174 } else {
175 char msg[256];
176 // append the status code to the message
177 sprintf(msg, "%s: status=0x%X", message, opStatus);
178 jniThrowException( env, exception, msg);
179 }
180 }
181 }
182}
183
184static void
Andreas Huber25643002010-01-28 11:19:57 -0800185android_media_MediaPlayer_setDataSourceAndHeaders(
James Dong17524dc2011-05-04 13:41:58 -0700186 JNIEnv *env, jobject thiz, jstring path,
187 jobjectArray keys, jobjectArray values) {
188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
190 if (mp == NULL ) {
191 jniThrowException(env, "java/lang/IllegalStateException", NULL);
192 return;
193 }
194
195 if (path == NULL) {
196 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
197 return;
198 }
199
James Dongc371a022011-04-06 12:16:07 -0700200 const char *tmp = env->GetStringUTFChars(path, NULL);
201 if (tmp == NULL) { // Out of memory
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 return;
203 }
Steve Block71f2cf12011-10-20 11:56:00 +0100204 ALOGV("setDataSource: path %s", tmp);
Andreas Huber25643002010-01-28 11:19:57 -0800205
James Dongc371a022011-04-06 12:16:07 -0700206 String8 pathStr(tmp);
207 env->ReleaseStringUTFChars(path, tmp);
208 tmp = NULL;
209
James Dong17524dc2011-05-04 13:41:58 -0700210 // We build a KeyedVector out of the key and val arrays
Andreas Huber25643002010-01-28 11:19:57 -0800211 KeyedVector<String8, String8> headersVector;
James Dong79f407c2011-05-05 12:50:04 -0700212 if (!ConvertKeyValueArraysToKeyedVector(
213 env, keys, values, &headersVector)) {
214 return;
Andreas Huber25643002010-01-28 11:19:57 -0800215 }
216
Andreas Huber25643002010-01-28 11:19:57 -0800217 status_t opStatus =
218 mp->setDataSource(
James Dongc371a022011-04-06 12:16:07 -0700219 pathStr,
James Dong79f407c2011-05-05 12:50:04 -0700220 headersVector.size() > 0? &headersVector : NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221
Andreas Huber25643002010-01-28 11:19:57 -0800222 process_media_player_call(
223 env, thiz, opStatus, "java/io/IOException",
224 "setDataSource failed." );
225}
226
227static void
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
229{
230 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
231 if (mp == NULL ) {
232 jniThrowException(env, "java/lang/IllegalStateException", NULL);
233 return;
234 }
235
236 if (fileDescriptor == NULL) {
237 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
238 return;
239 }
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700240 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
Steve Block71f2cf12011-10-20 11:56:00 +0100241 ALOGV("setDataSourceFD: fd %d", fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
243}
244
Andy McFaddend47f7d82012-12-18 09:48:38 -0800245static sp<IGraphicBufferProducer>
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700246getVideoSurfaceTexture(JNIEnv* env, jobject thiz) {
Ashok Bhat075e9a12014-01-06 13:45:09 +0000247 IGraphicBufferProducer * const p = (IGraphicBufferProducer*)env->GetLongField(thiz, fields.surface_texture);
Andy McFaddend47f7d82012-12-18 09:48:38 -0800248 return sp<IGraphicBufferProducer>(p);
Dave Sparks8b0b1742009-05-29 09:01:20 -0700249}
250
251static void
Gloria Wangd59310d2011-09-14 13:59:45 -0700252decVideoSurfaceRef(JNIEnv *env, jobject thiz)
253{
Gloria Wange828beb2011-09-15 15:28:43 -0700254 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
255 if (mp == NULL) {
256 return;
257 }
258
Andy McFaddend47f7d82012-12-18 09:48:38 -0800259 sp<IGraphicBufferProducer> old_st = getVideoSurfaceTexture(env, thiz);
Gloria Wangd59310d2011-09-14 13:59:45 -0700260 if (old_st != NULL) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800261 old_st->decStrong((void*)decVideoSurfaceRef);
Gloria Wangd59310d2011-09-14 13:59:45 -0700262 }
263}
264
265static void
James Dong43ef9132011-08-12 11:33:27 -0700266setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface, jboolean mediaPlayerMustBeAlive)
Dave Sparks8b0b1742009-05-29 09:01:20 -0700267{
268 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
James Dong43ef9132011-08-12 11:33:27 -0700269 if (mp == NULL) {
270 if (mediaPlayerMustBeAlive) {
271 jniThrowException(env, "java/lang/IllegalStateException", NULL);
272 }
Dave Sparks8b0b1742009-05-29 09:01:20 -0700273 return;
274 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700275
Gloria Wangd59310d2011-09-14 13:59:45 -0700276 decVideoSurfaceRef(env, thiz);
277
Andy McFaddend47f7d82012-12-18 09:48:38 -0800278 sp<IGraphicBufferProducer> new_st;
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700279 if (jsurface) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700280 sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
Jamie Gennisf76afc82011-10-14 19:06:55 -0700281 if (surface != NULL) {
Mathias Agopian52800612013-02-14 17:11:20 -0800282 new_st = surface->getIGraphicBufferProducer();
James Dong097922b2012-10-04 09:16:40 -0700283 if (new_st == NULL) {
284 jniThrowException(env, "java/lang/IllegalArgumentException",
285 "The surface does not have a binding SurfaceTexture!");
286 return;
287 }
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800288 new_st->incStrong((void*)decVideoSurfaceRef);
Jamie Gennisf76afc82011-10-14 19:06:55 -0700289 } else {
290 jniThrowException(env, "java/lang/IllegalArgumentException",
291 "The surface has been released");
292 return;
293 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700294 }
Gloria Wangd59310d2011-09-14 13:59:45 -0700295
Ashok Bhat075e9a12014-01-06 13:45:09 +0000296 env->SetLongField(thiz, fields.surface_texture, (jlong)new_st.get());
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700297
298 // This will fail if the media player has not been initialized yet. This
299 // can be the case if setDisplay() on MediaPlayer.java has been called
300 // before setDataSource(). The redundant call to setVideoSurfaceTexture()
301 // in prepare/prepareAsync covers for this case.
302 mp->setVideoSurfaceTexture(new_st);
Dave Sparks8b0b1742009-05-29 09:01:20 -0700303}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304
305static void
James Dong43ef9132011-08-12 11:33:27 -0700306android_media_MediaPlayer_setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface)
307{
308 setVideoSurface(env, thiz, jsurface, true /* mediaPlayerMustBeAlive */);
309}
310
311static void
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz)
313{
314 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
315 if (mp == NULL ) {
316 jniThrowException(env, "java/lang/IllegalStateException", NULL);
317 return;
318 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700319
320 // Handle the case where the display surface was set before the mp was
321 // initialized. We try again to make it stick.
Andy McFaddend47f7d82012-12-18 09:48:38 -0800322 sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700323 mp->setVideoSurfaceTexture(st);
324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
326}
327
328static void
329android_media_MediaPlayer_prepareAsync(JNIEnv *env, jobject thiz)
330{
331 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
332 if (mp == NULL ) {
333 jniThrowException(env, "java/lang/IllegalStateException", NULL);
334 return;
335 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700336
337 // Handle the case where the display surface was set before the mp was
338 // initialized. We try again to make it stick.
Andy McFaddend47f7d82012-12-18 09:48:38 -0800339 sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700340 mp->setVideoSurfaceTexture(st);
341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
343}
344
345static void
346android_media_MediaPlayer_start(JNIEnv *env, jobject thiz)
347{
Steve Block71f2cf12011-10-20 11:56:00 +0100348 ALOGV("start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
350 if (mp == NULL ) {
351 jniThrowException(env, "java/lang/IllegalStateException", NULL);
352 return;
353 }
354 process_media_player_call( env, thiz, mp->start(), NULL, NULL );
355}
356
357static void
358android_media_MediaPlayer_stop(JNIEnv *env, jobject thiz)
359{
Steve Block71f2cf12011-10-20 11:56:00 +0100360 ALOGV("stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
362 if (mp == NULL ) {
363 jniThrowException(env, "java/lang/IllegalStateException", NULL);
364 return;
365 }
Nicolas Catania32f82772009-06-11 16:33:49 -0700366 process_media_player_call( env, thiz, mp->stop(), NULL, NULL );
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367}
368
369static void
370android_media_MediaPlayer_pause(JNIEnv *env, jobject thiz)
371{
Steve Block71f2cf12011-10-20 11:56:00 +0100372 ALOGV("pause");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
374 if (mp == NULL ) {
375 jniThrowException(env, "java/lang/IllegalStateException", NULL);
376 return;
377 }
378 process_media_player_call( env, thiz, mp->pause(), NULL, NULL );
379}
380
381static jboolean
382android_media_MediaPlayer_isPlaying(JNIEnv *env, jobject thiz)
383{
384 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
385 if (mp == NULL ) {
386 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000387 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800389 const jboolean is_playing = mp->isPlaying();
390
Steve Block71f2cf12011-10-20 11:56:00 +0100391 ALOGV("isPlaying: %d", is_playing);
The Android Open Source Project4df24232009-03-05 14:34:35 -0800392 return is_playing;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393}
394
395static void
Ashok Bhat075e9a12014-01-06 13:45:09 +0000396android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, jint msec)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397{
398 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
399 if (mp == NULL ) {
400 jniThrowException(env, "java/lang/IllegalStateException", NULL);
401 return;
402 }
Steve Block71f2cf12011-10-20 11:56:00 +0100403 ALOGV("seekTo: %d(msec)", msec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 process_media_player_call( env, thiz, mp->seekTo(msec), NULL, NULL );
405}
406
Ashok Bhat075e9a12014-01-06 13:45:09 +0000407static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408android_media_MediaPlayer_getVideoWidth(JNIEnv *env, jobject thiz)
409{
410 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
411 if (mp == NULL ) {
412 jniThrowException(env, "java/lang/IllegalStateException", NULL);
413 return 0;
414 }
415 int w;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800416 if (0 != mp->getVideoWidth(&w)) {
Steve Block3762c312012-01-06 19:20:56 +0000417 ALOGE("getVideoWidth failed");
The Android Open Source Project4df24232009-03-05 14:34:35 -0800418 w = 0;
419 }
Steve Block71f2cf12011-10-20 11:56:00 +0100420 ALOGV("getVideoWidth: %d", w);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000421 return (jint) w;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422}
423
Ashok Bhat075e9a12014-01-06 13:45:09 +0000424static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425android_media_MediaPlayer_getVideoHeight(JNIEnv *env, jobject thiz)
426{
427 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
428 if (mp == NULL ) {
429 jniThrowException(env, "java/lang/IllegalStateException", NULL);
430 return 0;
431 }
432 int h;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800433 if (0 != mp->getVideoHeight(&h)) {
Steve Block3762c312012-01-06 19:20:56 +0000434 ALOGE("getVideoHeight failed");
The Android Open Source Project4df24232009-03-05 14:34:35 -0800435 h = 0;
436 }
Steve Block71f2cf12011-10-20 11:56:00 +0100437 ALOGV("getVideoHeight: %d", h);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000438 return (jint) h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439}
440
441
Ashok Bhat075e9a12014-01-06 13:45:09 +0000442static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443android_media_MediaPlayer_getCurrentPosition(JNIEnv *env, jobject thiz)
444{
445 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
446 if (mp == NULL ) {
447 jniThrowException(env, "java/lang/IllegalStateException", NULL);
448 return 0;
449 }
450 int msec;
451 process_media_player_call( env, thiz, mp->getCurrentPosition(&msec), NULL, NULL );
Steve Block71f2cf12011-10-20 11:56:00 +0100452 ALOGV("getCurrentPosition: %d (msec)", msec);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000453 return (jint) msec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454}
455
Ashok Bhat075e9a12014-01-06 13:45:09 +0000456static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457android_media_MediaPlayer_getDuration(JNIEnv *env, jobject thiz)
458{
459 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
460 if (mp == NULL ) {
461 jniThrowException(env, "java/lang/IllegalStateException", NULL);
462 return 0;
463 }
464 int msec;
465 process_media_player_call( env, thiz, mp->getDuration(&msec), NULL, NULL );
Steve Block71f2cf12011-10-20 11:56:00 +0100466 ALOGV("getDuration: %d (msec)", msec);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000467 return (jint) msec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468}
469
470static void
471android_media_MediaPlayer_reset(JNIEnv *env, jobject thiz)
472{
Steve Block71f2cf12011-10-20 11:56:00 +0100473 ALOGV("reset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
475 if (mp == NULL ) {
476 jniThrowException(env, "java/lang/IllegalStateException", NULL);
477 return;
478 }
479 process_media_player_call( env, thiz, mp->reset(), NULL, NULL );
480}
481
482static void
Ashok Bhat075e9a12014-01-06 13:45:09 +0000483android_media_MediaPlayer_setAudioStreamType(JNIEnv *env, jobject thiz, jint streamtype)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484{
Steve Block71f2cf12011-10-20 11:56:00 +0100485 ALOGV("setAudioStreamType: %d", streamtype);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
487 if (mp == NULL ) {
488 jniThrowException(env, "java/lang/IllegalStateException", NULL);
489 return;
490 }
Glenn Kastenbc1d77b2012-01-12 16:38:12 -0800491 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 -0800492}
493
494static void
495android_media_MediaPlayer_setLooping(JNIEnv *env, jobject thiz, jboolean looping)
496{
Steve Block71f2cf12011-10-20 11:56:00 +0100497 ALOGV("setLooping: %d", looping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
499 if (mp == NULL ) {
500 jniThrowException(env, "java/lang/IllegalStateException", NULL);
501 return;
502 }
503 process_media_player_call( env, thiz, mp->setLooping(looping), NULL, NULL );
504}
505
506static jboolean
507android_media_MediaPlayer_isLooping(JNIEnv *env, jobject thiz)
508{
Steve Block71f2cf12011-10-20 11:56:00 +0100509 ALOGV("isLooping");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
511 if (mp == NULL ) {
512 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000513 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000515 return mp->isLooping() ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516}
517
518static void
Ashok Bhat075e9a12014-01-06 13:45:09 +0000519android_media_MediaPlayer_setVolume(JNIEnv *env, jobject thiz, jfloat leftVolume, jfloat rightVolume)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000521 ALOGV("setVolume: left %f right %f", (float) leftVolume, (float) rightVolume);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
523 if (mp == NULL ) {
524 jniThrowException(env, "java/lang/IllegalStateException", NULL);
525 return;
526 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000527 process_media_player_call( env, thiz, mp->setVolume((float) leftVolume, (float) rightVolume), NULL, NULL );
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528}
529
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700530// Sends the request and reply parcels to the media player via the
531// binder interface.
532static jint
533android_media_MediaPlayer_invoke(JNIEnv *env, jobject thiz,
534 jobject java_request, jobject java_reply)
535{
536 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
537 if (media_player == NULL ) {
538 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700539 return UNKNOWN_ERROR;
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700540 }
541
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700542 Parcel *request = parcelForJavaObject(env, java_request);
543 Parcel *reply = parcelForJavaObject(env, java_reply);
544
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700545 // Don't use process_media_player_call which use the async loop to
546 // report errors, instead returns the status.
Ashok Bhat075e9a12014-01-06 13:45:09 +0000547 return (jint) media_player->invoke(*request, reply);
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700548}
549
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700550// Sends the new filter to the client.
551static jint
552android_media_MediaPlayer_setMetadataFilter(JNIEnv *env, jobject thiz, jobject request)
553{
554 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
555 if (media_player == NULL ) {
556 jniThrowException(env, "java/lang/IllegalStateException", NULL);
557 return UNKNOWN_ERROR;
558 }
559
560 Parcel *filter = parcelForJavaObject(env, request);
561
Nicolas Catania5d55c712009-07-09 09:21:33 -0700562 if (filter == NULL ) {
563 jniThrowException(env, "java/lang/RuntimeException", "Filter is null");
564 return UNKNOWN_ERROR;
565 }
566
Ashok Bhat075e9a12014-01-06 13:45:09 +0000567 return (jint) media_player->setMetadataFilter(*filter);
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700568}
569
Nicolas Catania5d55c712009-07-09 09:21:33 -0700570static jboolean
571android_media_MediaPlayer_getMetadata(JNIEnv *env, jobject thiz, jboolean update_only,
572 jboolean apply_filter, jobject reply)
573{
574 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
575 if (media_player == NULL ) {
576 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000577 return JNI_FALSE;
Nicolas Catania5d55c712009-07-09 09:21:33 -0700578 }
579
580 Parcel *metadata = parcelForJavaObject(env, reply);
581
582 if (metadata == NULL ) {
583 jniThrowException(env, "java/lang/RuntimeException", "Reply parcel is null");
Ashok Bhat075e9a12014-01-06 13:45:09 +0000584 return JNI_FALSE;
Nicolas Catania5d55c712009-07-09 09:21:33 -0700585 }
586
587 metadata->freeData();
588 // On return metadata is positioned at the beginning of the
589 // metadata. Note however that the parcel actually starts with the
590 // return code so you should not rewind the parcel using
591 // setDataPosition(0).
Ashok Bhat075e9a12014-01-06 13:45:09 +0000592 if (media_player->getMetadata(update_only, apply_filter, metadata) == OK) {
593 return JNI_TRUE;
594 } else {
595 return JNI_FALSE;
596 }
Nicolas Catania5d55c712009-07-09 09:21:33 -0700597}
598
Marco Nelissen4935d052009-08-03 11:12:58 -0700599// This function gets some field IDs, which in turn causes class initialization.
600// It is called from a static block in MediaPlayer, which won't run until the
601// first time an instance of this class is used.
602static void
603android_media_MediaPlayer_native_init(JNIEnv *env)
604{
605 jclass clazz;
606
607 clazz = env->FindClass("android/media/MediaPlayer");
608 if (clazz == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700609 return;
610 }
611
Ashok Bhat075e9a12014-01-06 13:45:09 +0000612 fields.context = env->GetFieldID(clazz, "mNativeContext", "J");
Marco Nelissen4935d052009-08-03 11:12:58 -0700613 if (fields.context == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700614 return;
615 }
616
617 fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
618 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
619 if (fields.post_event == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700620 return;
621 }
622
Ashok Bhat075e9a12014-01-06 13:45:09 +0000623 fields.surface_texture = env->GetFieldID(clazz, "mNativeSurfaceTexture", "J");
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700624 if (fields.surface_texture == NULL) {
Glenn Kastencc562a32011-02-08 17:26:17 -0800625 return;
626 }
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700627
628 clazz = env->FindClass("android/net/ProxyProperties");
629 if (clazz == NULL) {
630 return;
631 }
632
633 fields.proxyConfigGetHost =
634 env->GetMethodID(clazz, "getHost", "()Ljava/lang/String;");
635
636 fields.proxyConfigGetPort =
637 env->GetMethodID(clazz, "getPort", "()I");
638
639 fields.proxyConfigGetExclusionList =
640 env->GetMethodID(clazz, "getExclusionList", "()Ljava/lang/String;");
Marco Nelissen4935d052009-08-03 11:12:58 -0700641}
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800643static void
644android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
645{
Steve Block71f2cf12011-10-20 11:56:00 +0100646 ALOGV("native_setup");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647 sp<MediaPlayer> mp = new MediaPlayer();
648 if (mp == NULL) {
649 jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
650 return;
651 }
652
653 // create new listener and give it to MediaPlayer
654 sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
655 mp->setListener(listener);
656
657 // Stow our new C++ MediaPlayer in an opaque field in the Java object.
658 setMediaPlayer(env, thiz, mp);
659}
660
661static void
662android_media_MediaPlayer_release(JNIEnv *env, jobject thiz)
663{
Steve Block71f2cf12011-10-20 11:56:00 +0100664 ALOGV("release");
Gloria Wangd59310d2011-09-14 13:59:45 -0700665 decVideoSurfaceRef(env, thiz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800666 sp<MediaPlayer> mp = setMediaPlayer(env, thiz, 0);
667 if (mp != NULL) {
668 // this prevents native callbacks after the object is released
669 mp->setListener(0);
670 mp->disconnect();
671 }
672}
673
674static void
675android_media_MediaPlayer_native_finalize(JNIEnv *env, jobject thiz)
676{
Steve Block71f2cf12011-10-20 11:56:00 +0100677 ALOGV("native_finalize");
Marco Nelissen8dc20842011-09-28 09:21:11 -0700678 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
679 if (mp != NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +0000680 ALOGW("MediaPlayer finalized without being released");
Marco Nelissen8dc20842011-09-28 09:21:11 -0700681 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800682 android_media_MediaPlayer_release(env, thiz);
683}
684
Eric Laurent619346f2010-06-21 09:27:30 -0700685static void android_media_MediaPlayer_set_audio_session_id(JNIEnv *env, jobject thiz, jint sessionId) {
Steve Block71f2cf12011-10-20 11:56:00 +0100686 ALOGV("set_session_id(): %d", sessionId);
Eric Laurent619346f2010-06-21 09:27:30 -0700687 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
688 if (mp == NULL ) {
689 jniThrowException(env, "java/lang/IllegalStateException", NULL);
690 return;
691 }
692 process_media_player_call( env, thiz, mp->setAudioSessionId(sessionId), NULL, NULL );
693}
694
695static jint android_media_MediaPlayer_get_audio_session_id(JNIEnv *env, jobject thiz) {
Steve Block71f2cf12011-10-20 11:56:00 +0100696 ALOGV("get_session_id()");
Eric Laurent619346f2010-06-21 09:27:30 -0700697 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
698 if (mp == NULL ) {
699 jniThrowException(env, "java/lang/IllegalStateException", NULL);
700 return 0;
701 }
702
Ashok Bhat075e9a12014-01-06 13:45:09 +0000703 return (jint) mp->getAudioSessionId();
Eric Laurent619346f2010-06-21 09:27:30 -0700704}
705
Eric Laurent7070b362010-07-16 07:43:46 -0700706static void
707android_media_MediaPlayer_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level)
708{
Steve Block71f2cf12011-10-20 11:56:00 +0100709 ALOGV("setAuxEffectSendLevel: level %f", level);
Eric Laurent7070b362010-07-16 07:43:46 -0700710 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
711 if (mp == NULL ) {
712 jniThrowException(env, "java/lang/IllegalStateException", NULL);
713 return;
714 }
715 process_media_player_call( env, thiz, mp->setAuxEffectSendLevel(level), NULL, NULL );
716}
717
718static void android_media_MediaPlayer_attachAuxEffect(JNIEnv *env, jobject thiz, jint effectId) {
Steve Block71f2cf12011-10-20 11:56:00 +0100719 ALOGV("attachAuxEffect(): %d", effectId);
Eric Laurent7070b362010-07-16 07:43:46 -0700720 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
721 if (mp == NULL ) {
722 jniThrowException(env, "java/lang/IllegalStateException", NULL);
723 return;
724 }
725 process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL );
726}
727
Gloria Wangd211f412011-02-19 18:37:57 -0800728static jint
729android_media_MediaPlayer_pullBatteryData(JNIEnv *env, jobject thiz, jobject java_reply)
730{
731 sp<IBinder> binder = defaultServiceManager()->getService(String16("media.player"));
732 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
733 if (service.get() == NULL) {
734 jniThrowException(env, "java/lang/RuntimeException", "cannot get MediaPlayerService");
735 return UNKNOWN_ERROR;
736 }
737
738 Parcel *reply = parcelForJavaObject(env, java_reply);
739
Ashok Bhat075e9a12014-01-06 13:45:09 +0000740 return (jint) service->pullBatteryData(reply);
Gloria Wangd211f412011-02-19 18:37:57 -0800741}
742
John Grossman720aa282012-02-22 15:38:35 -0800743static jint
744android_media_MediaPlayer_setRetransmitEndpoint(JNIEnv *env, jobject thiz,
745 jstring addrString, jint port) {
746 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
747 if (mp == NULL ) {
748 jniThrowException(env, "java/lang/IllegalStateException", NULL);
749 return INVALID_OPERATION;
750 }
751
752 const char *cAddrString = NULL;
753
754 if (NULL != addrString) {
755 cAddrString = env->GetStringUTFChars(addrString, NULL);
756 if (cAddrString == NULL) { // Out of memory
757 return NO_MEMORY;
758 }
759 }
760 ALOGV("setRetransmitEndpoint: %s:%d",
761 cAddrString ? cAddrString : "(null)", port);
762
763 status_t ret;
764 if (cAddrString && (port > 0xFFFF)) {
765 ret = BAD_VALUE;
766 } else {
767 ret = mp->setRetransmitEndpoint(cAddrString,
768 static_cast<uint16_t>(port));
769 }
770
771 if (NULL != addrString) {
772 env->ReleaseStringUTFChars(addrString, cAddrString);
773 }
774
775 if (ret == INVALID_OPERATION ) {
776 jniThrowException(env, "java/lang/IllegalStateException", NULL);
777 }
778
Ashok Bhat075e9a12014-01-06 13:45:09 +0000779 return (jint) ret;
John Grossman720aa282012-02-22 15:38:35 -0800780}
781
Marco Nelissen84b83202012-02-28 16:07:44 -0800782static void
783android_media_MediaPlayer_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject java_player)
784{
785 ALOGV("setNextMediaPlayer");
786 sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
787 if (thisplayer == NULL) {
788 jniThrowException(env, "java/lang/IllegalStateException", "This player not initialized");
789 return;
790 }
791 sp<MediaPlayer> nextplayer = (java_player == NULL) ? NULL : getMediaPlayer(env, java_player);
792 if (nextplayer == NULL && java_player != NULL) {
793 jniThrowException(env, "java/lang/IllegalStateException", "That player not initialized");
794 return;
795 }
796
797 if (nextplayer == thisplayer) {
798 jniThrowException(env, "java/lang/IllegalArgumentException", "Next player can't be self");
799 return;
800 }
801 // tie the two players together
802 process_media_player_call(
803 env, thiz, thisplayer->setNextMediaPlayer(nextplayer),
804 "java/lang/IllegalArgumentException",
805 "setNextMediaPlayer failed." );
806 ;
807}
808
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700809static void
810android_media_MediaPlayer_updateProxyConfig(
811 JNIEnv *env, jobject thiz, jobject proxyProps)
812{
813 ALOGV("updateProxyConfig");
814 sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
815 if (thisplayer == NULL) {
816 return;
817 }
818
819 if (proxyProps == NULL) {
820 thisplayer->updateProxyConfig(
821 NULL /* host */, 0 /* port */, NULL /* exclusionList */);
822 } else {
823 jstring hostObj = (jstring)env->CallObjectMethod(
824 proxyProps, fields.proxyConfigGetHost);
825
826 const char *host = env->GetStringUTFChars(hostObj, NULL);
827
828 int port = env->CallIntMethod(proxyProps, fields.proxyConfigGetPort);
829
830 jstring exclusionListObj = (jstring)env->CallObjectMethod(
831 proxyProps, fields.proxyConfigGetExclusionList);
832
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700833 if (host != NULL && exclusionListObj != NULL) {
Oscar Rydhée795ec72013-09-24 13:43:55 +0200834 const char *exclusionList = env->GetStringUTFChars(exclusionListObj, NULL);
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700835
Oscar Rydhée795ec72013-09-24 13:43:55 +0200836 if (exclusionList != NULL) {
837 thisplayer->updateProxyConfig(host, port, exclusionList);
838
839 env->ReleaseStringUTFChars(exclusionListObj, exclusionList);
840 exclusionList = NULL;
841 } else {
842 thisplayer->updateProxyConfig(host, port, "");
843 }
844 } else if (host != NULL) {
845 thisplayer->updateProxyConfig(host, port, "");
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700846 }
847
848 if (host != NULL) {
849 env->ReleaseStringUTFChars(hostObj, host);
850 host = NULL;
851 }
852 }
853}
854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855// ----------------------------------------------------------------------------
856
857static JNINativeMethod gMethods[] = {
James Dong17524dc2011-05-04 13:41:58 -0700858 {
859 "_setDataSource",
860 "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
861 (void *)android_media_MediaPlayer_setDataSourceAndHeaders
862 },
863
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700864 {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700865 {"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 {"prepare", "()V", (void *)android_media_MediaPlayer_prepare},
867 {"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync},
868 {"_start", "()V", (void *)android_media_MediaPlayer_start},
869 {"_stop", "()V", (void *)android_media_MediaPlayer_stop},
870 {"getVideoWidth", "()I", (void *)android_media_MediaPlayer_getVideoWidth},
871 {"getVideoHeight", "()I", (void *)android_media_MediaPlayer_getVideoHeight},
872 {"seekTo", "(I)V", (void *)android_media_MediaPlayer_seekTo},
873 {"_pause", "()V", (void *)android_media_MediaPlayer_pause},
874 {"isPlaying", "()Z", (void *)android_media_MediaPlayer_isPlaying},
875 {"getCurrentPosition", "()I", (void *)android_media_MediaPlayer_getCurrentPosition},
876 {"getDuration", "()I", (void *)android_media_MediaPlayer_getDuration},
877 {"_release", "()V", (void *)android_media_MediaPlayer_release},
878 {"_reset", "()V", (void *)android_media_MediaPlayer_reset},
879 {"setAudioStreamType", "(I)V", (void *)android_media_MediaPlayer_setAudioStreamType},
880 {"setLooping", "(Z)V", (void *)android_media_MediaPlayer_setLooping},
881 {"isLooping", "()Z", (void *)android_media_MediaPlayer_isLooping},
882 {"setVolume", "(FF)V", (void *)android_media_MediaPlayer_setVolume},
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700883 {"native_invoke", "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700884 {"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter},
Nicolas Catania5d55c712009-07-09 09:21:33 -0700885 {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata},
Marco Nelissen4935d052009-08-03 11:12:58 -0700886 {"native_init", "()V", (void *)android_media_MediaPlayer_native_init},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 {"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup},
888 {"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
Eric Laurent619346f2010-06-21 09:27:30 -0700889 {"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id},
890 {"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id},
Eric Laurent7070b362010-07-16 07:43:46 -0700891 {"setAuxEffectSendLevel", "(F)V", (void *)android_media_MediaPlayer_setAuxEffectSendLevel},
892 {"attachAuxEffect", "(I)V", (void *)android_media_MediaPlayer_attachAuxEffect},
Gloria Wangd211f412011-02-19 18:37:57 -0800893 {"native_pullBatteryData", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_pullBatteryData},
John Grossman720aa282012-02-22 15:38:35 -0800894 {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I", (void *)android_media_MediaPlayer_setRetransmitEndpoint},
Marco Nelissen84b83202012-02-28 16:07:44 -0800895 {"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer},
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700896 {"updateProxyConfig", "(Landroid/net/ProxyProperties;)V", (void *)android_media_MediaPlayer_updateProxyConfig},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897};
898
899static const char* const kClassPathName = "android/media/MediaPlayer";
900
Marco Nelissen4935d052009-08-03 11:12:58 -0700901// This function only registers the native methods
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902static int register_android_media_MediaPlayer(JNIEnv *env)
903{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 return AndroidRuntime::registerNativeMethods(env,
905 "android/media/MediaPlayer", gMethods, NELEM(gMethods));
906}
907
Zhijun He212e78d2013-06-07 11:36:23 -0700908extern int register_android_media_ImageReader(JNIEnv *env);
Andreas Huber8240d922012-04-04 14:06:32 -0700909extern int register_android_media_Crypto(JNIEnv *env);
Jeff Tinker8a0c80f2013-02-08 10:20:44 -0800910extern int register_android_media_Drm(JNIEnv *env);
Andreas Huber88572f72012-02-21 11:47:18 -0800911extern int register_android_media_MediaCodec(JNIEnv *env);
912extern int register_android_media_MediaExtractor(JNIEnv *env);
Andreas Huber5a04bf32012-03-29 16:41:38 -0700913extern int register_android_media_MediaCodecList(JNIEnv *env);
Andreas Huberbfb9fb12009-12-03 11:31:19 -0800914extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
ztenghui68ccf102013-02-13 14:07:02 -0800915extern int register_android_media_MediaMuxer(JNIEnv *env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916extern int register_android_media_MediaRecorder(JNIEnv *env);
917extern int register_android_media_MediaScanner(JNIEnv *env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918extern int register_android_media_ResampleInputStream(JNIEnv *env);
James Dongc3711942010-01-19 17:45:38 -0800919extern int register_android_media_MediaProfiles(JNIEnv *env);
Andreas Huberbfb9fb12009-12-03 11:31:19 -0800920extern int register_android_media_AmrInputStream(JNIEnv *env);
Mike Lockwood0cd01362010-12-30 11:54:33 -0500921extern int register_android_mtp_MtpDatabase(JNIEnv *env);
Mike Lockwood8182e722010-12-30 15:38:45 -0500922extern int register_android_mtp_MtpDevice(JNIEnv *env);
Mike Lockwood0cd01362010-12-30 11:54:33 -0500923extern int register_android_mtp_MtpServer(JNIEnv *env);
Andreas Huberbfb9fb12009-12-03 11:31:19 -0800924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925jint JNI_OnLoad(JavaVM* vm, void* reserved)
926{
927 JNIEnv* env = NULL;
928 jint result = -1;
929
930 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
Steve Block3762c312012-01-06 19:20:56 +0000931 ALOGE("ERROR: GetEnv failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 goto bail;
933 }
934 assert(env != NULL);
935
Zhijun He212e78d2013-06-07 11:36:23 -0700936 if (register_android_media_ImageReader(env) < 0) {
937 ALOGE("ERROR: ImageReader native registration failed");
938 goto bail;
939 }
940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941 if (register_android_media_MediaPlayer(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000942 ALOGE("ERROR: MediaPlayer native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800943 goto bail;
944 }
945
946 if (register_android_media_MediaRecorder(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000947 ALOGE("ERROR: MediaRecorder native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 goto bail;
949 }
950
951 if (register_android_media_MediaScanner(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000952 ALOGE("ERROR: MediaScanner native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 goto bail;
954 }
955
956 if (register_android_media_MediaMetadataRetriever(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000957 ALOGE("ERROR: MediaMetadataRetriever native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 goto bail;
959 }
960
961 if (register_android_media_AmrInputStream(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000962 ALOGE("ERROR: AmrInputStream native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 goto bail;
964 }
965
966 if (register_android_media_ResampleInputStream(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000967 ALOGE("ERROR: ResampleInputStream native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 goto bail;
969 }
970
James Dongc3711942010-01-19 17:45:38 -0800971 if (register_android_media_MediaProfiles(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000972 ALOGE("ERROR: MediaProfiles native registration failed");
James Dongc3711942010-01-19 17:45:38 -0800973 goto bail;
974 }
975
Mike Lockwood0cd01362010-12-30 11:54:33 -0500976 if (register_android_mtp_MtpDatabase(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000977 ALOGE("ERROR: MtpDatabase native registration failed");
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400978 goto bail;
979 }
980
Mike Lockwood8182e722010-12-30 15:38:45 -0500981 if (register_android_mtp_MtpDevice(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000982 ALOGE("ERROR: MtpDevice native registration failed");
Mike Lockwood8182e722010-12-30 15:38:45 -0500983 goto bail;
984 }
985
Mike Lockwood0cd01362010-12-30 11:54:33 -0500986 if (register_android_mtp_MtpServer(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000987 ALOGE("ERROR: MtpServer native registration failed");
Mike Lockwood81ea83d2010-06-30 17:49:41 -0400988 goto bail;
989 }
990
Andreas Huber88572f72012-02-21 11:47:18 -0800991 if (register_android_media_MediaCodec(env) < 0) {
992 ALOGE("ERROR: MediaCodec native registration failed");
993 goto bail;
994 }
995
996 if (register_android_media_MediaExtractor(env) < 0) {
997 ALOGE("ERROR: MediaCodec native registration failed");
998 goto bail;
999 }
1000
ztenghui68ccf102013-02-13 14:07:02 -08001001 if (register_android_media_MediaMuxer(env) < 0) {
1002 ALOGE("ERROR: MediaMuxer native registration failed");
1003 goto bail;
1004 }
1005
Andreas Huber5a04bf32012-03-29 16:41:38 -07001006 if (register_android_media_MediaCodecList(env) < 0) {
1007 ALOGE("ERROR: MediaCodec native registration failed");
1008 goto bail;
1009 }
1010
Andreas Huber8240d922012-04-04 14:06:32 -07001011 if (register_android_media_Crypto(env) < 0) {
1012 ALOGE("ERROR: MediaCodec native registration failed");
1013 goto bail;
1014 }
1015
Jeff Tinker8a0c80f2013-02-08 10:20:44 -08001016 if (register_android_media_Drm(env) < 0) {
1017 ALOGE("ERROR: MediaDrm native registration failed");
1018 goto bail;
1019 }
1020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 /* success -- return valid version number */
1022 result = JNI_VERSION_1_4;
1023
1024bail:
1025 return result;
1026}
1027
1028// KTHXBYE