blob: a94230014437acfd3bb86f3396c7ea1cdae7a1cf [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>
Lajos Molnarb3d5fd22015-04-22 13:14:34 -070023#include <media/AudioResamplerPublic.h>
Andreas Huberd2506a52014-01-29 10:32:46 -080024#include <media/IMediaHTTPService.h>
Nicolas Catania20cb94e2009-05-12 23:25:55 -070025#include <media/MediaPlayerInterface.h>
Ray Essick81fbc5b2019-12-07 06:24:59 -080026#include <media/MediaMetricsItem.h>
Dongwon Kangefada5692017-10-09 11:46:39 -070027#include <media/stagefright/foundation/ByteUtils.h> // for FOURCC definition
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028#include <stdio.h>
29#include <assert.h>
30#include <limits.h>
31#include <unistd.h>
32#include <fcntl.h>
33#include <utils/threads.h>
34#include "jni.h"
Orion Hodson329c6122020-06-02 13:22:06 +010035#include <nativehelper/JNIPlatformHelp.h>
Colin Cross082aec62020-08-27 04:12:26 +000036#include <nativehelper/ScopedUtfChars.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037#include "android_runtime/AndroidRuntime.h"
Ted Bonkenburg1ee60112011-07-26 09:51:18 -070038#include "android_runtime/android_view_Surface.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070039#include "android_runtime/Log.h"
The Android Open Source Project4df24232009-03-05 14:34:35 -080040#include "utils/Errors.h" // for status_t
Andreas Huber25643002010-01-28 11:19:57 -080041#include "utils/KeyedVector.h"
42#include "utils/String8.h"
Chris Watkins4eaa2932015-03-20 10:31:42 -070043#include "android_media_MediaDataSource.h"
Ray Essick0e0fee12017-01-25 18:01:56 -080044#include "android_media_MediaMetricsJNI.h"
Wei Jia2d61e2b2015-05-08 15:23:28 -070045#include "android_media_PlaybackParams.h"
46#include "android_media_SyncParams.h"
Andy Hung035d4ec2017-01-24 13:45:02 -080047#include "android_media_VolumeShaper.h"
Jooyung Hancb1e8962019-02-21 14:18:11 +090048#include "android_media_Streams.h"
James Dong79f407c2011-05-05 12:50:04 -070049
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080050#include "android_os_Parcel.h"
Nicolas Catania20cb94e2009-05-12 23:25:55 -070051#include "android_util_Binder.h"
52#include <binder/Parcel.h>
Andy McFaddend47f7d82012-12-18 09:48:38 -080053#include <gui/IGraphicBufferProducer.h>
Mathias Agopian8335f1c2012-02-25 18:48:35 -080054#include <gui/Surface.h>
Gloria Wangd211f412011-02-19 18:37:57 -080055#include <binder/IPCThreadState.h>
56#include <binder/IServiceManager.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057
Andreas Huberd2506a52014-01-29 10:32:46 -080058#include "android_util_Binder.h"
Hassan Shojania0b52e952017-01-23 09:06:31 -080059
60// Modular DRM begin
Hassan Shojania0b52e952017-01-23 09:06:31 -080061#define FIND_CLASS(var, className) \
62var = env->FindClass(className); \
63LOG_FATAL_IF(! (var), "Unable to find class " className);
64
Hassan Shojania0b52e952017-01-23 09:06:31 -080065#define GET_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
66var = env->GetMethodID(clazz, fieldName, fieldDescriptor); \
67LOG_FATAL_IF(! (var), "Unable to find method " fieldName);
68
Hassan Shojania0b52e952017-01-23 09:06:31 -080069struct StateExceptionFields {
70 jmethodID init;
71 jclass classId;
72};
73
Hassan Shojania06b25fb2017-02-06 21:09:42 -080074static StateExceptionFields gStateExceptionFields;
Hassan Shojania0b52e952017-01-23 09:06:31 -080075// Modular DRM end
76
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077// ----------------------------------------------------------------------------
78
79using namespace android;
80
Ivan Lozano330d8762017-08-08 12:51:06 -070081using media::VolumeShaper;
82
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083// ----------------------------------------------------------------------------
84
85struct fields_t {
86 jfieldID context;
Ted Bonkenburg1ee60112011-07-26 09:51:18 -070087 jfieldID surface_texture;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
89 jmethodID post_event;
Andreas Huberd5f9fa52013-05-28 14:39:39 -070090
91 jmethodID proxyConfigGetHost;
92 jmethodID proxyConfigGetPort;
93 jmethodID proxyConfigGetExclusionList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094};
95static fields_t fields;
96
Wei Jia2d61e2b2015-05-08 15:23:28 -070097static PlaybackParams::fields_t gPlaybackParamsFields;
98static SyncParams::fields_t gSyncParamsFields;
Andy Hung035d4ec2017-01-24 13:45:02 -080099static VolumeShaperHelper::fields_t gVolumeShaperFields;
Lajos Molnarb3d5fd22015-04-22 13:14:34 -0700100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101static Mutex sLock;
102
103// ----------------------------------------------------------------------------
104// ref-counted object for callbacks
105class JNIMediaPlayerListener: public MediaPlayerListener
106{
107public:
108 JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
109 ~JNIMediaPlayerListener();
Gloria Wang162ee492011-04-11 17:23:27 -0700110 virtual void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111private:
112 JNIMediaPlayerListener();
113 jclass mClass; // Reference to MediaPlayer class
114 jobject mObject; // Weak ref to MediaPlayer Java object to call on
115};
116
117JNIMediaPlayerListener::JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
118{
119
120 // Hold onto the MediaPlayer class for use in calling the static method
121 // that posts events to the application thread.
122 jclass clazz = env->GetObjectClass(thiz);
123 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000124 ALOGE("Can't find android/media/MediaPlayer");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 jniThrowException(env, "java/lang/Exception", NULL);
126 return;
127 }
128 mClass = (jclass)env->NewGlobalRef(clazz);
129
130 // We use a weak reference so the MediaPlayer object can be garbage collected.
131 // The reference is only used as a proxy for callbacks.
132 mObject = env->NewGlobalRef(weak_thiz);
133}
134
135JNIMediaPlayerListener::~JNIMediaPlayerListener()
136{
137 // remove global references
138 JNIEnv *env = AndroidRuntime::getJNIEnv();
139 env->DeleteGlobalRef(mObject);
140 env->DeleteGlobalRef(mClass);
141}
142
Gloria Wang162ee492011-04-11 17:23:27 -0700143void JNIMediaPlayerListener::notify(int msg, int ext1, int ext2, const Parcel *obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144{
145 JNIEnv *env = AndroidRuntime::getJNIEnv();
Gloria Wang162ee492011-04-11 17:23:27 -0700146 if (obj && obj->dataSize() > 0) {
Insun Kang333c0992012-07-10 12:47:03 +0900147 jobject jParcel = createJavaParcelObject(env);
148 if (jParcel != NULL) {
149 Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
Insun Kang89020972012-05-01 14:13:19 +0900150 nativeParcel->setData(obj->data(), obj->dataSize());
Gloria Wang162ee492011-04-11 17:23:27 -0700151 env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
Insun Kang333c0992012-07-10 12:47:03 +0900152 msg, ext1, ext2, jParcel);
Elliott Hughes99f75212013-11-13 15:10:40 -0800153 env->DeleteLocalRef(jParcel);
Gloria Wang162ee492011-04-11 17:23:27 -0700154 }
155 } else {
156 env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
157 msg, ext1, ext2, NULL);
158 }
Insun Kang89020972012-05-01 14:13:19 +0900159 if (env->ExceptionCheck()) {
160 ALOGW("An exception occurred while notifying an event.");
161 LOGW_EX(env);
162 env->ExceptionClear();
163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164}
165
166// ----------------------------------------------------------------------------
167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168static sp<MediaPlayer> getMediaPlayer(JNIEnv* env, jobject thiz)
169{
170 Mutex::Autolock l(sLock);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000171 MediaPlayer* const p = (MediaPlayer*)env->GetLongField(thiz, fields.context);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 return sp<MediaPlayer>(p);
173}
174
175static sp<MediaPlayer> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaPlayer>& player)
176{
177 Mutex::Autolock l(sLock);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000178 sp<MediaPlayer> old = (MediaPlayer*)env->GetLongField(thiz, fields.context);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 if (player.get()) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800180 player->incStrong((void*)setMediaPlayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 }
182 if (old != 0) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800183 old->decStrong((void*)setMediaPlayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000185 env->SetLongField(thiz, fields.context, (jlong)player.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 return old;
187}
188
Nicolas Catania32f82772009-06-11 16:33:49 -0700189// If exception is NULL and opStatus is not OK, this method sends an error
190// event to the client application; otherwise, if exception is not NULL and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191// opStatus is not OK, this method throws the given exception to the client
192// application.
193static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStatus, const char* exception, const char *message)
194{
195 if (exception == NULL) { // Don't throw exception. Instead, send an event.
196 if (opStatus != (status_t) OK) {
197 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
198 if (mp != 0) mp->notify(MEDIA_ERROR, opStatus, 0);
199 }
200 } else { // Throw exception!
201 if ( opStatus == (status_t) INVALID_OPERATION ) {
202 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700203 } else if ( opStatus == (status_t) BAD_VALUE ) {
204 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
Dave Burkefc301b02011-08-30 14:39:17 +0100205 } else if ( opStatus == (status_t) PERMISSION_DENIED ) {
206 jniThrowException(env, "java/lang/SecurityException", NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 } else if ( opStatus != (status_t) OK ) {
208 if (strlen(message) > 230) {
209 // if the message is too long, don't bother displaying the status code
210 jniThrowException( env, exception, message);
211 } else {
212 char msg[256];
213 // append the status code to the message
214 sprintf(msg, "%s: status=0x%X", message, opStatus);
215 jniThrowException( env, exception, msg);
216 }
217 }
218 }
219}
220
221static void
Andreas Huber25643002010-01-28 11:19:57 -0800222android_media_MediaPlayer_setDataSourceAndHeaders(
Andreas Huberd2506a52014-01-29 10:32:46 -0800223 JNIEnv *env, jobject thiz, jobject httpServiceBinderObj, jstring path,
James Dong17524dc2011-05-04 13:41:58 -0700224 jobjectArray keys, jobjectArray values) {
225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
227 if (mp == NULL ) {
228 jniThrowException(env, "java/lang/IllegalStateException", NULL);
229 return;
230 }
231
232 if (path == NULL) {
233 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
234 return;
235 }
236
James Dongc371a022011-04-06 12:16:07 -0700237 const char *tmp = env->GetStringUTFChars(path, NULL);
238 if (tmp == NULL) { // Out of memory
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 return;
240 }
Steve Block71f2cf12011-10-20 11:56:00 +0100241 ALOGV("setDataSource: path %s", tmp);
Andreas Huber25643002010-01-28 11:19:57 -0800242
James Dongc371a022011-04-06 12:16:07 -0700243 String8 pathStr(tmp);
244 env->ReleaseStringUTFChars(path, tmp);
245 tmp = NULL;
246
James Dong17524dc2011-05-04 13:41:58 -0700247 // We build a KeyedVector out of the key and val arrays
Andreas Huber25643002010-01-28 11:19:57 -0800248 KeyedVector<String8, String8> headersVector;
James Dong79f407c2011-05-05 12:50:04 -0700249 if (!ConvertKeyValueArraysToKeyedVector(
250 env, keys, values, &headersVector)) {
251 return;
Andreas Huber25643002010-01-28 11:19:57 -0800252 }
253
Andreas Huberd2506a52014-01-29 10:32:46 -0800254 sp<IMediaHTTPService> httpService;
255 if (httpServiceBinderObj != NULL) {
256 sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
257 httpService = interface_cast<IMediaHTTPService>(binder);
258 }
259
Andreas Huber25643002010-01-28 11:19:57 -0800260 status_t opStatus =
261 mp->setDataSource(
Andreas Huberd2506a52014-01-29 10:32:46 -0800262 httpService,
Tomasz Wasilczyk835dfe52023-08-17 16:27:22 +0000263 pathStr.c_str(),
James Dong79f407c2011-05-05 12:50:04 -0700264 headersVector.size() > 0? &headersVector : NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265
Andreas Huber25643002010-01-28 11:19:57 -0800266 process_media_player_call(
267 env, thiz, opStatus, "java/io/IOException",
268 "setDataSource failed." );
269}
270
271static void
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
273{
274 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
275 if (mp == NULL ) {
276 jniThrowException(env, "java/lang/IllegalStateException", NULL);
277 return;
278 }
279
280 if (fileDescriptor == NULL) {
281 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
282 return;
283 }
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700284 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
Steve Block71f2cf12011-10-20 11:56:00 +0100285 ALOGV("setDataSourceFD: fd %d", fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
287}
288
Chris Watkins4eaa2932015-03-20 10:31:42 -0700289static void
290android_media_MediaPlayer_setDataSourceCallback(JNIEnv *env, jobject thiz, jobject dataSource)
291{
292 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
293 if (mp == NULL ) {
294 jniThrowException(env, "java/lang/IllegalStateException", NULL);
295 return;
296 }
297
298 if (dataSource == NULL) {
299 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
300 return;
301 }
302 sp<IDataSource> callbackDataSource = new JMediaDataSource(env, dataSource);
303 process_media_player_call(env, thiz, mp->setDataSource(callbackDataSource), "java/lang/RuntimeException", "setDataSourceCallback failed." );
304}
305
Andy McFaddend47f7d82012-12-18 09:48:38 -0800306static sp<IGraphicBufferProducer>
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700307getVideoSurfaceTexture(JNIEnv* env, jobject thiz) {
Ashok Bhat075e9a12014-01-06 13:45:09 +0000308 IGraphicBufferProducer * const p = (IGraphicBufferProducer*)env->GetLongField(thiz, fields.surface_texture);
Andy McFaddend47f7d82012-12-18 09:48:38 -0800309 return sp<IGraphicBufferProducer>(p);
Dave Sparks8b0b1742009-05-29 09:01:20 -0700310}
311
312static void
Gloria Wangd59310d2011-09-14 13:59:45 -0700313decVideoSurfaceRef(JNIEnv *env, jobject thiz)
314{
Gloria Wange828beb2011-09-15 15:28:43 -0700315 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
316 if (mp == NULL) {
317 return;
318 }
319
Andy McFaddend47f7d82012-12-18 09:48:38 -0800320 sp<IGraphicBufferProducer> old_st = getVideoSurfaceTexture(env, thiz);
Gloria Wangd59310d2011-09-14 13:59:45 -0700321 if (old_st != NULL) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800322 old_st->decStrong((void*)decVideoSurfaceRef);
Gloria Wangd59310d2011-09-14 13:59:45 -0700323 }
324}
325
326static void
James Dong43ef9132011-08-12 11:33:27 -0700327setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface, jboolean mediaPlayerMustBeAlive)
Dave Sparks8b0b1742009-05-29 09:01:20 -0700328{
329 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
James Dong43ef9132011-08-12 11:33:27 -0700330 if (mp == NULL) {
331 if (mediaPlayerMustBeAlive) {
332 jniThrowException(env, "java/lang/IllegalStateException", NULL);
333 }
Dave Sparks8b0b1742009-05-29 09:01:20 -0700334 return;
335 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700336
Gloria Wangd59310d2011-09-14 13:59:45 -0700337 decVideoSurfaceRef(env, thiz);
338
Andy McFaddend47f7d82012-12-18 09:48:38 -0800339 sp<IGraphicBufferProducer> new_st;
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700340 if (jsurface) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700341 sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
Jamie Gennisf76afc82011-10-14 19:06:55 -0700342 if (surface != NULL) {
Mathias Agopian52800612013-02-14 17:11:20 -0800343 new_st = surface->getIGraphicBufferProducer();
James Dong097922b9c2012-10-04 09:16:40 -0700344 if (new_st == NULL) {
345 jniThrowException(env, "java/lang/IllegalArgumentException",
346 "The surface does not have a binding SurfaceTexture!");
347 return;
348 }
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800349 new_st->incStrong((void*)decVideoSurfaceRef);
Jamie Gennisf76afc82011-10-14 19:06:55 -0700350 } else {
351 jniThrowException(env, "java/lang/IllegalArgumentException",
352 "The surface has been released");
353 return;
354 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700355 }
Gloria Wangd59310d2011-09-14 13:59:45 -0700356
Ashok Bhat075e9a12014-01-06 13:45:09 +0000357 env->SetLongField(thiz, fields.surface_texture, (jlong)new_st.get());
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700358
359 // This will fail if the media player has not been initialized yet. This
360 // can be the case if setDisplay() on MediaPlayer.java has been called
361 // before setDataSource(). The redundant call to setVideoSurfaceTexture()
362 // in prepare/prepareAsync covers for this case.
363 mp->setVideoSurfaceTexture(new_st);
Dave Sparks8b0b1742009-05-29 09:01:20 -0700364}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365
366static void
James Dong43ef9132011-08-12 11:33:27 -0700367android_media_MediaPlayer_setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface)
368{
369 setVideoSurface(env, thiz, jsurface, true /* mediaPlayerMustBeAlive */);
370}
371
Vlad Popa66824a32022-08-12 16:05:05 +0200372static jint
373android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz, jobject piidParcel)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374{
375 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
Vlad Popa66824a32022-08-12 16:05:05 +0200376 if (mp == nullptr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Vlad Popa66824a32022-08-12 16:05:05 +0200378 return UNKNOWN_ERROR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700380
381 // Handle the case where the display surface was set before the mp was
382 // initialized. We try again to make it stick.
Andy McFaddend47f7d82012-12-18 09:48:38 -0800383 sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700384 mp->setVideoSurfaceTexture(st);
385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
Vlad Popa66824a32022-08-12 16:05:05 +0200387
Vlad Popa33ae2f62023-04-25 17:44:36 +0200388 if (env->ExceptionCheck()) {
389 return UNKNOWN_ERROR;
390 }
391
Vlad Popa66824a32022-08-12 16:05:05 +0200392 // update the piid
393 Parcel *request = parcelForJavaObject(env, piidParcel);
394 auto reply = std::make_unique<Parcel>();
395 return static_cast<jint>(mp->invoke(*request, reply.get()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396}
397
Vlad Popa66824a32022-08-12 16:05:05 +0200398static jint
399android_media_MediaPlayer_prepareAsync(JNIEnv *env, jobject thiz, jobject piidParcel)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400{
401 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
Vlad Popa66824a32022-08-12 16:05:05 +0200402 if (mp == nullptr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Vlad Popa66824a32022-08-12 16:05:05 +0200404 return UNKNOWN_ERROR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 }
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700406
407 // Handle the case where the display surface was set before the mp was
408 // initialized. We try again to make it stick.
Andy McFaddend47f7d82012-12-18 09:48:38 -0800409 sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700410 mp->setVideoSurfaceTexture(st);
411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
Vlad Popa66824a32022-08-12 16:05:05 +0200413
Vlad Popa33ae2f62023-04-25 17:44:36 +0200414 if (env->ExceptionCheck()) {
415 return UNKNOWN_ERROR;
416 }
417
Vlad Popa66824a32022-08-12 16:05:05 +0200418 // update the piid
419 Parcel *request = parcelForJavaObject(env, piidParcel);
420 auto reply = std::make_unique<Parcel>();
421 return static_cast<jint>(mp->invoke(*request, reply.get()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422}
423
424static void
425android_media_MediaPlayer_start(JNIEnv *env, jobject thiz)
426{
Steve Block71f2cf12011-10-20 11:56:00 +0100427 ALOGV("start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
429 if (mp == NULL ) {
430 jniThrowException(env, "java/lang/IllegalStateException", NULL);
431 return;
432 }
433 process_media_player_call( env, thiz, mp->start(), NULL, NULL );
434}
435
436static void
437android_media_MediaPlayer_stop(JNIEnv *env, jobject thiz)
438{
Steve Block71f2cf12011-10-20 11:56:00 +0100439 ALOGV("stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
441 if (mp == NULL ) {
442 jniThrowException(env, "java/lang/IllegalStateException", NULL);
443 return;
444 }
Nicolas Catania32f82772009-06-11 16:33:49 -0700445 process_media_player_call( env, thiz, mp->stop(), NULL, NULL );
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446}
447
448static void
449android_media_MediaPlayer_pause(JNIEnv *env, jobject thiz)
450{
Steve Block71f2cf12011-10-20 11:56:00 +0100451 ALOGV("pause");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
453 if (mp == NULL ) {
454 jniThrowException(env, "java/lang/IllegalStateException", NULL);
455 return;
456 }
457 process_media_player_call( env, thiz, mp->pause(), NULL, NULL );
458}
459
460static jboolean
461android_media_MediaPlayer_isPlaying(JNIEnv *env, jobject thiz)
462{
463 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
464 if (mp == NULL ) {
465 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000466 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800468 const jboolean is_playing = mp->isPlaying();
469
Steve Block71f2cf12011-10-20 11:56:00 +0100470 ALOGV("isPlaying: %d", is_playing);
The Android Open Source Project4df24232009-03-05 14:34:35 -0800471 return is_playing;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472}
473
474static void
Wei Jia2d61e2b2015-05-08 15:23:28 -0700475android_media_MediaPlayer_setPlaybackParams(JNIEnv *env, jobject thiz, jobject params)
Wei Jiad93fcf42015-02-09 16:05:53 -0800476{
477 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
478 if (mp == NULL) {
479 jniThrowException(env, "java/lang/IllegalStateException", NULL);
480 return;
481 }
Lajos Molnarb3d5fd22015-04-22 13:14:34 -0700482
Wei Jia2d61e2b2015-05-08 15:23:28 -0700483 PlaybackParams pbp;
484 pbp.fillFromJobject(env, gPlaybackParamsFields, params);
485 ALOGV("setPlaybackParams: %d:%f %d:%f %d:%u %d:%u",
486 pbp.speedSet, pbp.audioRate.mSpeed,
487 pbp.pitchSet, pbp.audioRate.mPitch,
488 pbp.audioFallbackModeSet, pbp.audioRate.mFallbackMode,
489 pbp.audioStretchModeSet, pbp.audioRate.mStretchMode);
Lajos Molnarb3d5fd22015-04-22 13:14:34 -0700490
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700491 AudioPlaybackRate rate;
492 status_t err = mp->getPlaybackSettings(&rate);
493 if (err == OK) {
494 bool updatedRate = false;
Wei Jia2d61e2b2015-05-08 15:23:28 -0700495 if (pbp.speedSet) {
496 rate.mSpeed = pbp.audioRate.mSpeed;
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700497 updatedRate = true;
498 }
Wei Jia2d61e2b2015-05-08 15:23:28 -0700499 if (pbp.pitchSet) {
500 rate.mPitch = pbp.audioRate.mPitch;
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700501 updatedRate = true;
502 }
Wei Jia2d61e2b2015-05-08 15:23:28 -0700503 if (pbp.audioFallbackModeSet) {
504 rate.mFallbackMode = pbp.audioRate.mFallbackMode;
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700505 updatedRate = true;
506 }
Wei Jia2d61e2b2015-05-08 15:23:28 -0700507 if (pbp.audioStretchModeSet) {
508 rate.mStretchMode = pbp.audioRate.mStretchMode;
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700509 updatedRate = true;
510 }
511 if (updatedRate) {
512 err = mp->setPlaybackSettings(rate);
513 }
514 }
515 process_media_player_call(
516 env, thiz, err,
517 "java/lang/IllegalStateException", "unexpected error");
Lajos Molnarb3d5fd22015-04-22 13:14:34 -0700518}
519
520static jobject
Wei Jia2d61e2b2015-05-08 15:23:28 -0700521android_media_MediaPlayer_getPlaybackParams(JNIEnv *env, jobject thiz)
Lajos Molnarb3d5fd22015-04-22 13:14:34 -0700522{
523 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
524 if (mp == NULL) {
525 jniThrowException(env, "java/lang/IllegalStateException", NULL);
526 return NULL;
527 }
528
Wei Jia2d61e2b2015-05-08 15:23:28 -0700529 PlaybackParams pbp;
530 AudioPlaybackRate &audioRate = pbp.audioRate;
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700531 process_media_player_call(
532 env, thiz, mp->getPlaybackSettings(&audioRate),
533 "java/lang/IllegalStateException", "unexpected error");
Dongwon Kang44801272018-05-23 17:38:35 -0700534 if (env->ExceptionCheck()) {
535 return nullptr;
536 }
Lajos Molnarb3d5fd22015-04-22 13:14:34 -0700537 ALOGV("getPlaybackSettings: %f %f %d %d",
538 audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode);
539
Wei Jia2d61e2b2015-05-08 15:23:28 -0700540 pbp.speedSet = true;
541 pbp.pitchSet = true;
542 pbp.audioFallbackModeSet = true;
543 pbp.audioStretchModeSet = true;
Lajos Molnarb3d5fd22015-04-22 13:14:34 -0700544
Wei Jia2d61e2b2015-05-08 15:23:28 -0700545 return pbp.asJobject(env, gPlaybackParamsFields);
Wei Jiad93fcf42015-02-09 16:05:53 -0800546}
547
548static void
Wei Jia2d61e2b2015-05-08 15:23:28 -0700549android_media_MediaPlayer_setSyncParams(JNIEnv *env, jobject thiz, jobject params)
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700550{
551 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
552 if (mp == NULL) {
553 jniThrowException(env, "java/lang/IllegalStateException", NULL);
554 return;
555 }
556
Wei Jia2d61e2b2015-05-08 15:23:28 -0700557 SyncParams scp;
558 scp.fillFromJobject(env, gSyncParamsFields, params);
559 ALOGV("setSyncParams: %d:%d %d:%d %d:%f %d:%f",
560 scp.syncSourceSet, scp.sync.mSource,
561 scp.audioAdjustModeSet, scp.sync.mAudioAdjustMode,
562 scp.toleranceSet, scp.sync.mTolerance,
563 scp.frameRateSet, scp.frameRate);
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700564
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700565 AVSyncSettings avsync;
566 float videoFrameRate;
567 status_t err = mp->getSyncSettings(&avsync, &videoFrameRate);
568 if (err == OK) {
Wei Jia2d61e2b2015-05-08 15:23:28 -0700569 bool updatedSync = scp.frameRateSet;
570 if (scp.syncSourceSet) {
571 avsync.mSource = scp.sync.mSource;
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700572 updatedSync = true;
573 }
Wei Jia2d61e2b2015-05-08 15:23:28 -0700574 if (scp.audioAdjustModeSet) {
575 avsync.mAudioAdjustMode = scp.sync.mAudioAdjustMode;
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700576 updatedSync = true;
577 }
Wei Jia2d61e2b2015-05-08 15:23:28 -0700578 if (scp.toleranceSet) {
579 avsync.mTolerance = scp.sync.mTolerance;
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700580 updatedSync = true;
581 }
582 if (updatedSync) {
Wei Jia2d61e2b2015-05-08 15:23:28 -0700583 err = mp->setSyncSettings(avsync, scp.frameRateSet ? scp.frameRate : -1.f);
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700584 }
585 }
586 process_media_player_call(
587 env, thiz, err,
588 "java/lang/IllegalStateException", "unexpected error");
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700589}
590
591static jobject
Wei Jia2d61e2b2015-05-08 15:23:28 -0700592android_media_MediaPlayer_getSyncParams(JNIEnv *env, jobject thiz)
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700593{
594 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
595 if (mp == NULL) {
596 jniThrowException(env, "java/lang/IllegalStateException", NULL);
597 return NULL;
598 }
599
Wei Jia2d61e2b2015-05-08 15:23:28 -0700600 SyncParams scp;
601 scp.frameRate = -1.f;
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700602 process_media_player_call(
Wei Jia2d61e2b2015-05-08 15:23:28 -0700603 env, thiz, mp->getSyncSettings(&scp.sync, &scp.frameRate),
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700604 "java/lang/IllegalStateException", "unexpected error");
Dongwon Kang44801272018-05-23 17:38:35 -0700605 if (env->ExceptionCheck()) {
606 return nullptr;
607 }
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700608
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700609 ALOGV("getSyncSettings: %d %d %f %f",
Wei Jia2d61e2b2015-05-08 15:23:28 -0700610 scp.sync.mSource, scp.sync.mAudioAdjustMode, scp.sync.mTolerance, scp.frameRate);
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700611
Alice Kuoc2c679d2020-07-30 16:14:48 +0000612 // check params
Wei Jia2d61e2b2015-05-08 15:23:28 -0700613 if (scp.sync.mSource >= AVSYNC_SOURCE_MAX
614 || scp.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX
615 || scp.sync.mTolerance < 0.f
616 || scp.sync.mTolerance >= AVSYNC_TOLERANCE_MAX) {
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700617 jniThrowException(env, "java/lang/IllegalStateException", NULL);
618 return NULL;
619 }
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700620
Wei Jia2d61e2b2015-05-08 15:23:28 -0700621 scp.syncSourceSet = true;
622 scp.audioAdjustModeSet = true;
623 scp.toleranceSet = true;
624 scp.frameRateSet = scp.frameRate >= 0.f;
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700625
Wei Jia2d61e2b2015-05-08 15:23:28 -0700626 return scp.asJobject(env, gSyncParamsFields);
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700627}
628
629static void
Wei Jiabebeaf92017-04-19 16:22:10 -0700630android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, jlong msec, jint mode)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631{
632 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
633 if (mp == NULL ) {
634 jniThrowException(env, "java/lang/IllegalStateException", NULL);
635 return;
636 }
Wei Jiabebeaf92017-04-19 16:22:10 -0700637 ALOGV("seekTo: %lld(msec), mode=%d", (long long)msec, mode);
638 process_media_player_call( env, thiz, mp->seekTo((int)msec, (MediaPlayerSeekMode)mode), NULL, NULL );
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639}
640
Wei Jiac02f09d2017-09-13 18:19:48 -0700641static void
642android_media_MediaPlayer_notifyAt(JNIEnv *env, jobject thiz, jlong mediaTimeUs)
643{
644 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
645 if (mp == NULL) {
646 jniThrowException(env, "java/lang/IllegalStateException", NULL);
647 return;
648 }
649 ALOGV("notifyAt: %lld", (long long)mediaTimeUs);
650 process_media_player_call( env, thiz, mp->notifyAt((int64_t)mediaTimeUs), NULL, NULL );
651}
652
Ashok Bhat075e9a12014-01-06 13:45:09 +0000653static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654android_media_MediaPlayer_getVideoWidth(JNIEnv *env, jobject thiz)
655{
656 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
657 if (mp == NULL ) {
658 jniThrowException(env, "java/lang/IllegalStateException", NULL);
659 return 0;
660 }
661 int w;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800662 if (0 != mp->getVideoWidth(&w)) {
Steve Block3762c312012-01-06 19:20:56 +0000663 ALOGE("getVideoWidth failed");
The Android Open Source Project4df24232009-03-05 14:34:35 -0800664 w = 0;
665 }
Steve Block71f2cf12011-10-20 11:56:00 +0100666 ALOGV("getVideoWidth: %d", w);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000667 return (jint) w;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668}
669
Ashok Bhat075e9a12014-01-06 13:45:09 +0000670static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671android_media_MediaPlayer_getVideoHeight(JNIEnv *env, jobject thiz)
672{
673 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
674 if (mp == NULL ) {
675 jniThrowException(env, "java/lang/IllegalStateException", NULL);
676 return 0;
677 }
678 int h;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800679 if (0 != mp->getVideoHeight(&h)) {
Steve Block3762c312012-01-06 19:20:56 +0000680 ALOGE("getVideoHeight failed");
The Android Open Source Project4df24232009-03-05 14:34:35 -0800681 h = 0;
682 }
Steve Block71f2cf12011-10-20 11:56:00 +0100683 ALOGV("getVideoHeight: %d", h);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000684 return (jint) h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685}
686
Ray Essick0e0fee12017-01-25 18:01:56 -0800687static jobject
Ray Essickf2d0e402017-03-09 10:17:51 -0800688android_media_MediaPlayer_native_getMetrics(JNIEnv *env, jobject thiz)
Ray Essick0e0fee12017-01-25 18:01:56 -0800689{
690 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
691 if (mp == NULL ) {
692 jniThrowException(env, "java/lang/IllegalStateException", NULL);
693 return 0;
694 }
695
696 Parcel p;
697 int key = FOURCC('m','t','r','X');
698 status_t status = mp->getParameter(key, &p);
699 if (status != OK) {
700 ALOGD("getMetrics() failed: %d", status);
701 return (jobject) NULL;
702 }
703
Ray Essick81fbc5b2019-12-07 06:24:59 -0800704 std::unique_ptr<mediametrics::Item> item(mediametrics::Item::create());
Ray Essick0e0fee12017-01-25 18:01:56 -0800705 item->readFromParcel(p);
Ray Essicke9b9c982019-01-28 20:34:42 -0800706 jobject mybundle = MediaMetricsJNI::writeMetricsToBundle(env, item.get(), NULL);
Ray Essick0e0fee12017-01-25 18:01:56 -0800707
708 return mybundle;
709}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710
Ashok Bhat075e9a12014-01-06 13:45:09 +0000711static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712android_media_MediaPlayer_getCurrentPosition(JNIEnv *env, jobject thiz)
713{
714 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
715 if (mp == NULL ) {
716 jniThrowException(env, "java/lang/IllegalStateException", NULL);
717 return 0;
718 }
719 int msec;
720 process_media_player_call( env, thiz, mp->getCurrentPosition(&msec), NULL, NULL );
Steve Block71f2cf12011-10-20 11:56:00 +0100721 ALOGV("getCurrentPosition: %d (msec)", msec);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000722 return (jint) msec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723}
724
Ashok Bhat075e9a12014-01-06 13:45:09 +0000725static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800726android_media_MediaPlayer_getDuration(JNIEnv *env, jobject thiz)
727{
728 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
729 if (mp == NULL ) {
730 jniThrowException(env, "java/lang/IllegalStateException", NULL);
731 return 0;
732 }
733 int msec;
734 process_media_player_call( env, thiz, mp->getDuration(&msec), NULL, NULL );
Steve Block71f2cf12011-10-20 11:56:00 +0100735 ALOGV("getDuration: %d (msec)", msec);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000736 return (jint) msec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737}
738
739static void
740android_media_MediaPlayer_reset(JNIEnv *env, jobject thiz)
741{
Steve Block71f2cf12011-10-20 11:56:00 +0100742 ALOGV("reset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
744 if (mp == NULL ) {
745 jniThrowException(env, "java/lang/IllegalStateException", NULL);
746 return;
747 }
748 process_media_player_call( env, thiz, mp->reset(), NULL, NULL );
749}
750
751static void
Ashok Bhat075e9a12014-01-06 13:45:09 +0000752android_media_MediaPlayer_setAudioStreamType(JNIEnv *env, jobject thiz, jint streamtype)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753{
Steve Block71f2cf12011-10-20 11:56:00 +0100754 ALOGV("setAudioStreamType: %d", streamtype);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
756 if (mp == NULL ) {
757 jniThrowException(env, "java/lang/IllegalStateException", NULL);
758 return;
759 }
Glenn Kastenbc1d77b2012-01-12 16:38:12 -0800760 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 -0800761}
762
John Spurlock1af30c72014-03-10 08:33:35 -0400763static jint
764android_media_MediaPlayer_getAudioStreamType(JNIEnv *env, jobject thiz)
765{
766 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
767 if (mp == NULL ) {
768 jniThrowException(env, "java/lang/IllegalStateException", NULL);
769 return 0;
770 }
771 audio_stream_type_t streamtype;
772 process_media_player_call( env, thiz, mp->getAudioStreamType(&streamtype), NULL, NULL );
773 ALOGV("getAudioStreamType: %d (streamtype)", streamtype);
774 return (jint) streamtype;
775}
776
Jean-Michel Trivi8df982d2014-06-26 12:05:16 -0700777static jboolean
778android_media_MediaPlayer_setParameter(JNIEnv *env, jobject thiz, jint key, jobject java_request)
779{
780 ALOGV("setParameter: key %d", key);
781 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
782 if (mp == NULL ) {
783 jniThrowException(env, "java/lang/IllegalStateException", NULL);
784 return false;
785 }
786
787 Parcel *request = parcelForJavaObject(env, java_request);
788 status_t err = mp->setParameter(key, *request);
789 if (err == OK) {
790 return true;
791 } else {
792 return false;
793 }
794}
795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796static void
797android_media_MediaPlayer_setLooping(JNIEnv *env, jobject thiz, jboolean looping)
798{
Steve Block71f2cf12011-10-20 11:56:00 +0100799 ALOGV("setLooping: %d", looping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
801 if (mp == NULL ) {
802 jniThrowException(env, "java/lang/IllegalStateException", NULL);
803 return;
804 }
805 process_media_player_call( env, thiz, mp->setLooping(looping), NULL, NULL );
806}
807
808static jboolean
809android_media_MediaPlayer_isLooping(JNIEnv *env, jobject thiz)
810{
Steve Block71f2cf12011-10-20 11:56:00 +0100811 ALOGV("isLooping");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
813 if (mp == NULL ) {
814 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000815 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000817 return mp->isLooping() ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800818}
819
820static void
Ashok Bhat075e9a12014-01-06 13:45:09 +0000821android_media_MediaPlayer_setVolume(JNIEnv *env, jobject thiz, jfloat leftVolume, jfloat rightVolume)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000823 ALOGV("setVolume: left %f right %f", (float) leftVolume, (float) rightVolume);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
825 if (mp == NULL ) {
826 jniThrowException(env, "java/lang/IllegalStateException", NULL);
827 return;
828 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000829 process_media_player_call( env, thiz, mp->setVolume((float) leftVolume, (float) rightVolume), NULL, NULL );
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830}
831
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700832// Sends the request and reply parcels to the media player via the
833// binder interface.
834static jint
835android_media_MediaPlayer_invoke(JNIEnv *env, jobject thiz,
836 jobject java_request, jobject java_reply)
837{
838 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
839 if (media_player == NULL ) {
840 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700841 return UNKNOWN_ERROR;
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700842 }
843
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700844 Parcel *request = parcelForJavaObject(env, java_request);
845 Parcel *reply = parcelForJavaObject(env, java_reply);
846
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700847 // Don't use process_media_player_call which use the async loop to
848 // report errors, instead returns the status.
Ashok Bhat075e9a12014-01-06 13:45:09 +0000849 return (jint) media_player->invoke(*request, reply);
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700850}
851
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700852// Sends the new filter to the client.
853static jint
854android_media_MediaPlayer_setMetadataFilter(JNIEnv *env, jobject thiz, jobject request)
855{
856 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
857 if (media_player == NULL ) {
858 jniThrowException(env, "java/lang/IllegalStateException", NULL);
859 return UNKNOWN_ERROR;
860 }
861
862 Parcel *filter = parcelForJavaObject(env, request);
863
Nicolas Catania5d55c712009-07-09 09:21:33 -0700864 if (filter == NULL ) {
865 jniThrowException(env, "java/lang/RuntimeException", "Filter is null");
866 return UNKNOWN_ERROR;
867 }
868
Ashok Bhat075e9a12014-01-06 13:45:09 +0000869 return (jint) media_player->setMetadataFilter(*filter);
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700870}
871
Nicolas Catania5d55c712009-07-09 09:21:33 -0700872static jboolean
873android_media_MediaPlayer_getMetadata(JNIEnv *env, jobject thiz, jboolean update_only,
874 jboolean apply_filter, jobject reply)
875{
876 sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
877 if (media_player == NULL ) {
878 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000879 return JNI_FALSE;
Nicolas Catania5d55c712009-07-09 09:21:33 -0700880 }
881
882 Parcel *metadata = parcelForJavaObject(env, reply);
883
884 if (metadata == NULL ) {
885 jniThrowException(env, "java/lang/RuntimeException", "Reply parcel is null");
Ashok Bhat075e9a12014-01-06 13:45:09 +0000886 return JNI_FALSE;
Nicolas Catania5d55c712009-07-09 09:21:33 -0700887 }
888
889 metadata->freeData();
890 // On return metadata is positioned at the beginning of the
891 // metadata. Note however that the parcel actually starts with the
892 // return code so you should not rewind the parcel using
893 // setDataPosition(0).
Ashok Bhat075e9a12014-01-06 13:45:09 +0000894 if (media_player->getMetadata(update_only, apply_filter, metadata) == OK) {
895 return JNI_TRUE;
896 } else {
897 return JNI_FALSE;
898 }
Nicolas Catania5d55c712009-07-09 09:21:33 -0700899}
900
Marco Nelissen4935d052009-08-03 11:12:58 -0700901// This function gets some field IDs, which in turn causes class initialization.
902// It is called from a static block in MediaPlayer, which won't run until the
903// first time an instance of this class is used.
904static void
905android_media_MediaPlayer_native_init(JNIEnv *env)
906{
907 jclass clazz;
908
909 clazz = env->FindClass("android/media/MediaPlayer");
910 if (clazz == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700911 return;
912 }
913
Ashok Bhat075e9a12014-01-06 13:45:09 +0000914 fields.context = env->GetFieldID(clazz, "mNativeContext", "J");
Marco Nelissen4935d052009-08-03 11:12:58 -0700915 if (fields.context == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700916 return;
917 }
918
919 fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
920 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
921 if (fields.post_event == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700922 return;
923 }
924
Ashok Bhat075e9a12014-01-06 13:45:09 +0000925 fields.surface_texture = env->GetFieldID(clazz, "mNativeSurfaceTexture", "J");
Ted Bonkenburg1ee60112011-07-26 09:51:18 -0700926 if (fields.surface_texture == NULL) {
Glenn Kastencc562a32011-02-08 17:26:17 -0800927 return;
928 }
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700929
Lajos Molnarb3d5fd22015-04-22 13:14:34 -0700930 env->DeleteLocalRef(clazz);
931
Selim Gurun5ba69be2014-05-07 15:04:40 -0700932 clazz = env->FindClass("android/net/ProxyInfo");
Andreas Huberd5f9fa52013-05-28 14:39:39 -0700933 if (clazz == NULL) {
934 return;
935 }
936
937 fields.proxyConfigGetHost =
938 env->GetMethodID(clazz, "getHost", "()Ljava/lang/String;");
939
940 fields.proxyConfigGetPort =
941 env->GetMethodID(clazz, "getPort", "()I");
942
943 fields.proxyConfigGetExclusionList =
Selim Gurun5ba69be2014-05-07 15:04:40 -0700944 env->GetMethodID(clazz, "getExclusionListAsString", "()Ljava/lang/String;");
Lajos Molnarb3d5fd22015-04-22 13:14:34 -0700945
946 env->DeleteLocalRef(clazz);
947
Hassan Shojania0b52e952017-01-23 09:06:31 -0800948 // Modular DRM
Hassan Shojania0b52e952017-01-23 09:06:31 -0800949 FIND_CLASS(clazz, "android/media/MediaDrm$MediaDrmStateException");
950 if (clazz) {
Hassan Shojania06b25fb2017-02-06 21:09:42 -0800951 GET_METHOD_ID(gStateExceptionFields.init, clazz, "<init>", "(ILjava/lang/String;)V");
952 gStateExceptionFields.classId = static_cast<jclass>(env->NewGlobalRef(clazz));
Hassan Shojania0b52e952017-01-23 09:06:31 -0800953
954 env->DeleteLocalRef(clazz);
955 } else {
Hassan Shojania06b25fb2017-02-06 21:09:42 -0800956 ALOGE("JNI android_media_MediaPlayer_native_init couldn't "
Hassan Shojania0b52e952017-01-23 09:06:31 -0800957 "get clazz android/media/MediaDrm$MediaDrmStateException");
958 }
959
Wei Jia2d61e2b2015-05-08 15:23:28 -0700960 gPlaybackParamsFields.init(env);
961 gSyncParamsFields.init(env);
Andy Hung035d4ec2017-01-24 13:45:02 -0800962 gVolumeShaperFields.init(env);
Marco Nelissen4935d052009-08-03 11:12:58 -0700963}
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965static void
Colin Cross082aec62020-08-27 04:12:26 +0000966android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
Jan Sebechlebsky0bbdb712023-01-09 14:29:19 +0100967 jobject jAttributionSource,
968 jint jAudioSessionId)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969{
Steve Block71f2cf12011-10-20 11:56:00 +0100970 ALOGV("native_setup");
Philip P. Moltmannfece2432020-07-17 16:39:54 -0700971
Svet Ganov2eebf922021-05-20 15:09:08 +0000972 Parcel* parcel = parcelForJavaObject(env, jAttributionSource);
973 android::content::AttributionSourceState attributionSource;
974 attributionSource.readFromParcel(parcel);
Jan Sebechlebsky0bbdb712023-01-09 14:29:19 +0100975 sp<MediaPlayer> mp = sp<MediaPlayer>::make(
976 attributionSource, static_cast<audio_session_t>(jAudioSessionId));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 if (mp == NULL) {
978 jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
979 return;
980 }
981
982 // create new listener and give it to MediaPlayer
983 sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
984 mp->setListener(listener);
985
986 // Stow our new C++ MediaPlayer in an opaque field in the Java object.
987 setMediaPlayer(env, thiz, mp);
988}
989
990static void
991android_media_MediaPlayer_release(JNIEnv *env, jobject thiz)
992{
Steve Block71f2cf12011-10-20 11:56:00 +0100993 ALOGV("release");
Gloria Wangd59310d2011-09-14 13:59:45 -0700994 decVideoSurfaceRef(env, thiz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 sp<MediaPlayer> mp = setMediaPlayer(env, thiz, 0);
996 if (mp != NULL) {
997 // this prevents native callbacks after the object is released
998 mp->setListener(0);
999 mp->disconnect();
1000 }
1001}
1002
1003static void
1004android_media_MediaPlayer_native_finalize(JNIEnv *env, jobject thiz)
1005{
Steve Block71f2cf12011-10-20 11:56:00 +01001006 ALOGV("native_finalize");
Marco Nelissen8dc208472011-09-28 09:21:11 -07001007 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1008 if (mp != NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +00001009 ALOGW("MediaPlayer finalized without being released");
Marco Nelissen8dc208472011-09-28 09:21:11 -07001010 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 android_media_MediaPlayer_release(env, thiz);
1012}
1013
Glenn Kasten33b84042016-03-08 12:02:55 -08001014static void android_media_MediaPlayer_set_audio_session_id(JNIEnv *env, jobject thiz,
1015 jint sessionId) {
Steve Block71f2cf12011-10-20 11:56:00 +01001016 ALOGV("set_session_id(): %d", sessionId);
Eric Laurent619346f2010-06-21 09:27:30 -07001017 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1018 if (mp == NULL ) {
1019 jniThrowException(env, "java/lang/IllegalStateException", NULL);
1020 return;
1021 }
Glenn Kasten33b84042016-03-08 12:02:55 -08001022 process_media_player_call( env, thiz, mp->setAudioSessionId((audio_session_t) sessionId), NULL,
1023 NULL);
Eric Laurent619346f2010-06-21 09:27:30 -07001024}
1025
1026static jint android_media_MediaPlayer_get_audio_session_id(JNIEnv *env, jobject thiz) {
Steve Block71f2cf12011-10-20 11:56:00 +01001027 ALOGV("get_session_id()");
Eric Laurent619346f2010-06-21 09:27:30 -07001028 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1029 if (mp == NULL ) {
1030 jniThrowException(env, "java/lang/IllegalStateException", NULL);
1031 return 0;
1032 }
1033
Ashok Bhat075e9a12014-01-06 13:45:09 +00001034 return (jint) mp->getAudioSessionId();
Eric Laurent619346f2010-06-21 09:27:30 -07001035}
1036
Eric Laurent7070b362010-07-16 07:43:46 -07001037static void
1038android_media_MediaPlayer_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level)
1039{
Steve Block71f2cf12011-10-20 11:56:00 +01001040 ALOGV("setAuxEffectSendLevel: level %f", level);
Eric Laurent7070b362010-07-16 07:43:46 -07001041 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1042 if (mp == NULL ) {
1043 jniThrowException(env, "java/lang/IllegalStateException", NULL);
1044 return;
1045 }
1046 process_media_player_call( env, thiz, mp->setAuxEffectSendLevel(level), NULL, NULL );
1047}
1048
1049static void android_media_MediaPlayer_attachAuxEffect(JNIEnv *env, jobject thiz, jint effectId) {
Steve Block71f2cf12011-10-20 11:56:00 +01001050 ALOGV("attachAuxEffect(): %d", effectId);
Eric Laurent7070b362010-07-16 07:43:46 -07001051 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1052 if (mp == NULL ) {
1053 jniThrowException(env, "java/lang/IllegalStateException", NULL);
1054 return;
1055 }
1056 process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL );
1057}
1058
Gloria Wangd211f412011-02-19 18:37:57 -08001059static jint
Andreas Huberd2506a52014-01-29 10:32:46 -08001060android_media_MediaPlayer_pullBatteryData(
1061 JNIEnv *env, jobject /* thiz */, jobject java_reply)
Gloria Wangd211f412011-02-19 18:37:57 -08001062{
1063 sp<IBinder> binder = defaultServiceManager()->getService(String16("media.player"));
1064 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
1065 if (service.get() == NULL) {
1066 jniThrowException(env, "java/lang/RuntimeException", "cannot get MediaPlayerService");
1067 return UNKNOWN_ERROR;
1068 }
1069
1070 Parcel *reply = parcelForJavaObject(env, java_reply);
1071
Ashok Bhat075e9a12014-01-06 13:45:09 +00001072 return (jint) service->pullBatteryData(reply);
Gloria Wangd211f412011-02-19 18:37:57 -08001073}
1074
John Grossman720aa282012-02-22 15:38:35 -08001075static jint
1076android_media_MediaPlayer_setRetransmitEndpoint(JNIEnv *env, jobject thiz,
1077 jstring addrString, jint port) {
1078 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1079 if (mp == NULL ) {
1080 jniThrowException(env, "java/lang/IllegalStateException", NULL);
1081 return INVALID_OPERATION;
1082 }
1083
1084 const char *cAddrString = NULL;
1085
1086 if (NULL != addrString) {
1087 cAddrString = env->GetStringUTFChars(addrString, NULL);
1088 if (cAddrString == NULL) { // Out of memory
1089 return NO_MEMORY;
1090 }
1091 }
1092 ALOGV("setRetransmitEndpoint: %s:%d",
1093 cAddrString ? cAddrString : "(null)", port);
1094
1095 status_t ret;
1096 if (cAddrString && (port > 0xFFFF)) {
1097 ret = BAD_VALUE;
1098 } else {
1099 ret = mp->setRetransmitEndpoint(cAddrString,
1100 static_cast<uint16_t>(port));
1101 }
1102
1103 if (NULL != addrString) {
1104 env->ReleaseStringUTFChars(addrString, cAddrString);
1105 }
1106
1107 if (ret == INVALID_OPERATION ) {
1108 jniThrowException(env, "java/lang/IllegalStateException", NULL);
1109 }
1110
Ashok Bhat075e9a12014-01-06 13:45:09 +00001111 return (jint) ret;
John Grossman720aa282012-02-22 15:38:35 -08001112}
1113
Marco Nelissen84b83202012-02-28 16:07:44 -08001114static void
1115android_media_MediaPlayer_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject java_player)
1116{
1117 ALOGV("setNextMediaPlayer");
1118 sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
1119 if (thisplayer == NULL) {
1120 jniThrowException(env, "java/lang/IllegalStateException", "This player not initialized");
1121 return;
1122 }
1123 sp<MediaPlayer> nextplayer = (java_player == NULL) ? NULL : getMediaPlayer(env, java_player);
1124 if (nextplayer == NULL && java_player != NULL) {
1125 jniThrowException(env, "java/lang/IllegalStateException", "That player not initialized");
1126 return;
1127 }
1128
1129 if (nextplayer == thisplayer) {
1130 jniThrowException(env, "java/lang/IllegalArgumentException", "Next player can't be self");
1131 return;
1132 }
1133 // tie the two players together
1134 process_media_player_call(
1135 env, thiz, thisplayer->setNextMediaPlayer(nextplayer),
1136 "java/lang/IllegalArgumentException",
1137 "setNextMediaPlayer failed." );
1138 ;
1139}
1140
Andy Hung035d4ec2017-01-24 13:45:02 -08001141// Pass through the arguments to the MediaServer player implementation.
1142static jint android_media_MediaPlayer_applyVolumeShaper(JNIEnv *env, jobject thiz,
1143 jobject jconfig, jobject joperation) {
1144 // NOTE: hard code here to prevent platform issues. Must match VolumeShaper.java
1145 const int VOLUME_SHAPER_INVALID_OPERATION = -38;
1146
1147 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1148 if (mp == nullptr) {
1149 return (jint)VOLUME_SHAPER_INVALID_OPERATION;
1150 }
1151
1152 sp<VolumeShaper::Configuration> configuration;
1153 sp<VolumeShaper::Operation> operation;
1154 if (jconfig != nullptr) {
1155 configuration = VolumeShaperHelper::convertJobjectToConfiguration(
1156 env, gVolumeShaperFields, jconfig);
1157 ALOGV("applyVolumeShaper configuration: %s", configuration->toString().c_str());
1158 }
1159 if (joperation != nullptr) {
1160 operation = VolumeShaperHelper::convertJobjectToOperation(
1161 env, gVolumeShaperFields, joperation);
1162 ALOGV("applyVolumeShaper operation: %s", operation->toString().c_str());
1163 }
1164 VolumeShaper::Status status = mp->applyVolumeShaper(configuration, operation);
1165 if (status == INVALID_OPERATION) {
1166 status = VOLUME_SHAPER_INVALID_OPERATION;
1167 }
1168 return (jint)status; // if status < 0 an error, else a VolumeShaper id
1169}
1170
1171// Pass through the arguments to the MediaServer player implementation.
1172static jobject android_media_MediaPlayer_getVolumeShaperState(JNIEnv *env, jobject thiz,
1173 jint id) {
1174 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1175 if (mp == nullptr) {
1176 return (jobject)nullptr;
1177 }
1178
1179 sp<VolumeShaper::State> state = mp->getVolumeShaperState((int)id);
1180 if (state.get() == nullptr) {
1181 return (jobject)nullptr;
1182 }
1183 return VolumeShaperHelper::convertStateToJobject(env, gVolumeShaperFields, state);
1184}
1185
Hassan Shojania0b52e952017-01-23 09:06:31 -08001186/////////////////////////////////////////////////////////////////////////////////////
1187// Modular DRM begin
1188
1189// TODO: investigate if these can be shared with their MediaDrm counterparts
1190static void throwDrmStateException(JNIEnv *env, const char *msg, status_t err)
1191{
1192 ALOGE("Illegal DRM state exception: %s (%d)", msg, err);
1193
Hassan Shojania06b25fb2017-02-06 21:09:42 -08001194 jobject exception = env->NewObject(gStateExceptionFields.classId,
1195 gStateExceptionFields.init, static_cast<int>(err),
Hassan Shojania0b52e952017-01-23 09:06:31 -08001196 env->NewStringUTF(msg));
1197 env->Throw(static_cast<jthrowable>(exception));
1198}
1199
1200// TODO: investigate if these can be shared with their MediaDrm counterparts
1201static bool throwDrmExceptionAsNecessary(JNIEnv *env, status_t err, const char *msg = NULL)
1202{
1203 const char *drmMessage = "Unknown DRM Msg";
1204
1205 switch (err) {
1206 case ERROR_DRM_UNKNOWN:
1207 drmMessage = "General DRM error";
1208 break;
1209 case ERROR_DRM_NO_LICENSE:
1210 drmMessage = "No license";
1211 break;
1212 case ERROR_DRM_LICENSE_EXPIRED:
1213 drmMessage = "License expired";
1214 break;
1215 case ERROR_DRM_SESSION_NOT_OPENED:
1216 drmMessage = "Session not opened";
1217 break;
1218 case ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED:
1219 drmMessage = "Not initialized";
1220 break;
1221 case ERROR_DRM_DECRYPT:
1222 drmMessage = "Decrypt error";
1223 break;
1224 case ERROR_DRM_CANNOT_HANDLE:
1225 drmMessage = "Unsupported scheme or data format";
1226 break;
1227 case ERROR_DRM_TAMPER_DETECTED:
1228 drmMessage = "Invalid state";
1229 break;
1230 default:
1231 break;
1232 }
1233
1234 String8 vendorMessage;
1235 if (err >= ERROR_DRM_VENDOR_MIN && err <= ERROR_DRM_VENDOR_MAX) {
1236 vendorMessage = String8::format("DRM vendor-defined error: %d", err);
Tomasz Wasilczyk3815d342023-08-10 23:54:44 +00001237 drmMessage = vendorMessage.c_str();
Hassan Shojania0b52e952017-01-23 09:06:31 -08001238 }
1239
1240 if (err == BAD_VALUE) {
1241 jniThrowException(env, "java/lang/IllegalArgumentException", msg);
1242 return true;
1243 } else if (err == ERROR_DRM_NOT_PROVISIONED) {
1244 jniThrowException(env, "android/media/NotProvisionedException", msg);
1245 return true;
1246 } else if (err == ERROR_DRM_RESOURCE_BUSY) {
1247 jniThrowException(env, "android/media/ResourceBusyException", msg);
1248 return true;
1249 } else if (err == ERROR_DRM_DEVICE_REVOKED) {
1250 jniThrowException(env, "android/media/DeniedByServerException", msg);
1251 return true;
1252 } else if (err == DEAD_OBJECT) {
1253 jniThrowException(env, "android/media/MediaDrmResetException",
1254 "mediaserver died");
1255 return true;
1256 } else if (err != OK) {
1257 String8 errbuf;
1258 if (drmMessage != NULL) {
1259 if (msg == NULL) {
1260 msg = drmMessage;
1261 } else {
1262 errbuf = String8::format("%s: %s", msg, drmMessage);
Tomasz Wasilczyk3815d342023-08-10 23:54:44 +00001263 msg = errbuf.c_str();
Hassan Shojania0b52e952017-01-23 09:06:31 -08001264 }
1265 }
1266 throwDrmStateException(env, msg, err);
1267 return true;
1268 }
1269 return false;
1270}
1271
Hassan Shojania0b52e952017-01-23 09:06:31 -08001272static Vector<uint8_t> JByteArrayToVector(JNIEnv *env, jbyteArray const &byteArray)
1273{
1274 Vector<uint8_t> vector;
1275 size_t length = env->GetArrayLength(byteArray);
1276 vector.insertAt((size_t)0, length);
1277 env->GetByteArrayRegion(byteArray, 0, length, (jbyte *)vector.editArray());
1278 return vector;
1279}
1280
Hassan Shojania0b52e952017-01-23 09:06:31 -08001281static void android_media_MediaPlayer_prepareDrm(JNIEnv *env, jobject thiz,
Hassan Shojania06b25fb2017-02-06 21:09:42 -08001282 jbyteArray uuidObj, jbyteArray drmSessionIdObj)
Hassan Shojania0b52e952017-01-23 09:06:31 -08001283{
1284 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1285 if (mp == NULL) {
1286 jniThrowException(env, "java/lang/IllegalStateException", NULL);
1287 return;
1288 }
1289
1290 if (uuidObj == NULL) {
1291 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1292 return;
1293 }
1294
1295 Vector<uint8_t> uuid = JByteArrayToVector(env, uuidObj);
1296
1297 if (uuid.size() != 16) {
1298 jniThrowException(
1299 env,
1300 "java/lang/IllegalArgumentException",
1301 "invalid UUID size, expected 16 bytes");
1302 return;
1303 }
1304
Hassan Shojania06b25fb2017-02-06 21:09:42 -08001305 Vector<uint8_t> drmSessionId = JByteArrayToVector(env, drmSessionIdObj);
1306
1307 if (drmSessionId.size() == 0) {
1308 jniThrowException(
1309 env,
1310 "java/lang/IllegalArgumentException",
1311 "empty drmSessionId");
1312 return;
1313 }
1314
1315 status_t err = mp->prepareDrm(uuid.array(), drmSessionId);
Hassan Shojania0b52e952017-01-23 09:06:31 -08001316 if (err != OK) {
1317 if (err == INVALID_OPERATION) {
1318 jniThrowException(
1319 env,
1320 "java/lang/IllegalStateException",
Hassan Shojania06b25fb2017-02-06 21:09:42 -08001321 "The player must be in prepared state.");
Hassan Shojania0b52e952017-01-23 09:06:31 -08001322 } else if (err == ERROR_DRM_CANNOT_HANDLE) {
1323 jniThrowException(
1324 env,
1325 "android/media/UnsupportedSchemeException",
1326 "Failed to instantiate drm object.");
1327 } else {
1328 throwDrmExceptionAsNecessary(env, err, "Failed to prepare DRM scheme");
1329 }
1330 }
1331}
1332
1333static void android_media_MediaPlayer_releaseDrm(JNIEnv *env, jobject thiz)
1334{
1335 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1336 if (mp == NULL ) {
1337 jniThrowException(env, "java/lang/IllegalStateException", NULL);
1338 return;
1339 }
1340
1341 status_t err = mp->releaseDrm();
1342 if (err != OK) {
1343 if (err == INVALID_OPERATION) {
1344 jniThrowException(
1345 env,
1346 "java/lang/IllegalStateException",
Hassan Shojania06b25fb2017-02-06 21:09:42 -08001347 "Can not release DRM in an active player state.");
Hassan Shojania0b52e952017-01-23 09:06:31 -08001348 }
1349 }
1350}
Hassan Shojania0b52e952017-01-23 09:06:31 -08001351// Modular DRM end
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352// ----------------------------------------------------------------------------
1353
jiabin6e5a6282017-10-06 09:34:23 -07001354/////////////////////////////////////////////////////////////////////////////////////
1355// AudioRouting begin
1356static jboolean android_media_MediaPlayer_setOutputDevice(JNIEnv *env, jobject thiz, jint device_id)
1357{
1358 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1359 if (mp == NULL) {
1360 return false;
1361 }
1362 return mp->setOutputDevice(device_id) == NO_ERROR;
1363}
1364
Robert Wub5565592024-10-29 23:39:13 +00001365static jintArray android_media_MediaPlayer_getRoutedDeviceIds(JNIEnv *env, jobject thiz)
jiabin6e5a6282017-10-06 09:34:23 -07001366{
1367 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1368 if (mp == NULL) {
Robert Wub5565592024-10-29 23:39:13 +00001369 return NULL;
jiabin6e5a6282017-10-06 09:34:23 -07001370 }
Robert Wub5565592024-10-29 23:39:13 +00001371 DeviceIdVector deviceIds;
1372 // TODO: b/379161379 - Should we throw an exception if the result is not ok?
1373 mp->getRoutedDeviceIds(deviceIds);
1374 jintArray result;
1375 result = env->NewIntArray(deviceIds.size());
1376 if (result == NULL) {
1377 return NULL;
1378 }
1379 jint* values = env->GetIntArrayElements(result, 0);
1380 for (unsigned int i = 0; i < deviceIds.size(); i++) {
1381 values[i++] = static_cast<jint>(deviceIds[i]);
1382 }
1383 env->ReleaseIntArrayElements(result, values, 0);
1384 return result;
jiabin6e5a6282017-10-06 09:34:23 -07001385}
1386
1387static void android_media_MediaPlayer_enableDeviceCallback(
1388 JNIEnv* env, jobject thiz, jboolean enabled)
1389{
1390 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
1391 if (mp == NULL) {
1392 return;
1393 }
1394
1395 status_t status = mp->enableAudioDeviceCallback(enabled);
1396 if (status != NO_ERROR) {
1397 jniThrowException(env, "java/lang/IllegalStateException", NULL);
1398 ALOGE("enable device callback failed: %d", status);
1399 }
1400}
1401
1402// AudioRouting end
1403// ----------------------------------------------------------------------------
1404
Daniel Micay76f6a862015-09-19 17:31:01 -04001405static const JNINativeMethod gMethods[] = {
James Dong17524dc2011-05-04 13:41:58 -07001406 {
Andreas Huberd2506a52014-01-29 10:32:46 -08001407 "nativeSetDataSource",
1408 "(Landroid/os/IBinder;Ljava/lang/String;[Ljava/lang/String;"
1409 "[Ljava/lang/String;)V",
James Dong17524dc2011-05-04 13:41:58 -07001410 (void *)android_media_MediaPlayer_setDataSourceAndHeaders
1411 },
1412
Chris Watkins4eaa2932015-03-20 10:31:42 -07001413 {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
1414 {"_setDataSource", "(Landroid/media/MediaDataSource;)V",(void *)android_media_MediaPlayer_setDataSourceCallback },
Ted Bonkenburg1ee60112011-07-26 09:51:18 -07001415 {"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface},
Vlad Popa66824a32022-08-12 16:05:05 +02001416 {"_prepare", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_prepare},
1417 {"_prepareAsync", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_prepareAsync},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 {"_start", "()V", (void *)android_media_MediaPlayer_start},
1419 {"_stop", "()V", (void *)android_media_MediaPlayer_stop},
1420 {"getVideoWidth", "()I", (void *)android_media_MediaPlayer_getVideoWidth},
1421 {"getVideoHeight", "()I", (void *)android_media_MediaPlayer_getVideoHeight},
Ray Essick10353e32017-04-14 10:22:55 -07001422 {"native_getMetrics", "()Landroid/os/PersistableBundle;", (void *)android_media_MediaPlayer_native_getMetrics},
Wei Jia2d61e2b2015-05-08 15:23:28 -07001423 {"setPlaybackParams", "(Landroid/media/PlaybackParams;)V", (void *)android_media_MediaPlayer_setPlaybackParams},
1424 {"getPlaybackParams", "()Landroid/media/PlaybackParams;", (void *)android_media_MediaPlayer_getPlaybackParams},
1425 {"setSyncParams", "(Landroid/media/SyncParams;)V", (void *)android_media_MediaPlayer_setSyncParams},
1426 {"getSyncParams", "()Landroid/media/SyncParams;", (void *)android_media_MediaPlayer_getSyncParams},
Wei Jiabebeaf92017-04-19 16:22:10 -07001427 {"_seekTo", "(JI)V", (void *)android_media_MediaPlayer_seekTo},
Wei Jiac02f09d2017-09-13 18:19:48 -07001428 {"_notifyAt", "(J)V", (void *)android_media_MediaPlayer_notifyAt},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 {"_pause", "()V", (void *)android_media_MediaPlayer_pause},
1430 {"isPlaying", "()Z", (void *)android_media_MediaPlayer_isPlaying},
1431 {"getCurrentPosition", "()I", (void *)android_media_MediaPlayer_getCurrentPosition},
1432 {"getDuration", "()I", (void *)android_media_MediaPlayer_getDuration},
1433 {"_release", "()V", (void *)android_media_MediaPlayer_release},
1434 {"_reset", "()V", (void *)android_media_MediaPlayer_reset},
John Spurlock1af30c72014-03-10 08:33:35 -04001435 {"_setAudioStreamType", "(I)V", (void *)android_media_MediaPlayer_setAudioStreamType},
1436 {"_getAudioStreamType", "()I", (void *)android_media_MediaPlayer_getAudioStreamType},
Jean-Michel Trivi8df982d2014-06-26 12:05:16 -07001437 {"setParameter", "(ILandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_setParameter},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001438 {"setLooping", "(Z)V", (void *)android_media_MediaPlayer_setLooping},
1439 {"isLooping", "()Z", (void *)android_media_MediaPlayer_isLooping},
John Spurlock1af30c72014-03-10 08:33:35 -04001440 {"_setVolume", "(FF)V", (void *)android_media_MediaPlayer_setVolume},
Nicolas Catania20cb94e2009-05-12 23:25:55 -07001441 {"native_invoke", "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
Nicolas Cataniab2c69392009-07-08 08:57:42 -07001442 {"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter},
Nicolas Catania5d55c712009-07-09 09:21:33 -07001443 {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata},
Marco Nelissen4935d052009-08-03 11:12:58 -07001444 {"native_init", "()V", (void *)android_media_MediaPlayer_native_init},
Jan Sebechlebsky0bbdb712023-01-09 14:29:19 +01001445 {"native_setup",
1446 "(Ljava/lang/Object;Landroid/os/Parcel;I)V",
1447 (void *)android_media_MediaPlayer_native_setup},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001448 {"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
Eric Laurent619346f2010-06-21 09:27:30 -07001449 {"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id},
Eric Laurent53945a42021-01-29 21:24:08 +01001450 {"native_setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id},
John Spurlock1af30c72014-03-10 08:33:35 -04001451 {"_setAuxEffectSendLevel", "(F)V", (void *)android_media_MediaPlayer_setAuxEffectSendLevel},
Eric Laurent7070b362010-07-16 07:43:46 -07001452 {"attachAuxEffect", "(I)V", (void *)android_media_MediaPlayer_attachAuxEffect},
Gloria Wangd211f412011-02-19 18:37:57 -08001453 {"native_pullBatteryData", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_pullBatteryData},
John Grossman720aa282012-02-22 15:38:35 -08001454 {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I", (void *)android_media_MediaPlayer_setRetransmitEndpoint},
Marco Nelissen84b83202012-02-28 16:07:44 -08001455 {"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer},
Andy Hung035d4ec2017-01-24 13:45:02 -08001456 {"native_applyVolumeShaper",
1457 "(Landroid/media/VolumeShaper$Configuration;Landroid/media/VolumeShaper$Operation;)I",
1458 (void *)android_media_MediaPlayer_applyVolumeShaper},
1459 {"native_getVolumeShaperState",
1460 "(I)Landroid/media/VolumeShaper$State;",
1461 (void *)android_media_MediaPlayer_getVolumeShaperState},
Hassan Shojania0b52e952017-01-23 09:06:31 -08001462 // Modular DRM
Hassan Shojania06b25fb2017-02-06 21:09:42 -08001463 { "_prepareDrm", "([B[B)V", (void *)android_media_MediaPlayer_prepareDrm },
Hassan Shojania0b52e952017-01-23 09:06:31 -08001464 { "_releaseDrm", "()V", (void *)android_media_MediaPlayer_releaseDrm },
jiabin6e5a6282017-10-06 09:34:23 -07001465
1466 // AudioRouting
1467 {"native_setOutputDevice", "(I)Z", (void *)android_media_MediaPlayer_setOutputDevice},
Robert Wub5565592024-10-29 23:39:13 +00001468 {"native_getRoutedDeviceIds", "()[I",
1469 (void *)android_media_MediaPlayer_getRoutedDeviceIds},
jiabin6e5a6282017-10-06 09:34:23 -07001470 {"native_enableDeviceCallback", "(Z)V", (void *)android_media_MediaPlayer_enableDeviceCallback},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471};
1472
Marco Nelissen4935d052009-08-03 11:12:58 -07001473// This function only registers the native methods
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474static int register_android_media_MediaPlayer(JNIEnv *env)
1475{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 return AndroidRuntime::registerNativeMethods(env,
1477 "android/media/MediaPlayer", gMethods, NELEM(gMethods));
1478}
Zhijun He212e78d2013-06-07 11:36:23 -07001479extern int register_android_media_ImageReader(JNIEnv *env);
Zhijun Hef6a09e52015-02-24 18:12:23 -08001480extern int register_android_media_ImageWriter(JNIEnv *env);
Marco Nelissen5ff11732019-10-17 08:55:52 -07001481extern int register_android_media_JetPlayer(JNIEnv *env);
Andreas Huber8240d922012-04-04 14:06:32 -07001482extern int register_android_media_Crypto(JNIEnv *env);
Jeff Tinker8a0c80f2013-02-08 10:20:44 -08001483extern int register_android_media_Drm(JNIEnv *env);
Chong Zhangd5927ae2017-01-03 11:07:18 -08001484extern int register_android_media_Descrambler(JNIEnv *env);
Andreas Huber88572f72012-02-21 11:47:18 -08001485extern int register_android_media_MediaCodec(JNIEnv *env);
1486extern int register_android_media_MediaExtractor(JNIEnv *env);
Andreas Huber5a04bf32012-03-29 16:41:38 -07001487extern int register_android_media_MediaCodecList(JNIEnv *env);
Andreas Huberd2506a52014-01-29 10:32:46 -08001488extern int register_android_media_MediaHTTPConnection(JNIEnv *env);
Andreas Huberbfb9fb12009-12-03 11:31:19 -08001489extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
ztenghui68ccf102013-02-13 14:07:02 -08001490extern int register_android_media_MediaMuxer(JNIEnv *env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491extern int register_android_media_MediaRecorder(JNIEnv *env);
Wei Jia071a8b72015-03-09 16:38:25 -07001492extern int register_android_media_MediaSync(JNIEnv *env);
Sally Qiaba398d2021-12-06 16:37:50 -08001493extern int register_android_media_PublicFormatUtils(JNIEnv *env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494extern int register_android_media_ResampleInputStream(JNIEnv *env);
James Dongc3711942010-01-19 17:45:38 -08001495extern int register_android_media_MediaProfiles(JNIEnv *env);
Mike Lockwood0cd01362010-12-30 11:54:33 -05001496extern int register_android_mtp_MtpDatabase(JNIEnv *env);
Mike Lockwood8182e722010-12-30 15:38:45 -05001497extern int register_android_mtp_MtpDevice(JNIEnv *env);
Mike Lockwood0cd01362010-12-30 11:54:33 -05001498extern int register_android_mtp_MtpServer(JNIEnv *env);
Andreas Huberbfb9fb12009-12-03 11:31:19 -08001499
Andreas Huberd2506a52014-01-29 10:32:46 -08001500jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501{
1502 JNIEnv* env = NULL;
1503 jint result = -1;
1504
1505 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
Steve Block3762c312012-01-06 19:20:56 +00001506 ALOGE("ERROR: GetEnv failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001507 goto bail;
1508 }
1509 assert(env != NULL);
1510
Zhijun Hef6a09e52015-02-24 18:12:23 -08001511 if (register_android_media_ImageWriter(env) != JNI_OK) {
1512 ALOGE("ERROR: ImageWriter native registration failed");
1513 goto bail;
1514 }
1515
Zhijun He212e78d2013-06-07 11:36:23 -07001516 if (register_android_media_ImageReader(env) < 0) {
1517 ALOGE("ERROR: ImageReader native registration failed");
1518 goto bail;
1519 }
1520
Marco Nelissen5ff11732019-10-17 08:55:52 -07001521 if (register_android_media_JetPlayer(env) < 0) {
1522 ALOGE("ERROR: JetPlayer native registration failed");
1523 goto bail;
1524 }
1525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 if (register_android_media_MediaPlayer(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001527 ALOGE("ERROR: MediaPlayer native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 goto bail;
1529 }
1530
1531 if (register_android_media_MediaRecorder(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001532 ALOGE("ERROR: MediaRecorder native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 goto bail;
1534 }
1535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 if (register_android_media_MediaMetadataRetriever(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001537 ALOGE("ERROR: MediaMetadataRetriever native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001538 goto bail;
1539 }
1540
Sally Qiaba398d2021-12-06 16:37:50 -08001541 if (register_android_media_PublicFormatUtils(env) < 0) {
1542 ALOGE("ERROR: PublicFormatUtils native registration failed\n");
1543 goto bail;
1544 }
1545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 if (register_android_media_ResampleInputStream(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001547 ALOGE("ERROR: ResampleInputStream native registration failed\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 goto bail;
1549 }
1550
James Dongc3711942010-01-19 17:45:38 -08001551 if (register_android_media_MediaProfiles(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001552 ALOGE("ERROR: MediaProfiles native registration failed");
James Dongc3711942010-01-19 17:45:38 -08001553 goto bail;
1554 }
1555
Mike Lockwood0cd01362010-12-30 11:54:33 -05001556 if (register_android_mtp_MtpDatabase(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001557 ALOGE("ERROR: MtpDatabase native registration failed");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001558 goto bail;
1559 }
1560
Mike Lockwood8182e722010-12-30 15:38:45 -05001561 if (register_android_mtp_MtpDevice(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001562 ALOGE("ERROR: MtpDevice native registration failed");
Mike Lockwood8182e722010-12-30 15:38:45 -05001563 goto bail;
1564 }
1565
Mike Lockwood0cd01362010-12-30 11:54:33 -05001566 if (register_android_mtp_MtpServer(env) < 0) {
Steve Block3762c312012-01-06 19:20:56 +00001567 ALOGE("ERROR: MtpServer native registration failed");
Mike Lockwood81ea83d2010-06-30 17:49:41 -04001568 goto bail;
1569 }
1570
Andreas Huber88572f72012-02-21 11:47:18 -08001571 if (register_android_media_MediaCodec(env) < 0) {
1572 ALOGE("ERROR: MediaCodec native registration failed");
1573 goto bail;
1574 }
1575
Wei Jia071a8b72015-03-09 16:38:25 -07001576 if (register_android_media_MediaSync(env) < 0) {
1577 ALOGE("ERROR: MediaSync native registration failed");
1578 goto bail;
1579 }
1580
Andreas Huber88572f72012-02-21 11:47:18 -08001581 if (register_android_media_MediaExtractor(env) < 0) {
1582 ALOGE("ERROR: MediaCodec native registration failed");
1583 goto bail;
1584 }
1585
ztenghui68ccf102013-02-13 14:07:02 -08001586 if (register_android_media_MediaMuxer(env) < 0) {
1587 ALOGE("ERROR: MediaMuxer native registration failed");
1588 goto bail;
1589 }
1590
Andreas Huber5a04bf32012-03-29 16:41:38 -07001591 if (register_android_media_MediaCodecList(env) < 0) {
1592 ALOGE("ERROR: MediaCodec native registration failed");
1593 goto bail;
1594 }
1595
Andreas Huber8240d922012-04-04 14:06:32 -07001596 if (register_android_media_Crypto(env) < 0) {
1597 ALOGE("ERROR: MediaCodec native registration failed");
1598 goto bail;
1599 }
1600
Jeff Tinker8a0c80f2013-02-08 10:20:44 -08001601 if (register_android_media_Drm(env) < 0) {
1602 ALOGE("ERROR: MediaDrm native registration failed");
1603 goto bail;
1604 }
1605
Chong Zhangd5927ae2017-01-03 11:07:18 -08001606 if (register_android_media_Descrambler(env) < 0) {
1607 ALOGE("ERROR: MediaDescrambler native registration failed");
1608 goto bail;
1609 }
1610
Andreas Huberd2506a52014-01-29 10:32:46 -08001611 if (register_android_media_MediaHTTPConnection(env) < 0) {
1612 ALOGE("ERROR: MediaHTTPConnection native registration failed");
1613 goto bail;
1614 }
1615
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001616 /* success -- return valid version number */
1617 result = JNI_VERSION_1_4;
1618
1619bail:
1620 return result;
1621}
1622
1623// KTHXBYE