blob: 9b66c0677b6dd5a53ab82025bf7b178b3e4e6a76 [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
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700528// Sends the request and reply parcels to the media player via the
529// binder interface.
530static jint
531android_media_MediaPlayer_invoke(JNIEnv *env, jobject thiz,
532 jobject java_request, jobject java_reply)
533{
534 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
535 if (media_player == NULL ) {
536 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700537 return UNKNOWN_ERROR;
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700538 }
539
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700540 Parcel *request = parcelForJavaObject(env, java_request);
541 Parcel *reply = parcelForJavaObject(env, java_reply);
542
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700543 // Don't use process_media_player_call which use the async loop to
544 // report errors, instead returns the status.
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700545 return media_player->invoke(*request, reply);
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700546}
547
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700548// Sends the new filter to the client.
549static jint
550android_media_MediaPlayer_setMetadataFilter(JNIEnv *env, jobject thiz, jobject request)
551{
552 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
553 if (media_player == NULL ) {
554 jniThrowException(env, "java/lang/IllegalStateException", NULL);
555 return UNKNOWN_ERROR;
556 }
557
558 Parcel *filter = parcelForJavaObject(env, request);
559
Nicolas Catania5d55c712009-07-09 09:21:33 -0700560 if (filter == NULL ) {
561 jniThrowException(env, "java/lang/RuntimeException", "Filter is null");
562 return UNKNOWN_ERROR;
563 }
564
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700565 return media_player->setMetadataFilter(*filter);
566}
567
Nicolas Catania5d55c712009-07-09 09:21:33 -0700568static jboolean
569android_media_MediaPlayer_getMetadata(JNIEnv *env, jobject thiz, jboolean update_only,
570 jboolean apply_filter, jobject reply)
571{
572 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
573 if (media_player == NULL ) {
574 jniThrowException(env, "java/lang/IllegalStateException", NULL);
575 return false;
576 }
577
578 Parcel *metadata = parcelForJavaObject(env, reply);
579
580 if (metadata == NULL ) {
581 jniThrowException(env, "java/lang/RuntimeException", "Reply parcel is null");
582 return false;
583 }
584
585 metadata->freeData();
586 // On return metadata is positioned at the beginning of the
587 // metadata. Note however that the parcel actually starts with the
588 // return code so you should not rewind the parcel using
589 // setDataPosition(0).
590 return media_player->getMetadata(update_only, apply_filter, metadata) == OK;
591}
592
Marco Nelissen4935d052009-08-03 11:12:58 -0700593// This function gets some field IDs, which in turn causes class initialization.
594// It is called from a static block in MediaPlayer, which won't run until the
595// first time an instance of this class is used.
596static void
597android_media_MediaPlayer_native_init(JNIEnv *env)
598{
599 jclass clazz;
600
601 clazz = env->FindClass("android/media/MediaPlayer");
602 if (clazz == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700603 return;
604 }
605
606 fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
607 if (fields.context == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700608 return;
609 }
610
611 fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
612 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
613 if (fields.post_event == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700614 return;
615 }
616
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700617 fields.surface_texture = env->GetFieldID(clazz, "mNativeSurfaceTexture", "I");
618 if (fields.surface_texture == NULL) {
Glenn Kastencc562a32011-02-08 17:26:17 -0800619 return;
620 }
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700621
622 clazz = env->FindClass("android/net/ProxyProperties");
623 if (clazz == NULL) {
624 return;
625 }
626
627 fields.proxyConfigGetHost =
628 env->GetMethodID(clazz, "getHost", "()Ljava/lang/String;");
629
630 fields.proxyConfigGetPort =
631 env->GetMethodID(clazz, "getPort", "()I");
632
633 fields.proxyConfigGetExclusionList =
634 env->GetMethodID(clazz, "getExclusionList", "()Ljava/lang/String;");
Marco Nelissen4935d052009-08-03 11:12:58 -0700635}
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637static void
638android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
639{
Steve Block71f2cf12011-10-20 11:56:00 +0100640 ALOGV("native_setup");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 sp<MediaPlayer> mp = new MediaPlayer();
642 if (mp == NULL) {
643 jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
644 return;
645 }
646
647 // create new listener and give it to MediaPlayer
648 sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
649 mp->setListener(listener);
650
651 // Stow our new C++ MediaPlayer in an opaque field in the Java object.
652 setMediaPlayer(env, thiz, mp);
653}
654
655static void
656android_media_MediaPlayer_release(JNIEnv *env, jobject thiz)
657{
Steve Block71f2cf12011-10-20 11:56:00 +0100658 ALOGV("release");
Gloria Wangd59310d2011-09-14 13:59:45 -0700659 decVideoSurfaceRef(env, thiz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800660 sp<MediaPlayer> mp = setMediaPlayer(env, thiz, 0);
661 if (mp != NULL) {
662 // this prevents native callbacks after the object is released
663 mp->setListener(0);
664 mp->disconnect();
665 }
666}
667
668static void
669android_media_MediaPlayer_native_finalize(JNIEnv *env, jobject thiz)
670{
Steve Block71f2cf12011-10-20 11:56:00 +0100671 ALOGV("native_finalize");
Marco Nelissen8dc20842011-09-28 09:21:11 -0700672 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
673 if (mp != NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +0000674 ALOGW("MediaPlayer finalized without being released");
Marco Nelissen8dc20842011-09-28 09:21:11 -0700675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800676 android_media_MediaPlayer_release(env, thiz);
677}
678
Eric Laurent619346f2010-06-21 09:27:30 -0700679static void android_media_MediaPlayer_set_audio_session_id(JNIEnv *env, jobject thiz, jint sessionId) {
Steve Block71f2cf12011-10-20 11:56:00 +0100680 ALOGV("set_session_id(): %d", sessionId);
Eric Laurent619346f2010-06-21 09:27:30 -0700681 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
682 if (mp == NULL ) {
683 jniThrowException(env, "java/lang/IllegalStateException", NULL);
684 return;
685 }
686 process_media_player_call( env, thiz, mp->setAudioSessionId(sessionId), NULL, NULL );
687}
688
689static jint android_media_MediaPlayer_get_audio_session_id(JNIEnv *env, jobject thiz) {
Steve Block71f2cf12011-10-20 11:56:00 +0100690 ALOGV("get_session_id()");
Eric Laurent619346f2010-06-21 09:27:30 -0700691 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
692 if (mp == NULL ) {
693 jniThrowException(env, "java/lang/IllegalStateException", NULL);
694 return 0;
695 }
696
697 return mp->getAudioSessionId();
698}
699
Eric Laurent7070b362010-07-16 07:43:46 -0700700static void
701android_media_MediaPlayer_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level)
702{
Steve Block71f2cf12011-10-20 11:56:00 +0100703 ALOGV("setAuxEffectSendLevel: level %f", level);
Eric Laurent7070b362010-07-16 07:43:46 -0700704 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
705 if (mp == NULL ) {
706 jniThrowException(env, "java/lang/IllegalStateException", NULL);
707 return;
708 }
709 process_media_player_call( env, thiz, mp->setAuxEffectSendLevel(level), NULL, NULL );
710}
711
712static void android_media_MediaPlayer_attachAuxEffect(JNIEnv *env, jobject thiz, jint effectId) {
Steve Block71f2cf12011-10-20 11:56:00 +0100713 ALOGV("attachAuxEffect(): %d", effectId);
Eric Laurent7070b362010-07-16 07:43:46 -0700714 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
715 if (mp == NULL ) {
716 jniThrowException(env, "java/lang/IllegalStateException", NULL);
717 return;
718 }
719 process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL );
720}
721
Gloria Wangd211f412011-02-19 18:37:57 -0800722static jint
723android_media_MediaPlayer_pullBatteryData(JNIEnv *env, jobject thiz, jobject java_reply)
724{
725 sp<IBinder> binder = defaultServiceManager()->getService(String16("media.player"));
726 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
727 if (service.get() == NULL) {
728 jniThrowException(env, "java/lang/RuntimeException", "cannot get MediaPlayerService");
729 return UNKNOWN_ERROR;
730 }
731
732 Parcel *reply = parcelForJavaObject(env, java_reply);
733
734 return service->pullBatteryData(reply);
735}
736
John Grossman720aa282012-02-22 15:38:35 -0800737static jint
738android_media_MediaPlayer_setRetransmitEndpoint(JNIEnv *env, jobject thiz,
739 jstring addrString, jint port) {
740 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
741 if (mp == NULL ) {
742 jniThrowException(env, "java/lang/IllegalStateException", NULL);
743 return INVALID_OPERATION;
744 }
745
746 const char *cAddrString = NULL;
747
748 if (NULL != addrString) {
749 cAddrString = env->GetStringUTFChars(addrString, NULL);
750 if (cAddrString == NULL) { // Out of memory
751 return NO_MEMORY;
752 }
753 }
754 ALOGV("setRetransmitEndpoint: %s:%d",
755 cAddrString ? cAddrString : "(null)", port);
756
757 status_t ret;
758 if (cAddrString && (port > 0xFFFF)) {
759 ret = BAD_VALUE;
760 } else {
761 ret = mp->setRetransmitEndpoint(cAddrString,
762 static_cast<uint16_t>(port));
763 }
764
765 if (NULL != addrString) {
766 env->ReleaseStringUTFChars(addrString, cAddrString);
767 }
768
769 if (ret == INVALID_OPERATION ) {
770 jniThrowException(env, "java/lang/IllegalStateException", NULL);
771 }
772
773 return ret;
774}
775
Marco Nelissen84b83202012-02-28 16:07:44 -0800776static void
777android_media_MediaPlayer_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject java_player)
778{
779 ALOGV("setNextMediaPlayer");
780 sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
781 if (thisplayer == NULL) {
782 jniThrowException(env, "java/lang/IllegalStateException", "This player not initialized");
783 return;
784 }
785 sp<MediaPlayer> nextplayer = (java_player == NULL) ? NULL : getMediaPlayer(env, java_player);
786 if (nextplayer == NULL && java_player != NULL) {
787 jniThrowException(env, "java/lang/IllegalStateException", "That player not initialized");
788 return;
789 }
790
791 if (nextplayer == thisplayer) {
792 jniThrowException(env, "java/lang/IllegalArgumentException", "Next player can't be self");
793 return;
794 }
795 // tie the two players together
796 process_media_player_call(
797 env, thiz, thisplayer->setNextMediaPlayer(nextplayer),
798 "java/lang/IllegalArgumentException",
799 "setNextMediaPlayer failed." );
800 ;
801}
802
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700803static void
804android_media_MediaPlayer_updateProxyConfig(
805 JNIEnv *env, jobject thiz, jobject proxyProps)
806{
807 ALOGV("updateProxyConfig");
808 sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
809 if (thisplayer == NULL) {
810 return;
811 }
812
813 if (proxyProps == NULL) {
814 thisplayer->updateProxyConfig(
815 NULL /* host */, 0 /* port */, NULL /* exclusionList */);
816 } else {
817 jstring hostObj = (jstring)env->CallObjectMethod(
818 proxyProps, fields.proxyConfigGetHost);
819
820 const char *host = env->GetStringUTFChars(hostObj, NULL);
821
822 int port = env->CallIntMethod(proxyProps, fields.proxyConfigGetPort);
823
824 jstring exclusionListObj = (jstring)env->CallObjectMethod(
825 proxyProps, fields.proxyConfigGetExclusionList);
826
827 const char *exclusionList =
828 env->GetStringUTFChars(exclusionListObj, NULL);
829
830 if (host != NULL && exclusionListObj != NULL) {
831 thisplayer->updateProxyConfig(host, port, exclusionList);
832 }
833
834 if (exclusionList != NULL) {
835 env->ReleaseStringUTFChars(exclusionListObj, exclusionList);
836 exclusionList = NULL;
837 }
838
839 if (host != NULL) {
840 env->ReleaseStringUTFChars(hostObj, host);
841 host = NULL;
842 }
843 }
844}
845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846// ----------------------------------------------------------------------------
847
848static JNINativeMethod gMethods[] = {
James Dong17524dc2011-05-04 13:41:58 -0700849 {
850 "_setDataSource",
851 "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
852 (void *)android_media_MediaPlayer_setDataSourceAndHeaders
853 },
854
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700855 {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700856 {"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 {"prepare", "()V", (void *)android_media_MediaPlayer_prepare},
858 {"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync},
859 {"_start", "()V", (void *)android_media_MediaPlayer_start},
860 {"_stop", "()V", (void *)android_media_MediaPlayer_stop},
861 {"getVideoWidth", "()I", (void *)android_media_MediaPlayer_getVideoWidth},
862 {"getVideoHeight", "()I", (void *)android_media_MediaPlayer_getVideoHeight},
863 {"seekTo", "(I)V", (void *)android_media_MediaPlayer_seekTo},
864 {"_pause", "()V", (void *)android_media_MediaPlayer_pause},
865 {"isPlaying", "()Z", (void *)android_media_MediaPlayer_isPlaying},
866 {"getCurrentPosition", "()I", (void *)android_media_MediaPlayer_getCurrentPosition},
867 {"getDuration", "()I", (void *)android_media_MediaPlayer_getDuration},
868 {"_release", "()V", (void *)android_media_MediaPlayer_release},
869 {"_reset", "()V", (void *)android_media_MediaPlayer_reset},
870 {"setAudioStreamType", "(I)V", (void *)android_media_MediaPlayer_setAudioStreamType},
871 {"setLooping", "(Z)V", (void *)android_media_MediaPlayer_setLooping},
872 {"isLooping", "()Z", (void *)android_media_MediaPlayer_isLooping},
873 {"setVolume", "(FF)V", (void *)android_media_MediaPlayer_setVolume},
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700874 {"native_invoke", "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700875 {"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter},
Nicolas Catania5d55c712009-07-09 09:21:33 -0700876 {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata},
Marco Nelissen4935d052009-08-03 11:12:58 -0700877 {"native_init", "()V", (void *)android_media_MediaPlayer_native_init},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 {"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup},
879 {"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
Eric Laurent619346f2010-06-21 09:27:30 -0700880 {"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id},
881 {"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id},
Eric Laurent7070b362010-07-16 07:43:46 -0700882 {"setAuxEffectSendLevel", "(F)V", (void *)android_media_MediaPlayer_setAuxEffectSendLevel},
883 {"attachAuxEffect", "(I)V", (void *)android_media_MediaPlayer_attachAuxEffect},
Gloria Wangd211f412011-02-19 18:37:57 -0800884 {"native_pullBatteryData", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_pullBatteryData},
John Grossman720aa282012-02-22 15:38:35 -0800885 {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I", (void *)android_media_MediaPlayer_setRetransmitEndpoint},
Marco Nelissen84b83202012-02-28 16:07:44 -0800886 {"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer},
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700887 {"updateProxyConfig", "(Landroid/net/ProxyProperties;)V", (void *)android_media_MediaPlayer_updateProxyConfig},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800888};
889
890static const char* const kClassPathName = "android/media/MediaPlayer";
891
Marco Nelissen4935d052009-08-03 11:12:58 -0700892// This function only registers the native methods
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893static int register_android_media_MediaPlayer(JNIEnv *env)
894{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895 return AndroidRuntime::registerNativeMethods(env,
896 "android/media/MediaPlayer", gMethods, NELEM(gMethods));
897}
898
Zhijun He212e78d2013-06-07 11:36:23 -0700899extern int register_android_media_ImageReader(JNIEnv *env);
Andreas Huber8240d922012-04-04 14:06:32 -0700900extern int register_android_media_Crypto(JNIEnv *env);
Jeff Tinker8a0c80f2013-02-08 10:20:44 -0800901extern int register_android_media_Drm(JNIEnv *env);
Andreas Huber88572f72012-02-21 11:47:18 -0800902extern int register_android_media_MediaCodec(JNIEnv *env);
903extern int register_android_media_MediaExtractor(JNIEnv *env);
Andreas Huber5a04bf32012-03-29 16:41:38 -0700904extern int register_android_media_MediaCodecList(JNIEnv *env);
Andreas Huberbfb9fb12009-12-03 11:31:19 -0800905extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
ztenghui68ccf102013-02-13 14:07:02 -0800906extern int register_android_media_MediaMuxer(JNIEnv *env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907extern int register_android_media_MediaRecorder(JNIEnv *env);
908extern int register_android_media_MediaScanner(JNIEnv *env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909extern int register_android_media_ResampleInputStream(JNIEnv *env);
James Dongc3711942010-01-19 17:45:38 -0800910extern int register_android_media_MediaProfiles(JNIEnv *env);
Andreas Huberbfb9fb12009-12-03 11:31:19 -0800911extern int register_android_media_AmrInputStream(JNIEnv *env);
Mike Lockwood0cd01362010-12-30 11:54:33 -0500912extern int register_android_mtp_MtpDatabase(JNIEnv *env);
Mike Lockwood8182e722010-12-30 15:38:45 -0500913extern int register_android_mtp_MtpDevice(JNIEnv *env);
Mike Lockwood0cd01362010-12-30 11:54:33 -0500914extern int register_android_mtp_MtpServer(JNIEnv *env);
Andreas Huberbfb9fb12009-12-03 11:31:19 -0800915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916jint JNI_OnLoad(JavaVM* vm, void* reserved)
917{
918 JNIEnv* env = NULL;
919 jint result = -1;
920
921 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
Steve Block3762c312012-01-06 19:20:56 +0000922 ALOGE("ERROR: GetEnv failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800923 goto bail;
924 }
925 assert(env != NULL);
926
Zhijun He212e78d2013-06-07 11:36:23 -0700927 if (register_android_media_ImageReader(env) < 0) {
928 ALOGE("ERROR: ImageReader native registration failed");
929 goto bail;
930 }
931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 if (register_android_media_MediaPlayer(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000933 ALOGE("ERROR: MediaPlayer native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 goto bail;
935 }
936
937 if (register_android_media_MediaRecorder(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000938 ALOGE("ERROR: MediaRecorder native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 goto bail;
940 }
941
942 if (register_android_media_MediaScanner(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000943 ALOGE("ERROR: MediaScanner native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 goto bail;
945 }
946
947 if (register_android_media_MediaMetadataRetriever(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000948 ALOGE("ERROR: MediaMetadataRetriever native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 goto bail;
950 }
951
952 if (register_android_media_AmrInputStream(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000953 ALOGE("ERROR: AmrInputStream native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 goto bail;
955 }
956
957 if (register_android_media_ResampleInputStream(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000958 ALOGE("ERROR: ResampleInputStream native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 goto bail;
960 }
961
James Dongc3711942010-01-19 17:45:38 -0800962 if (register_android_media_MediaProfiles(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000963 ALOGE("ERROR: MediaProfiles native registration failed");
James Dongc3711942010-01-19 17:45:38 -0800964 goto bail;
965 }
966
Mike Lockwood0cd01362010-12-30 11:54:33 -0500967 if (register_android_mtp_MtpDatabase(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000968 ALOGE("ERROR: MtpDatabase native registration failed");
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400969 goto bail;
970 }
971
Mike Lockwood8182e722010-12-30 15:38:45 -0500972 if (register_android_mtp_MtpDevice(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000973 ALOGE("ERROR: MtpDevice native registration failed");
Mike Lockwood8182e722010-12-30 15:38:45 -0500974 goto bail;
975 }
976
Mike Lockwood0cd01362010-12-30 11:54:33 -0500977 if (register_android_mtp_MtpServer(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000978 ALOGE("ERROR: MtpServer native registration failed");
Mike Lockwood81ea83d2010-06-30 17:49:41 -0400979 goto bail;
980 }
981
Andreas Huber88572f72012-02-21 11:47:18 -0800982 if (register_android_media_MediaCodec(env) < 0) {
983 ALOGE("ERROR: MediaCodec native registration failed");
984 goto bail;
985 }
986
987 if (register_android_media_MediaExtractor(env) < 0) {
988 ALOGE("ERROR: MediaCodec native registration failed");
989 goto bail;
990 }
991
ztenghui68ccf102013-02-13 14:07:02 -0800992 if (register_android_media_MediaMuxer(env) < 0) {
993 ALOGE("ERROR: MediaMuxer native registration failed");
994 goto bail;
995 }
996
Andreas Huber5a04bf32012-03-29 16:41:38 -0700997 if (register_android_media_MediaCodecList(env) < 0) {
998 ALOGE("ERROR: MediaCodec native registration failed");
999 goto bail;
1000 }
1001
Andreas Huber8240d922012-04-04 14:06:32 -07001002 if (register_android_media_Crypto(env) < 0) {
1003 ALOGE("ERROR: MediaCodec native registration failed");
1004 goto bail;
1005 }
1006
Jeff Tinker8a0c80f2013-02-08 10:20:44 -08001007 if (register_android_media_Drm(env) < 0) {
1008 ALOGE("ERROR: MediaDrm native registration failed");
1009 goto bail;
1010 }
1011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 /* success -- return valid version number */
1013 result = JNI_VERSION_1_4;
1014
1015bail:
1016 return result;
1017}
1018
1019// KTHXBYE