1 /*
2 **
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>
23 #include <media/AudioResamplerPublic.h>
24 #include <media/IMediaHTTPService.h>
25 #include <media/MediaPlayerInterface.h>
26 #include <stdio.h>
27 #include <assert.h>
28 #include <limits.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <utils/threads.h>
32 #include "jni.h"
33 #include "JNIHelp.h"
34 #include "android_runtime/AndroidRuntime.h"
35 #include "android_runtime/android_view_Surface.h"
36 #include "android_runtime/Log.h"
37 #include "utils/Errors.h" // for status_t
38 #include "utils/KeyedVector.h"
39 #include "utils/String8.h"
40 #include "android_media_MediaDataSource.h"
41 #include "android_media_PlaybackParams.h"
42 #include "android_media_SyncParams.h"
43 #include "android_media_Utils.h"
44
45 #include "android_os_Parcel.h"
46 #include "android_util_Binder.h"
47 #include <binder/Parcel.h>
48 #include <gui/IGraphicBufferProducer.h>
49 #include <gui/Surface.h>
50 #include <binder/IPCThreadState.h>
51 #include <binder/IServiceManager.h>
52
53 #include "android_util_Binder.h"
54 // ----------------------------------------------------------------------------
55
56 using namespace android;
57
58 // ----------------------------------------------------------------------------
59
60 struct fields_t {
61 jfieldID context;
62 jfieldID surface_texture;
63
64 jmethodID post_event;
65
66 jmethodID proxyConfigGetHost;
67 jmethodID proxyConfigGetPort;
68 jmethodID proxyConfigGetExclusionList;
69 };
70 static fields_t fields;
71
72 static PlaybackParams::fields_t gPlaybackParamsFields;
73 static SyncParams::fields_t gSyncParamsFields;
74
75 static Mutex sLock;
76
77 // ----------------------------------------------------------------------------
78 // ref-counted object for callbacks
79 class JNIMediaPlayerListener: public MediaPlayerListener
80 {
81 public:
82 JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
83 ~JNIMediaPlayerListener();
84 virtual void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL);
85 private:
86 JNIMediaPlayerListener();
87 jclass mClass; // Reference to MediaPlayer class
88 jobject mObject; // Weak ref to MediaPlayer Java object to call on
89 };
90
JNIMediaPlayerListener(JNIEnv * env,jobject thiz,jobject weak_thiz)91 JNIMediaPlayerListener::JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
92 {
93
94 // Hold onto the MediaPlayer class for use in calling the static method
95 // that posts events to the application thread.
96 jclass clazz = env->GetObjectClass(thiz);
97 if (clazz == NULL) {
98 ALOGE("Can't find android/media/MediaPlayer");
99 jniThrowException(env, "java/lang/Exception", NULL);
100 return;
101 }
102 mClass = (jclass)env->NewGlobalRef(clazz);
103
104 // We use a weak reference so the MediaPlayer object can be garbage collected.
105 // The reference is only used as a proxy for callbacks.
106 mObject = env->NewGlobalRef(weak_thiz);
107 }
108
~JNIMediaPlayerListener()109 JNIMediaPlayerListener::~JNIMediaPlayerListener()
110 {
111 // remove global references
112 JNIEnv *env = AndroidRuntime::getJNIEnv();
113 env->DeleteGlobalRef(mObject);
114 env->DeleteGlobalRef(mClass);
115 }
116
notify(int msg,int ext1,int ext2,const Parcel * obj)117 void JNIMediaPlayerListener::notify(int msg, int ext1, int ext2, const Parcel *obj)
118 {
119 JNIEnv *env = AndroidRuntime::getJNIEnv();
120 if (obj && obj->dataSize() > 0) {
121 jobject jParcel = createJavaParcelObject(env);
122 if (jParcel != NULL) {
123 Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
124 nativeParcel->setData(obj->data(), obj->dataSize());
125 env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
126 msg, ext1, ext2, jParcel);
127 env->DeleteLocalRef(jParcel);
128 }
129 } else {
130 env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
131 msg, ext1, ext2, NULL);
132 }
133 if (env->ExceptionCheck()) {
134 ALOGW("An exception occurred while notifying an event.");
135 LOGW_EX(env);
136 env->ExceptionClear();
137 }
138 }
139
140 // ----------------------------------------------------------------------------
141
getMediaPlayer(JNIEnv * env,jobject thiz)142 static sp<MediaPlayer> getMediaPlayer(JNIEnv* env, jobject thiz)
143 {
144 Mutex::Autolock l(sLock);
145 MediaPlayer* const p = (MediaPlayer*)env->GetLongField(thiz, fields.context);
146 return sp<MediaPlayer>(p);
147 }
148
setMediaPlayer(JNIEnv * env,jobject thiz,const sp<MediaPlayer> & player)149 static sp<MediaPlayer> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaPlayer>& player)
150 {
151 Mutex::Autolock l(sLock);
152 sp<MediaPlayer> old = (MediaPlayer*)env->GetLongField(thiz, fields.context);
153 if (player.get()) {
154 player->incStrong((void*)setMediaPlayer);
155 }
156 if (old != 0) {
157 old->decStrong((void*)setMediaPlayer);
158 }
159 env->SetLongField(thiz, fields.context, (jlong)player.get());
160 return old;
161 }
162
163 // If exception is NULL and opStatus is not OK, this method sends an error
164 // event to the client application; otherwise, if exception is not NULL and
165 // opStatus is not OK, this method throws the given exception to the client
166 // application.
process_media_player_call(JNIEnv * env,jobject thiz,status_t opStatus,const char * exception,const char * message)167 static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStatus, const char* exception, const char *message)
168 {
169 if (exception == NULL) { // Don't throw exception. Instead, send an event.
170 if (opStatus != (status_t) OK) {
171 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
172 if (mp != 0) mp->notify(MEDIA_ERROR, opStatus, 0);
173 }
174 } else { // Throw exception!
175 if ( opStatus == (status_t) INVALID_OPERATION ) {
176 jniThrowException(env, "java/lang/IllegalStateException", NULL);
177 } else if ( opStatus == (status_t) BAD_VALUE ) {
178 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
179 } else if ( opStatus == (status_t) PERMISSION_DENIED ) {
180 jniThrowException(env, "java/lang/SecurityException", NULL);
181 } else if ( opStatus != (status_t) OK ) {
182 if (strlen(message) > 230) {
183 // if the message is too long, don't bother displaying the status code
184 jniThrowException( env, exception, message);
185 } else {
186 char msg[256];
187 // append the status code to the message
188 sprintf(msg, "%s: status=0x%X", message, opStatus);
189 jniThrowException( env, exception, msg);
190 }
191 }
192 }
193 }
194
195 static void
android_media_MediaPlayer_setDataSourceAndHeaders(JNIEnv * env,jobject thiz,jobject httpServiceBinderObj,jstring path,jobjectArray keys,jobjectArray values)196 android_media_MediaPlayer_setDataSourceAndHeaders(
197 JNIEnv *env, jobject thiz, jobject httpServiceBinderObj, jstring path,
198 jobjectArray keys, jobjectArray values) {
199
200 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
201 if (mp == NULL ) {
202 jniThrowException(env, "java/lang/IllegalStateException", NULL);
203 return;
204 }
205
206 if (path == NULL) {
207 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
208 return;
209 }
210
211 const char *tmp = env->GetStringUTFChars(path, NULL);
212 if (tmp == NULL) { // Out of memory
213 return;
214 }
215 ALOGV("setDataSource: path %s", tmp);
216
217 String8 pathStr(tmp);
218 env->ReleaseStringUTFChars(path, tmp);
219 tmp = NULL;
220
221 // We build a KeyedVector out of the key and val arrays
222 KeyedVector<String8, String8> headersVector;
223 if (!ConvertKeyValueArraysToKeyedVector(
224 env, keys, values, &headersVector)) {
225 return;
226 }
227
228 sp<IMediaHTTPService> httpService;
229 if (httpServiceBinderObj != NULL) {
230 sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
231 httpService = interface_cast<IMediaHTTPService>(binder);
232 }
233
234 status_t opStatus =
235 mp->setDataSource(
236 httpService,
237 pathStr,
238 headersVector.size() > 0? &headersVector : NULL);
239
240 process_media_player_call(
241 env, thiz, opStatus, "java/io/IOException",
242 "setDataSource failed." );
243 }
244
245 static void
android_media_MediaPlayer_setDataSourceFD(JNIEnv * env,jobject thiz,jobject fileDescriptor,jlong offset,jlong length)246 android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
247 {
248 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
249 if (mp == NULL ) {
250 jniThrowException(env, "java/lang/IllegalStateException", NULL);
251 return;
252 }
253
254 if (fileDescriptor == NULL) {
255 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
256 return;
257 }
258 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
259 ALOGV("setDataSourceFD: fd %d", fd);
260 process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
261 }
262
263 static void
android_media_MediaPlayer_setDataSourceCallback(JNIEnv * env,jobject thiz,jobject dataSource)264 android_media_MediaPlayer_setDataSourceCallback(JNIEnv *env, jobject thiz, jobject dataSource)
265 {
266 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
267 if (mp == NULL ) {
268 jniThrowException(env, "java/lang/IllegalStateException", NULL);
269 return;
270 }
271
272 if (dataSource == NULL) {
273 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
274 return;
275 }
276 sp<IDataSource> callbackDataSource = new JMediaDataSource(env, dataSource);
277 process_media_player_call(env, thiz, mp->setDataSource(callbackDataSource), "java/lang/RuntimeException", "setDataSourceCallback failed." );
278 }
279
280 static sp<IGraphicBufferProducer>
getVideoSurfaceTexture(JNIEnv * env,jobject thiz)281 getVideoSurfaceTexture(JNIEnv* env, jobject thiz) {
282 IGraphicBufferProducer * const p = (IGraphicBufferProducer*)env->GetLongField(thiz, fields.surface_texture);
283 return sp<IGraphicBufferProducer>(p);
284 }
285
286 static void
decVideoSurfaceRef(JNIEnv * env,jobject thiz)287 decVideoSurfaceRef(JNIEnv *env, jobject thiz)
288 {
289 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
290 if (mp == NULL) {
291 return;
292 }
293
294 sp<IGraphicBufferProducer> old_st = getVideoSurfaceTexture(env, thiz);
295 if (old_st != NULL) {
296 old_st->decStrong((void*)decVideoSurfaceRef);
297 }
298 }
299
300 static void
setVideoSurface(JNIEnv * env,jobject thiz,jobject jsurface,jboolean mediaPlayerMustBeAlive)301 setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface, jboolean mediaPlayerMustBeAlive)
302 {
303 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
304 if (mp == NULL) {
305 if (mediaPlayerMustBeAlive) {
306 jniThrowException(env, "java/lang/IllegalStateException", NULL);
307 }
308 return;
309 }
310
311 decVideoSurfaceRef(env, thiz);
312
313 sp<IGraphicBufferProducer> new_st;
314 if (jsurface) {
315 sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
316 if (surface != NULL) {
317 new_st = surface->getIGraphicBufferProducer();
318 if (new_st == NULL) {
319 jniThrowException(env, "java/lang/IllegalArgumentException",
320 "The surface does not have a binding SurfaceTexture!");
321 return;
322 }
323 new_st->incStrong((void*)decVideoSurfaceRef);
324 } else {
325 jniThrowException(env, "java/lang/IllegalArgumentException",
326 "The surface has been released");
327 return;
328 }
329 }
330
331 env->SetLongField(thiz, fields.surface_texture, (jlong)new_st.get());
332
333 // This will fail if the media player has not been initialized yet. This
334 // can be the case if setDisplay() on MediaPlayer.java has been called
335 // before setDataSource(). The redundant call to setVideoSurfaceTexture()
336 // in prepare/prepareAsync covers for this case.
337 mp->setVideoSurfaceTexture(new_st);
338 }
339
340 static void
android_media_MediaPlayer_setVideoSurface(JNIEnv * env,jobject thiz,jobject jsurface)341 android_media_MediaPlayer_setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface)
342 {
343 setVideoSurface(env, thiz, jsurface, true /* mediaPlayerMustBeAlive */);
344 }
345
346 static void
android_media_MediaPlayer_prepare(JNIEnv * env,jobject thiz)347 android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz)
348 {
349 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
350 if (mp == NULL ) {
351 jniThrowException(env, "java/lang/IllegalStateException", NULL);
352 return;
353 }
354
355 // Handle the case where the display surface was set before the mp was
356 // initialized. We try again to make it stick.
357 sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
358 mp->setVideoSurfaceTexture(st);
359
360 process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
361 }
362
363 static void
android_media_MediaPlayer_prepareAsync(JNIEnv * env,jobject thiz)364 android_media_MediaPlayer_prepareAsync(JNIEnv *env, jobject thiz)
365 {
366 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
367 if (mp == NULL ) {
368 jniThrowException(env, "java/lang/IllegalStateException", NULL);
369 return;
370 }
371
372 // Handle the case where the display surface was set before the mp was
373 // initialized. We try again to make it stick.
374 sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
375 mp->setVideoSurfaceTexture(st);
376
377 process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
378 }
379
380 static void
android_media_MediaPlayer_start(JNIEnv * env,jobject thiz)381 android_media_MediaPlayer_start(JNIEnv *env, jobject thiz)
382 {
383 ALOGV("start");
384 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
385 if (mp == NULL ) {
386 jniThrowException(env, "java/lang/IllegalStateException", NULL);
387 return;
388 }
389 process_media_player_call( env, thiz, mp->start(), NULL, NULL );
390 }
391
392 static void
android_media_MediaPlayer_stop(JNIEnv * env,jobject thiz)393 android_media_MediaPlayer_stop(JNIEnv *env, jobject thiz)
394 {
395 ALOGV("stop");
396 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
397 if (mp == NULL ) {
398 jniThrowException(env, "java/lang/IllegalStateException", NULL);
399 return;
400 }
401 process_media_player_call( env, thiz, mp->stop(), NULL, NULL );
402 }
403
404 static void
android_media_MediaPlayer_pause(JNIEnv * env,jobject thiz)405 android_media_MediaPlayer_pause(JNIEnv *env, jobject thiz)
406 {
407 ALOGV("pause");
408 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
409 if (mp == NULL ) {
410 jniThrowException(env, "java/lang/IllegalStateException", NULL);
411 return;
412 }
413 process_media_player_call( env, thiz, mp->pause(), NULL, NULL );
414 }
415
416 static jboolean
android_media_MediaPlayer_isPlaying(JNIEnv * env,jobject thiz)417 android_media_MediaPlayer_isPlaying(JNIEnv *env, jobject thiz)
418 {
419 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
420 if (mp == NULL ) {
421 jniThrowException(env, "java/lang/IllegalStateException", NULL);
422 return JNI_FALSE;
423 }
424 const jboolean is_playing = mp->isPlaying();
425
426 ALOGV("isPlaying: %d", is_playing);
427 return is_playing;
428 }
429
430 static void
android_media_MediaPlayer_setPlaybackParams(JNIEnv * env,jobject thiz,jobject params)431 android_media_MediaPlayer_setPlaybackParams(JNIEnv *env, jobject thiz, jobject params)
432 {
433 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
434 if (mp == NULL) {
435 jniThrowException(env, "java/lang/IllegalStateException", NULL);
436 return;
437 }
438
439 PlaybackParams pbp;
440 pbp.fillFromJobject(env, gPlaybackParamsFields, params);
441 ALOGV("setPlaybackParams: %d:%f %d:%f %d:%u %d:%u",
442 pbp.speedSet, pbp.audioRate.mSpeed,
443 pbp.pitchSet, pbp.audioRate.mPitch,
444 pbp.audioFallbackModeSet, pbp.audioRate.mFallbackMode,
445 pbp.audioStretchModeSet, pbp.audioRate.mStretchMode);
446
447 AudioPlaybackRate rate;
448 status_t err = mp->getPlaybackSettings(&rate);
449 if (err == OK) {
450 bool updatedRate = false;
451 if (pbp.speedSet) {
452 rate.mSpeed = pbp.audioRate.mSpeed;
453 updatedRate = true;
454 }
455 if (pbp.pitchSet) {
456 rate.mPitch = pbp.audioRate.mPitch;
457 updatedRate = true;
458 }
459 if (pbp.audioFallbackModeSet) {
460 rate.mFallbackMode = pbp.audioRate.mFallbackMode;
461 updatedRate = true;
462 }
463 if (pbp.audioStretchModeSet) {
464 rate.mStretchMode = pbp.audioRate.mStretchMode;
465 updatedRate = true;
466 }
467 if (updatedRate) {
468 err = mp->setPlaybackSettings(rate);
469 }
470 }
471 process_media_player_call(
472 env, thiz, err,
473 "java/lang/IllegalStateException", "unexpected error");
474 }
475
476 static jobject
android_media_MediaPlayer_getPlaybackParams(JNIEnv * env,jobject thiz)477 android_media_MediaPlayer_getPlaybackParams(JNIEnv *env, jobject thiz)
478 {
479 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
480 if (mp == NULL) {
481 jniThrowException(env, "java/lang/IllegalStateException", NULL);
482 return NULL;
483 }
484
485 PlaybackParams pbp;
486 AudioPlaybackRate &audioRate = pbp.audioRate;
487 process_media_player_call(
488 env, thiz, mp->getPlaybackSettings(&audioRate),
489 "java/lang/IllegalStateException", "unexpected error");
490 ALOGV("getPlaybackSettings: %f %f %d %d",
491 audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode);
492
493 pbp.speedSet = true;
494 pbp.pitchSet = true;
495 pbp.audioFallbackModeSet = true;
496 pbp.audioStretchModeSet = true;
497
498 return pbp.asJobject(env, gPlaybackParamsFields);
499 }
500
501 static void
android_media_MediaPlayer_setSyncParams(JNIEnv * env,jobject thiz,jobject params)502 android_media_MediaPlayer_setSyncParams(JNIEnv *env, jobject thiz, jobject params)
503 {
504 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
505 if (mp == NULL) {
506 jniThrowException(env, "java/lang/IllegalStateException", NULL);
507 return;
508 }
509
510 SyncParams scp;
511 scp.fillFromJobject(env, gSyncParamsFields, params);
512 ALOGV("setSyncParams: %d:%d %d:%d %d:%f %d:%f",
513 scp.syncSourceSet, scp.sync.mSource,
514 scp.audioAdjustModeSet, scp.sync.mAudioAdjustMode,
515 scp.toleranceSet, scp.sync.mTolerance,
516 scp.frameRateSet, scp.frameRate);
517
518 AVSyncSettings avsync;
519 float videoFrameRate;
520 status_t err = mp->getSyncSettings(&avsync, &videoFrameRate);
521 if (err == OK) {
522 bool updatedSync = scp.frameRateSet;
523 if (scp.syncSourceSet) {
524 avsync.mSource = scp.sync.mSource;
525 updatedSync = true;
526 }
527 if (scp.audioAdjustModeSet) {
528 avsync.mAudioAdjustMode = scp.sync.mAudioAdjustMode;
529 updatedSync = true;
530 }
531 if (scp.toleranceSet) {
532 avsync.mTolerance = scp.sync.mTolerance;
533 updatedSync = true;
534 }
535 if (updatedSync) {
536 err = mp->setSyncSettings(avsync, scp.frameRateSet ? scp.frameRate : -1.f);
537 }
538 }
539 process_media_player_call(
540 env, thiz, err,
541 "java/lang/IllegalStateException", "unexpected error");
542 }
543
544 static jobject
android_media_MediaPlayer_getSyncParams(JNIEnv * env,jobject thiz)545 android_media_MediaPlayer_getSyncParams(JNIEnv *env, jobject thiz)
546 {
547 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
548 if (mp == NULL) {
549 jniThrowException(env, "java/lang/IllegalStateException", NULL);
550 return NULL;
551 }
552
553 SyncParams scp;
554 scp.frameRate = -1.f;
555 process_media_player_call(
556 env, thiz, mp->getSyncSettings(&scp.sync, &scp.frameRate),
557 "java/lang/IllegalStateException", "unexpected error");
558
559 ALOGV("getSyncSettings: %d %d %f %f",
560 scp.sync.mSource, scp.sync.mAudioAdjustMode, scp.sync.mTolerance, scp.frameRate);
561
562 // sanity check params
563 if (scp.sync.mSource >= AVSYNC_SOURCE_MAX
564 || scp.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX
565 || scp.sync.mTolerance < 0.f
566 || scp.sync.mTolerance >= AVSYNC_TOLERANCE_MAX) {
567 jniThrowException(env, "java/lang/IllegalStateException", NULL);
568 return NULL;
569 }
570
571 scp.syncSourceSet = true;
572 scp.audioAdjustModeSet = true;
573 scp.toleranceSet = true;
574 scp.frameRateSet = scp.frameRate >= 0.f;
575
576 return scp.asJobject(env, gSyncParamsFields);
577 }
578
579 static void
android_media_MediaPlayer_seekTo(JNIEnv * env,jobject thiz,jint msec)580 android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, jint msec)
581 {
582 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
583 if (mp == NULL ) {
584 jniThrowException(env, "java/lang/IllegalStateException", NULL);
585 return;
586 }
587 ALOGV("seekTo: %d(msec)", msec);
588 process_media_player_call( env, thiz, mp->seekTo(msec), NULL, NULL );
589 }
590
591 static jint
android_media_MediaPlayer_getVideoWidth(JNIEnv * env,jobject thiz)592 android_media_MediaPlayer_getVideoWidth(JNIEnv *env, jobject thiz)
593 {
594 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
595 if (mp == NULL ) {
596 jniThrowException(env, "java/lang/IllegalStateException", NULL);
597 return 0;
598 }
599 int w;
600 if (0 != mp->getVideoWidth(&w)) {
601 ALOGE("getVideoWidth failed");
602 w = 0;
603 }
604 ALOGV("getVideoWidth: %d", w);
605 return (jint) w;
606 }
607
608 static jint
android_media_MediaPlayer_getVideoHeight(JNIEnv * env,jobject thiz)609 android_media_MediaPlayer_getVideoHeight(JNIEnv *env, jobject thiz)
610 {
611 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
612 if (mp == NULL ) {
613 jniThrowException(env, "java/lang/IllegalStateException", NULL);
614 return 0;
615 }
616 int h;
617 if (0 != mp->getVideoHeight(&h)) {
618 ALOGE("getVideoHeight failed");
619 h = 0;
620 }
621 ALOGV("getVideoHeight: %d", h);
622 return (jint) h;
623 }
624
625
626 static jint
android_media_MediaPlayer_getCurrentPosition(JNIEnv * env,jobject thiz)627 android_media_MediaPlayer_getCurrentPosition(JNIEnv *env, jobject thiz)
628 {
629 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
630 if (mp == NULL ) {
631 jniThrowException(env, "java/lang/IllegalStateException", NULL);
632 return 0;
633 }
634 int msec;
635 process_media_player_call( env, thiz, mp->getCurrentPosition(&msec), NULL, NULL );
636 ALOGV("getCurrentPosition: %d (msec)", msec);
637 return (jint) msec;
638 }
639
640 static jint
android_media_MediaPlayer_getDuration(JNIEnv * env,jobject thiz)641 android_media_MediaPlayer_getDuration(JNIEnv *env, jobject thiz)
642 {
643 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
644 if (mp == NULL ) {
645 jniThrowException(env, "java/lang/IllegalStateException", NULL);
646 return 0;
647 }
648 int msec;
649 process_media_player_call( env, thiz, mp->getDuration(&msec), NULL, NULL );
650 ALOGV("getDuration: %d (msec)", msec);
651 return (jint) msec;
652 }
653
654 static void
android_media_MediaPlayer_reset(JNIEnv * env,jobject thiz)655 android_media_MediaPlayer_reset(JNIEnv *env, jobject thiz)
656 {
657 ALOGV("reset");
658 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
659 if (mp == NULL ) {
660 jniThrowException(env, "java/lang/IllegalStateException", NULL);
661 return;
662 }
663 process_media_player_call( env, thiz, mp->reset(), NULL, NULL );
664 }
665
666 static void
android_media_MediaPlayer_setAudioStreamType(JNIEnv * env,jobject thiz,jint streamtype)667 android_media_MediaPlayer_setAudioStreamType(JNIEnv *env, jobject thiz, jint streamtype)
668 {
669 ALOGV("setAudioStreamType: %d", streamtype);
670 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
671 if (mp == NULL ) {
672 jniThrowException(env, "java/lang/IllegalStateException", NULL);
673 return;
674 }
675 process_media_player_call( env, thiz, mp->setAudioStreamType((audio_stream_type_t) streamtype) , NULL, NULL );
676 }
677
678 static jint
android_media_MediaPlayer_getAudioStreamType(JNIEnv * env,jobject thiz)679 android_media_MediaPlayer_getAudioStreamType(JNIEnv *env, jobject thiz)
680 {
681 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
682 if (mp == NULL ) {
683 jniThrowException(env, "java/lang/IllegalStateException", NULL);
684 return 0;
685 }
686 audio_stream_type_t streamtype;
687 process_media_player_call( env, thiz, mp->getAudioStreamType(&streamtype), NULL, NULL );
688 ALOGV("getAudioStreamType: %d (streamtype)", streamtype);
689 return (jint) streamtype;
690 }
691
692 static jboolean
android_media_MediaPlayer_setParameter(JNIEnv * env,jobject thiz,jint key,jobject java_request)693 android_media_MediaPlayer_setParameter(JNIEnv *env, jobject thiz, jint key, jobject java_request)
694 {
695 ALOGV("setParameter: key %d", key);
696 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
697 if (mp == NULL ) {
698 jniThrowException(env, "java/lang/IllegalStateException", NULL);
699 return false;
700 }
701
702 Parcel *request = parcelForJavaObject(env, java_request);
703 status_t err = mp->setParameter(key, *request);
704 if (err == OK) {
705 return true;
706 } else {
707 return false;
708 }
709 }
710
711 static void
android_media_MediaPlayer_setLooping(JNIEnv * env,jobject thiz,jboolean looping)712 android_media_MediaPlayer_setLooping(JNIEnv *env, jobject thiz, jboolean looping)
713 {
714 ALOGV("setLooping: %d", looping);
715 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
716 if (mp == NULL ) {
717 jniThrowException(env, "java/lang/IllegalStateException", NULL);
718 return;
719 }
720 process_media_player_call( env, thiz, mp->setLooping(looping), NULL, NULL );
721 }
722
723 static jboolean
android_media_MediaPlayer_isLooping(JNIEnv * env,jobject thiz)724 android_media_MediaPlayer_isLooping(JNIEnv *env, jobject thiz)
725 {
726 ALOGV("isLooping");
727 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
728 if (mp == NULL ) {
729 jniThrowException(env, "java/lang/IllegalStateException", NULL);
730 return JNI_FALSE;
731 }
732 return mp->isLooping() ? JNI_TRUE : JNI_FALSE;
733 }
734
735 static void
android_media_MediaPlayer_setVolume(JNIEnv * env,jobject thiz,jfloat leftVolume,jfloat rightVolume)736 android_media_MediaPlayer_setVolume(JNIEnv *env, jobject thiz, jfloat leftVolume, jfloat rightVolume)
737 {
738 ALOGV("setVolume: left %f right %f", (float) leftVolume, (float) rightVolume);
739 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
740 if (mp == NULL ) {
741 jniThrowException(env, "java/lang/IllegalStateException", NULL);
742 return;
743 }
744 process_media_player_call( env, thiz, mp->setVolume((float) leftVolume, (float) rightVolume), NULL, NULL );
745 }
746
747 // Sends the request and reply parcels to the media player via the
748 // binder interface.
749 static jint
android_media_MediaPlayer_invoke(JNIEnv * env,jobject thiz,jobject java_request,jobject java_reply)750 android_media_MediaPlayer_invoke(JNIEnv *env, jobject thiz,
751 jobject java_request, jobject java_reply)
752 {
753 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
754 if (media_player == NULL ) {
755 jniThrowException(env, "java/lang/IllegalStateException", NULL);
756 return UNKNOWN_ERROR;
757 }
758
759 Parcel *request = parcelForJavaObject(env, java_request);
760 Parcel *reply = parcelForJavaObject(env, java_reply);
761
762 // Don't use process_media_player_call which use the async loop to
763 // report errors, instead returns the status.
764 return (jint) media_player->invoke(*request, reply);
765 }
766
767 // Sends the new filter to the client.
768 static jint
android_media_MediaPlayer_setMetadataFilter(JNIEnv * env,jobject thiz,jobject request)769 android_media_MediaPlayer_setMetadataFilter(JNIEnv *env, jobject thiz, jobject request)
770 {
771 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
772 if (media_player == NULL ) {
773 jniThrowException(env, "java/lang/IllegalStateException", NULL);
774 return UNKNOWN_ERROR;
775 }
776
777 Parcel *filter = parcelForJavaObject(env, request);
778
779 if (filter == NULL ) {
780 jniThrowException(env, "java/lang/RuntimeException", "Filter is null");
781 return UNKNOWN_ERROR;
782 }
783
784 return (jint) media_player->setMetadataFilter(*filter);
785 }
786
787 static jboolean
android_media_MediaPlayer_getMetadata(JNIEnv * env,jobject thiz,jboolean update_only,jboolean apply_filter,jobject reply)788 android_media_MediaPlayer_getMetadata(JNIEnv *env, jobject thiz, jboolean update_only,
789 jboolean apply_filter, jobject reply)
790 {
791 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
792 if (media_player == NULL ) {
793 jniThrowException(env, "java/lang/IllegalStateException", NULL);
794 return JNI_FALSE;
795 }
796
797 Parcel *metadata = parcelForJavaObject(env, reply);
798
799 if (metadata == NULL ) {
800 jniThrowException(env, "java/lang/RuntimeException", "Reply parcel is null");
801 return JNI_FALSE;
802 }
803
804 metadata->freeData();
805 // On return metadata is positioned at the beginning of the
806 // metadata. Note however that the parcel actually starts with the
807 // return code so you should not rewind the parcel using
808 // setDataPosition(0).
809 if (media_player->getMetadata(update_only, apply_filter, metadata) == OK) {
810 return JNI_TRUE;
811 } else {
812 return JNI_FALSE;
813 }
814 }
815
816 // This function gets some field IDs, which in turn causes class initialization.
817 // It is called from a static block in MediaPlayer, which won't run until the
818 // first time an instance of this class is used.
819 static void
android_media_MediaPlayer_native_init(JNIEnv * env)820 android_media_MediaPlayer_native_init(JNIEnv *env)
821 {
822 jclass clazz;
823
824 clazz = env->FindClass("android/media/MediaPlayer");
825 if (clazz == NULL) {
826 return;
827 }
828
829 fields.context = env->GetFieldID(clazz, "mNativeContext", "J");
830 if (fields.context == NULL) {
831 return;
832 }
833
834 fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
835 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
836 if (fields.post_event == NULL) {
837 return;
838 }
839
840 fields.surface_texture = env->GetFieldID(clazz, "mNativeSurfaceTexture", "J");
841 if (fields.surface_texture == NULL) {
842 return;
843 }
844
845 env->DeleteLocalRef(clazz);
846
847 clazz = env->FindClass("android/net/ProxyInfo");
848 if (clazz == NULL) {
849 return;
850 }
851
852 fields.proxyConfigGetHost =
853 env->GetMethodID(clazz, "getHost", "()Ljava/lang/String;");
854
855 fields.proxyConfigGetPort =
856 env->GetMethodID(clazz, "getPort", "()I");
857
858 fields.proxyConfigGetExclusionList =
859 env->GetMethodID(clazz, "getExclusionListAsString", "()Ljava/lang/String;");
860
861 env->DeleteLocalRef(clazz);
862
863 gPlaybackParamsFields.init(env);
864 gSyncParamsFields.init(env);
865 }
866
867 static void
android_media_MediaPlayer_native_setup(JNIEnv * env,jobject thiz,jobject weak_this)868 android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
869 {
870 ALOGV("native_setup");
871 sp<MediaPlayer> mp = new MediaPlayer();
872 if (mp == NULL) {
873 jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
874 return;
875 }
876
877 // create new listener and give it to MediaPlayer
878 sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
879 mp->setListener(listener);
880
881 // Stow our new C++ MediaPlayer in an opaque field in the Java object.
882 setMediaPlayer(env, thiz, mp);
883 }
884
885 static void
android_media_MediaPlayer_release(JNIEnv * env,jobject thiz)886 android_media_MediaPlayer_release(JNIEnv *env, jobject thiz)
887 {
888 ALOGV("release");
889 decVideoSurfaceRef(env, thiz);
890 sp<MediaPlayer> mp = setMediaPlayer(env, thiz, 0);
891 if (mp != NULL) {
892 // this prevents native callbacks after the object is released
893 mp->setListener(0);
894 mp->disconnect();
895 }
896 }
897
898 static void
android_media_MediaPlayer_native_finalize(JNIEnv * env,jobject thiz)899 android_media_MediaPlayer_native_finalize(JNIEnv *env, jobject thiz)
900 {
901 ALOGV("native_finalize");
902 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
903 if (mp != NULL) {
904 ALOGW("MediaPlayer finalized without being released");
905 }
906 android_media_MediaPlayer_release(env, thiz);
907 }
908
android_media_MediaPlayer_set_audio_session_id(JNIEnv * env,jobject thiz,jint sessionId)909 static void android_media_MediaPlayer_set_audio_session_id(JNIEnv *env, jobject thiz,
910 jint sessionId) {
911 ALOGV("set_session_id(): %d", sessionId);
912 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
913 if (mp == NULL ) {
914 jniThrowException(env, "java/lang/IllegalStateException", NULL);
915 return;
916 }
917 process_media_player_call( env, thiz, mp->setAudioSessionId((audio_session_t) sessionId), NULL,
918 NULL);
919 }
920
android_media_MediaPlayer_get_audio_session_id(JNIEnv * env,jobject thiz)921 static jint android_media_MediaPlayer_get_audio_session_id(JNIEnv *env, jobject thiz) {
922 ALOGV("get_session_id()");
923 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
924 if (mp == NULL ) {
925 jniThrowException(env, "java/lang/IllegalStateException", NULL);
926 return 0;
927 }
928
929 return (jint) mp->getAudioSessionId();
930 }
931
932 static void
android_media_MediaPlayer_setAuxEffectSendLevel(JNIEnv * env,jobject thiz,jfloat level)933 android_media_MediaPlayer_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level)
934 {
935 ALOGV("setAuxEffectSendLevel: level %f", level);
936 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
937 if (mp == NULL ) {
938 jniThrowException(env, "java/lang/IllegalStateException", NULL);
939 return;
940 }
941 process_media_player_call( env, thiz, mp->setAuxEffectSendLevel(level), NULL, NULL );
942 }
943
android_media_MediaPlayer_attachAuxEffect(JNIEnv * env,jobject thiz,jint effectId)944 static void android_media_MediaPlayer_attachAuxEffect(JNIEnv *env, jobject thiz, jint effectId) {
945 ALOGV("attachAuxEffect(): %d", effectId);
946 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
947 if (mp == NULL ) {
948 jniThrowException(env, "java/lang/IllegalStateException", NULL);
949 return;
950 }
951 process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL );
952 }
953
954 static jint
android_media_MediaPlayer_pullBatteryData(JNIEnv * env,jobject,jobject java_reply)955 android_media_MediaPlayer_pullBatteryData(
956 JNIEnv *env, jobject /* thiz */, jobject java_reply)
957 {
958 sp<IBinder> binder = defaultServiceManager()->getService(String16("media.player"));
959 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
960 if (service.get() == NULL) {
961 jniThrowException(env, "java/lang/RuntimeException", "cannot get MediaPlayerService");
962 return UNKNOWN_ERROR;
963 }
964
965 Parcel *reply = parcelForJavaObject(env, java_reply);
966
967 return (jint) service->pullBatteryData(reply);
968 }
969
970 static jint
android_media_MediaPlayer_setRetransmitEndpoint(JNIEnv * env,jobject thiz,jstring addrString,jint port)971 android_media_MediaPlayer_setRetransmitEndpoint(JNIEnv *env, jobject thiz,
972 jstring addrString, jint port) {
973 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
974 if (mp == NULL ) {
975 jniThrowException(env, "java/lang/IllegalStateException", NULL);
976 return INVALID_OPERATION;
977 }
978
979 const char *cAddrString = NULL;
980
981 if (NULL != addrString) {
982 cAddrString = env->GetStringUTFChars(addrString, NULL);
983 if (cAddrString == NULL) { // Out of memory
984 return NO_MEMORY;
985 }
986 }
987 ALOGV("setRetransmitEndpoint: %s:%d",
988 cAddrString ? cAddrString : "(null)", port);
989
990 status_t ret;
991 if (cAddrString && (port > 0xFFFF)) {
992 ret = BAD_VALUE;
993 } else {
994 ret = mp->setRetransmitEndpoint(cAddrString,
995 static_cast<uint16_t>(port));
996 }
997
998 if (NULL != addrString) {
999 env->ReleaseStringUTFChars(addrString, cAddrString);
1000 }
1001
1002 if (ret == INVALID_OPERATION ) {
1003 jniThrowException(env, "java/lang/IllegalStateException", NULL);
1004 }
1005
1006 return (jint) ret;
1007 }
1008
1009 static void
android_media_MediaPlayer_setNextMediaPlayer(JNIEnv * env,jobject thiz,jobject java_player)1010 android_media_MediaPlayer_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject java_player)
1011 {
1012 ALOGV("setNextMediaPlayer");
1013 sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
1014 if (thisplayer == NULL) {
1015 jniThrowException(env, "java/lang/IllegalStateException", "This player not initialized");
1016 return;
1017 }
1018 sp<MediaPlayer> nextplayer = (java_player == NULL) ? NULL : getMediaPlayer(env, java_player);
1019 if (nextplayer == NULL && java_player != NULL) {
1020 jniThrowException(env, "java/lang/IllegalStateException", "That player not initialized");
1021 return;
1022 }
1023
1024 if (nextplayer == thisplayer) {
1025 jniThrowException(env, "java/lang/IllegalArgumentException", "Next player can't be self");
1026 return;
1027 }
1028 // tie the two players together
1029 process_media_player_call(
1030 env, thiz, thisplayer->setNextMediaPlayer(nextplayer),
1031 "java/lang/IllegalArgumentException",
1032 "setNextMediaPlayer failed." );
1033 ;
1034 }
1035
1036 // ----------------------------------------------------------------------------
1037
1038 static const JNINativeMethod gMethods[] = {
1039 {
1040 "nativeSetDataSource",
1041 "(Landroid/os/IBinder;Ljava/lang/String;[Ljava/lang/String;"
1042 "[Ljava/lang/String;)V",
1043 (void *)android_media_MediaPlayer_setDataSourceAndHeaders
1044 },
1045
1046 {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
1047 {"_setDataSource", "(Landroid/media/MediaDataSource;)V",(void *)android_media_MediaPlayer_setDataSourceCallback },
1048 {"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface},
1049 {"_prepare", "()V", (void *)android_media_MediaPlayer_prepare},
1050 {"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync},
1051 {"_start", "()V", (void *)android_media_MediaPlayer_start},
1052 {"_stop", "()V", (void *)android_media_MediaPlayer_stop},
1053 {"getVideoWidth", "()I", (void *)android_media_MediaPlayer_getVideoWidth},
1054 {"getVideoHeight", "()I", (void *)android_media_MediaPlayer_getVideoHeight},
1055 {"setPlaybackParams", "(Landroid/media/PlaybackParams;)V", (void *)android_media_MediaPlayer_setPlaybackParams},
1056 {"getPlaybackParams", "()Landroid/media/PlaybackParams;", (void *)android_media_MediaPlayer_getPlaybackParams},
1057 {"setSyncParams", "(Landroid/media/SyncParams;)V", (void *)android_media_MediaPlayer_setSyncParams},
1058 {"getSyncParams", "()Landroid/media/SyncParams;", (void *)android_media_MediaPlayer_getSyncParams},
1059 {"seekTo", "(I)V", (void *)android_media_MediaPlayer_seekTo},
1060 {"_pause", "()V", (void *)android_media_MediaPlayer_pause},
1061 {"isPlaying", "()Z", (void *)android_media_MediaPlayer_isPlaying},
1062 {"getCurrentPosition", "()I", (void *)android_media_MediaPlayer_getCurrentPosition},
1063 {"getDuration", "()I", (void *)android_media_MediaPlayer_getDuration},
1064 {"_release", "()V", (void *)android_media_MediaPlayer_release},
1065 {"_reset", "()V", (void *)android_media_MediaPlayer_reset},
1066 {"_setAudioStreamType", "(I)V", (void *)android_media_MediaPlayer_setAudioStreamType},
1067 {"_getAudioStreamType", "()I", (void *)android_media_MediaPlayer_getAudioStreamType},
1068 {"setParameter", "(ILandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_setParameter},
1069 {"setLooping", "(Z)V", (void *)android_media_MediaPlayer_setLooping},
1070 {"isLooping", "()Z", (void *)android_media_MediaPlayer_isLooping},
1071 {"_setVolume", "(FF)V", (void *)android_media_MediaPlayer_setVolume},
1072 {"native_invoke", "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
1073 {"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter},
1074 {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata},
1075 {"native_init", "()V", (void *)android_media_MediaPlayer_native_init},
1076 {"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup},
1077 {"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
1078 {"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id},
1079 {"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id},
1080 {"_setAuxEffectSendLevel", "(F)V", (void *)android_media_MediaPlayer_setAuxEffectSendLevel},
1081 {"attachAuxEffect", "(I)V", (void *)android_media_MediaPlayer_attachAuxEffect},
1082 {"native_pullBatteryData", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_pullBatteryData},
1083 {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I", (void *)android_media_MediaPlayer_setRetransmitEndpoint},
1084 {"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer},
1085 };
1086
1087 // This function only registers the native methods
register_android_media_MediaPlayer(JNIEnv * env)1088 static int register_android_media_MediaPlayer(JNIEnv *env)
1089 {
1090 return AndroidRuntime::registerNativeMethods(env,
1091 "android/media/MediaPlayer", gMethods, NELEM(gMethods));
1092 }
1093 extern int register_android_media_ExifInterface(JNIEnv *env);
1094 extern int register_android_media_ImageReader(JNIEnv *env);
1095 extern int register_android_media_ImageWriter(JNIEnv *env);
1096 extern int register_android_media_Crypto(JNIEnv *env);
1097 extern int register_android_media_Drm(JNIEnv *env);
1098 extern int register_android_media_MediaCodec(JNIEnv *env);
1099 extern int register_android_media_MediaExtractor(JNIEnv *env);
1100 extern int register_android_media_MediaCodecList(JNIEnv *env);
1101 extern int register_android_media_MediaHTTPConnection(JNIEnv *env);
1102 extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
1103 extern int register_android_media_MediaMuxer(JNIEnv *env);
1104 extern int register_android_media_MediaRecorder(JNIEnv *env);
1105 extern int register_android_media_MediaScanner(JNIEnv *env);
1106 extern int register_android_media_MediaSync(JNIEnv *env);
1107 extern int register_android_media_ResampleInputStream(JNIEnv *env);
1108 extern int register_android_media_MediaProfiles(JNIEnv *env);
1109 extern int register_android_media_AmrInputStream(JNIEnv *env);
1110 extern int register_android_mtp_MtpDatabase(JNIEnv *env);
1111 extern int register_android_mtp_MtpDevice(JNIEnv *env);
1112 extern int register_android_mtp_MtpServer(JNIEnv *env);
1113
JNI_OnLoad(JavaVM * vm,void *)1114 jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
1115 {
1116 JNIEnv* env = NULL;
1117 jint result = -1;
1118
1119 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1120 ALOGE("ERROR: GetEnv failed\n");
1121 goto bail;
1122 }
1123 assert(env != NULL);
1124
1125 if (register_android_media_ImageWriter(env) != JNI_OK) {
1126 ALOGE("ERROR: ImageWriter native registration failed");
1127 goto bail;
1128 }
1129
1130 if (register_android_media_ImageReader(env) < 0) {
1131 ALOGE("ERROR: ImageReader native registration failed");
1132 goto bail;
1133 }
1134
1135 if (register_android_media_MediaPlayer(env) < 0) {
1136 ALOGE("ERROR: MediaPlayer native registration failed\n");
1137 goto bail;
1138 }
1139
1140 if (register_android_media_MediaRecorder(env) < 0) {
1141 ALOGE("ERROR: MediaRecorder native registration failed\n");
1142 goto bail;
1143 }
1144
1145 if (register_android_media_MediaScanner(env) < 0) {
1146 ALOGE("ERROR: MediaScanner native registration failed\n");
1147 goto bail;
1148 }
1149
1150 if (register_android_media_MediaMetadataRetriever(env) < 0) {
1151 ALOGE("ERROR: MediaMetadataRetriever native registration failed\n");
1152 goto bail;
1153 }
1154
1155 if (register_android_media_AmrInputStream(env) < 0) {
1156 ALOGE("ERROR: AmrInputStream native registration failed\n");
1157 goto bail;
1158 }
1159
1160 if (register_android_media_ResampleInputStream(env) < 0) {
1161 ALOGE("ERROR: ResampleInputStream native registration failed\n");
1162 goto bail;
1163 }
1164
1165 if (register_android_media_MediaProfiles(env) < 0) {
1166 ALOGE("ERROR: MediaProfiles native registration failed");
1167 goto bail;
1168 }
1169
1170 if (register_android_mtp_MtpDatabase(env) < 0) {
1171 ALOGE("ERROR: MtpDatabase native registration failed");
1172 goto bail;
1173 }
1174
1175 if (register_android_mtp_MtpDevice(env) < 0) {
1176 ALOGE("ERROR: MtpDevice native registration failed");
1177 goto bail;
1178 }
1179
1180 if (register_android_mtp_MtpServer(env) < 0) {
1181 ALOGE("ERROR: MtpServer native registration failed");
1182 goto bail;
1183 }
1184
1185 if (register_android_media_MediaCodec(env) < 0) {
1186 ALOGE("ERROR: MediaCodec native registration failed");
1187 goto bail;
1188 }
1189
1190 if (register_android_media_MediaSync(env) < 0) {
1191 ALOGE("ERROR: MediaSync native registration failed");
1192 goto bail;
1193 }
1194
1195 if (register_android_media_MediaExtractor(env) < 0) {
1196 ALOGE("ERROR: MediaCodec native registration failed");
1197 goto bail;
1198 }
1199
1200 if (register_android_media_MediaMuxer(env) < 0) {
1201 ALOGE("ERROR: MediaMuxer native registration failed");
1202 goto bail;
1203 }
1204
1205 if (register_android_media_MediaCodecList(env) < 0) {
1206 ALOGE("ERROR: MediaCodec native registration failed");
1207 goto bail;
1208 }
1209
1210 if (register_android_media_Crypto(env) < 0) {
1211 ALOGE("ERROR: MediaCodec native registration failed");
1212 goto bail;
1213 }
1214
1215 if (register_android_media_Drm(env) < 0) {
1216 ALOGE("ERROR: MediaDrm native registration failed");
1217 goto bail;
1218 }
1219
1220 if (register_android_media_MediaHTTPConnection(env) < 0) {
1221 ALOGE("ERROR: MediaHTTPConnection native registration failed");
1222 goto bail;
1223 }
1224
1225 if (register_android_media_ExifInterface(env) < 0) {
1226 ALOGE("ERROR: ExifInterface native registration failed");
1227 goto bail;
1228 }
1229
1230 /* success -- return valid version number */
1231 result = JNI_VERSION_1_4;
1232
1233 bail:
1234 return result;
1235 }
1236
1237 // KTHXBYE
1238