blob: 3ec0903472bc64aa80472aec88eb0f06fdf53611 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mark Salyzyn85394032014-04-16 10:28:37 -070017#include <assert.h>
18#include <fcntl.h>
19#include <inttypes.h>
20#include <limits.h>
21#include <stdio.h>
22#include <unistd.h>
jiabin589f6a22018-01-23 12:22:47 -080023#include <vector>
Mark Salyzyn85394032014-04-16 10:28:37 -070024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025//#define LOG_NDEBUG 0
26#define LOG_TAG "MediaRecorderJNI"
27#include <utils/Log.h>
28
Mathias Agopian8335f1c2012-02-25 18:48:35 -080029#include <gui/Surface.h>
Mathias Agopian000479f2010-02-09 17:46:37 -080030#include <camera/Camera.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031#include <media/mediarecorder.h>
Ray Essickb0bd62f2017-02-12 19:22:48 -080032#include <media/MediaAnalyticsItem.h>
jiabin589f6a22018-01-23 12:22:47 -080033#include <media/MicrophoneInfo.h>
Chong Zhang03359162015-05-01 12:50:30 -070034#include <media/stagefright/PersistentSurface.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035#include <utils/threads.h>
36
Steven Moreland65e2ca22017-08-10 15:55:12 -070037#include <nativehelper/ScopedUtfChars.h>
Svet Ganovfa5ecdc2015-04-28 12:03:28 -070038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039#include "jni.h"
Steven Moreland60cc6c02017-08-25 15:49:25 -070040#include <nativehelper/JNIHelp.h>
jiabin589f6a22018-01-23 12:22:47 -080041#include "android_media_AudioErrors.h"
Ray Essickb0bd62f2017-02-12 19:22:48 -080042#include "android_media_MediaMetricsJNI.h"
jiabin589f6a22018-01-23 12:22:47 -080043#include "android_media_MicrophoneInfo.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044#include "android_runtime/AndroidRuntime.h"
45
Dima Zavin34bb4192011-05-11 14:15:23 -070046#include <system/audio.h>
Mathias Agopian3866f0d2013-02-11 22:08:48 -080047#include <android_runtime/android_view_Surface.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048
49// ----------------------------------------------------------------------------
50
51using namespace android;
52
53// ----------------------------------------------------------------------------
54
55// helper function to extract a native Camera object from a Camera Java object
Dave Sparks5e271152009-06-23 17:30:11 -070056extern sp<Camera> get_native_camera(JNIEnv *env, jobject thiz, struct JNICameraContext** context);
Chong Zhang03359162015-05-01 12:50:30 -070057extern sp<PersistentSurface>
58android_media_MediaCodec_getPersistentInputSurface(JNIEnv* env, jobject object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059
60struct fields_t {
61 jfieldID context;
62 jfieldID surface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063
64 jmethodID post_event;
65};
66static fields_t fields;
67
jiabin589f6a22018-01-23 12:22:47 -080068struct ArrayListFields {
69 jmethodID add;
70 jclass classId;
71};
72static ArrayListFields gArrayListFields;
73
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074static Mutex sLock;
75
76// ----------------------------------------------------------------------------
77// ref-counted object for callbacks
78class JNIMediaRecorderListener: public MediaRecorderListener
79{
80public:
81 JNIMediaRecorderListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
82 ~JNIMediaRecorderListener();
83 void notify(int msg, int ext1, int ext2);
84private:
85 JNIMediaRecorderListener();
86 jclass mClass; // Reference to MediaRecorder class
87 jobject mObject; // Weak ref to MediaRecorder Java object to call on
88};
89
90JNIMediaRecorderListener::JNIMediaRecorderListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
91{
92
93 // Hold onto the MediaRecorder class for use in calling the static method
94 // that posts events to the application thread.
95 jclass clazz = env->GetObjectClass(thiz);
96 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +000097 ALOGE("Can't find android/media/MediaRecorder");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 jniThrowException(env, "java/lang/Exception", NULL);
99 return;
100 }
101 mClass = (jclass)env->NewGlobalRef(clazz);
102
103 // We use a weak reference so the MediaRecorder object can be garbage collected.
104 // The reference is only used as a proxy for callbacks.
105 mObject = env->NewGlobalRef(weak_thiz);
106}
107
108JNIMediaRecorderListener::~JNIMediaRecorderListener()
109{
110 // remove global references
111 JNIEnv *env = AndroidRuntime::getJNIEnv();
112 env->DeleteGlobalRef(mObject);
113 env->DeleteGlobalRef(mClass);
114}
115
116void JNIMediaRecorderListener::notify(int msg, int ext1, int ext2)
117{
Steve Block71f2cf12011-10-20 11:56:00 +0100118 ALOGV("JNIMediaRecorderListener::notify");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119
120 JNIEnv *env = AndroidRuntime::getJNIEnv();
Haitao Feng8bd6a202014-12-31 13:48:08 +0800121 env->CallStaticVoidMethod(mClass, fields.post_event, mObject, msg, ext1, ext2, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122}
123
124// ----------------------------------------------------------------------------
125
126static sp<Surface> get_surface(JNIEnv* env, jobject clazz)
127{
Steve Block71f2cf12011-10-20 11:56:00 +0100128 ALOGV("get_surface");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800129 return android_view_Surface_getSurface(env, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130}
131
Chong Zhang03359162015-05-01 12:50:30 -0700132static sp<PersistentSurface> get_persistentSurface(JNIEnv* env, jobject object)
133{
134 ALOGV("get_persistentSurface");
135 return android_media_MediaCodec_getPersistentInputSurface(env, object);
136}
137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138// Returns true if it throws an exception.
139static bool process_media_recorder_call(JNIEnv *env, status_t opStatus, const char* exception, const char* message)
140{
Steve Block71f2cf12011-10-20 11:56:00 +0100141 ALOGV("process_media_recorder_call");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 if (opStatus == (status_t)INVALID_OPERATION) {
143 jniThrowException(env, "java/lang/IllegalStateException", NULL);
144 return true;
145 } else if (opStatus != (status_t)OK) {
146 jniThrowException(env, exception, message);
147 return true;
148 }
149 return false;
150}
151
Pannag Sanketicac873b2011-07-25 17:20:50 -0700152static sp<MediaRecorder> getMediaRecorder(JNIEnv* env, jobject thiz)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153{
154 Mutex::Autolock l(sLock);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000155 MediaRecorder* const p = (MediaRecorder*)env->GetLongField(thiz, fields.context);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 return sp<MediaRecorder>(p);
157}
158
159static sp<MediaRecorder> setMediaRecorder(JNIEnv* env, jobject thiz, const sp<MediaRecorder>& recorder)
160{
161 Mutex::Autolock l(sLock);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000162 sp<MediaRecorder> old = (MediaRecorder*)env->GetLongField(thiz, fields.context);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 if (recorder.get()) {
164 recorder->incStrong(thiz);
165 }
166 if (old != 0) {
167 old->decStrong(thiz);
168 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000169 env->SetLongField(thiz, fields.context, (jlong)recorder.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 return old;
171}
172
173
174static void android_media_MediaRecorder_setCamera(JNIEnv* env, jobject thiz, jobject camera)
175{
James Dong429a3b52009-05-11 10:58:03 -0700176 // we should not pass a null camera to get_native_camera() call.
177 if (camera == NULL) {
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700178 jniThrowNullPointerException(env, "camera object is a NULL pointer");
James Dong429a3b52009-05-11 10:58:03 -0700179 return;
180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 sp<Camera> c = get_native_camera(env, camera, NULL);
Eino-Ville Talvala6a5b1db2014-07-14 12:02:21 -0700182 if (c == NULL) {
183 // get_native_camera will throw an exception in this case
184 return;
185 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800187 if (mr == NULL) {
188 jniThrowException(env, "java/lang/IllegalStateException", NULL);
189 return;
190 }
Wu-cheng Li42419ce2011-06-01 17:22:24 +0800191 process_media_recorder_call(env, mr->setCamera(c->remote(), c->getRecordingProxy()),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 "java/lang/RuntimeException", "setCamera failed.");
193}
194
195static void
196android_media_MediaRecorder_setVideoSource(JNIEnv *env, jobject thiz, jint vs)
197{
Steve Block71f2cf12011-10-20 11:56:00 +0100198 ALOGV("setVideoSource(%d)", vs);
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700199 if (vs < VIDEO_SOURCE_DEFAULT || vs >= VIDEO_SOURCE_LIST_END) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid video source");
201 return;
202 }
203 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800204 if (mr == NULL) {
205 jniThrowException(env, "java/lang/IllegalStateException", NULL);
206 return;
207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 process_media_recorder_call(env, mr->setVideoSource(vs), "java/lang/RuntimeException", "setVideoSource failed.");
209}
210
211static void
212android_media_MediaRecorder_setAudioSource(JNIEnv *env, jobject thiz, jint as)
213{
Steve Block71f2cf12011-10-20 11:56:00 +0100214 ALOGV("setAudioSource(%d)", as);
Hochi Huang4a7873f12014-10-22 22:10:02 +0800215 if (as < AUDIO_SOURCE_DEFAULT ||
216 (as >= AUDIO_SOURCE_CNT && as != AUDIO_SOURCE_FM_TUNER)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid audio source");
218 return;
219 }
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800222 if (mr == NULL) {
223 jniThrowException(env, "java/lang/IllegalStateException", NULL);
224 return;
225 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 process_media_recorder_call(env, mr->setAudioSource(as), "java/lang/RuntimeException", "setAudioSource failed.");
227}
228
229static void
230android_media_MediaRecorder_setOutputFormat(JNIEnv *env, jobject thiz, jint of)
231{
Steve Block71f2cf12011-10-20 11:56:00 +0100232 ALOGV("setOutputFormat(%d)", of);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 if (of < OUTPUT_FORMAT_DEFAULT || of >= OUTPUT_FORMAT_LIST_END) {
234 jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid output format");
235 return;
236 }
237 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800238 if (mr == NULL) {
239 jniThrowException(env, "java/lang/IllegalStateException", NULL);
240 return;
241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 process_media_recorder_call(env, mr->setOutputFormat(of), "java/lang/RuntimeException", "setOutputFormat failed.");
243}
244
245static void
246android_media_MediaRecorder_setVideoEncoder(JNIEnv *env, jobject thiz, jint ve)
247{
Steve Block71f2cf12011-10-20 11:56:00 +0100248 ALOGV("setVideoEncoder(%d)", ve);
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700249 if (ve < VIDEO_ENCODER_DEFAULT || ve >= VIDEO_ENCODER_LIST_END) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid video encoder");
251 return;
252 }
253 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800254 if (mr == NULL) {
255 jniThrowException(env, "java/lang/IllegalStateException", NULL);
256 return;
257 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 process_media_recorder_call(env, mr->setVideoEncoder(ve), "java/lang/RuntimeException", "setVideoEncoder failed.");
259}
260
261static void
262android_media_MediaRecorder_setAudioEncoder(JNIEnv *env, jobject thiz, jint ae)
263{
Steve Block71f2cf12011-10-20 11:56:00 +0100264 ALOGV("setAudioEncoder(%d)", ae);
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700265 if (ae < AUDIO_ENCODER_DEFAULT || ae >= AUDIO_ENCODER_LIST_END) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid audio encoder");
267 return;
268 }
269 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800270 if (mr == NULL) {
271 jniThrowException(env, "java/lang/IllegalStateException", NULL);
272 return;
273 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 process_media_recorder_call(env, mr->setAudioEncoder(ae), "java/lang/RuntimeException", "setAudioEncoder failed.");
275}
276
277static void
James Dong0fc6bc42010-02-26 19:36:35 -0800278android_media_MediaRecorder_setParameter(JNIEnv *env, jobject thiz, jstring params)
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700279{
Steve Block71f2cf12011-10-20 11:56:00 +0100280 ALOGV("setParameter()");
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700281 if (params == NULL)
282 {
Steve Block3762c312012-01-06 19:20:56 +0000283 ALOGE("Invalid or empty params string. This parameter will be ignored.");
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700284 return;
285 }
286
287 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800288 if (mr == NULL) {
289 jniThrowException(env, "java/lang/IllegalStateException", NULL);
290 return;
291 }
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700292
293 const char* params8 = env->GetStringUTFChars(params, NULL);
294 if (params8 == NULL)
295 {
Steve Block3762c312012-01-06 19:20:56 +0000296 ALOGE("Failed to covert jstring to String8. This parameter will be ignored.");
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700297 return;
298 }
299
300 process_media_recorder_call(env, mr->setParameters(String8(params8)), "java/lang/RuntimeException", "setParameter failed.");
301 env->ReleaseStringUTFChars(params,params8);
302}
303
304static void
Hangyu Kuange176ee12017-01-03 17:25:50 -0800305android_media_MediaRecorder_setOutputFileFD(JNIEnv *env, jobject thiz, jobject fileDescriptor)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306{
Steve Block71f2cf12011-10-20 11:56:00 +0100307 ALOGV("setOutputFile");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 if (fileDescriptor == NULL) {
309 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
310 return;
311 }
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700312 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800314 if (mr == NULL) {
315 jniThrowException(env, "java/lang/IllegalStateException", NULL);
316 return;
317 }
Hangyu Kuange176ee12017-01-03 17:25:50 -0800318 status_t opStatus = mr->setOutputFile(fd);
319 process_media_recorder_call(env, opStatus, "java/io/IOException", "setOutputFile failed.");
320}
321
322static void
323android_media_MediaRecorder_setNextOutputFileFD(JNIEnv *env, jobject thiz, jobject fileDescriptor)
324{
325 ALOGV("setNextOutputFile");
326 if (fileDescriptor == NULL) {
327 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
328 return;
329 }
330 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
331 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
332 if (mr == NULL) {
333 jniThrowException(env, "java/lang/IllegalStateException", NULL);
334 return;
335 }
336 status_t opStatus = mr->setNextOutputFile(fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 process_media_recorder_call(env, opStatus, "java/io/IOException", "setOutputFile failed.");
338}
339
340static void
341android_media_MediaRecorder_setVideoSize(JNIEnv *env, jobject thiz, jint width, jint height)
342{
Steve Block71f2cf12011-10-20 11:56:00 +0100343 ALOGV("setVideoSize(%d, %d)", width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800345 if (mr == NULL) {
346 jniThrowException(env, "java/lang/IllegalStateException", NULL);
347 return;
348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349
350 if (width <= 0 || height <= 0) {
351 jniThrowException(env, "java/lang/IllegalArgumentException", "invalid video size");
352 return;
353 }
354 process_media_recorder_call(env, mr->setVideoSize(width, height), "java/lang/RuntimeException", "setVideoSize failed.");
355}
356
357static void
358android_media_MediaRecorder_setVideoFrameRate(JNIEnv *env, jobject thiz, jint rate)
359{
Steve Block71f2cf12011-10-20 11:56:00 +0100360 ALOGV("setVideoFrameRate(%d)", rate);
James Dongcbe7c542009-07-30 11:16:11 -0700361 if (rate <= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362 jniThrowException(env, "java/lang/IllegalArgumentException", "invalid frame rate");
363 return;
364 }
365 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800366 if (mr == NULL) {
367 jniThrowException(env, "java/lang/IllegalStateException", NULL);
368 return;
369 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 process_media_recorder_call(env, mr->setVideoFrameRate(rate), "java/lang/RuntimeException", "setVideoFrameRate failed.");
371}
372
373static void
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700374android_media_MediaRecorder_setMaxDuration(JNIEnv *env, jobject thiz, jint max_duration_ms)
375{
Steve Block71f2cf12011-10-20 11:56:00 +0100376 ALOGV("setMaxDuration(%d)", max_duration_ms);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700377 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800378 if (mr == NULL) {
379 jniThrowException(env, "java/lang/IllegalStateException", NULL);
380 return;
381 }
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700382
383 char params[64];
384 sprintf(params, "max-duration=%d", max_duration_ms);
385
386 process_media_recorder_call(env, mr->setParameters(String8(params)), "java/lang/RuntimeException", "setMaxDuration failed.");
387}
388
389static void
The Android Open Source Project10592532009-03-18 17:39:46 -0700390android_media_MediaRecorder_setMaxFileSize(
391 JNIEnv *env, jobject thiz, jlong max_filesize_bytes)
392{
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +0100393 ALOGV("setMaxFileSize(%lld)", (long long)max_filesize_bytes);
The Android Open Source Project10592532009-03-18 17:39:46 -0700394 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800395 if (mr == NULL) {
396 jniThrowException(env, "java/lang/IllegalStateException", NULL);
397 return;
398 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700399
400 char params[64];
Mark Salyzyn85394032014-04-16 10:28:37 -0700401 sprintf(params, "max-filesize=%" PRId64, max_filesize_bytes);
The Android Open Source Project10592532009-03-18 17:39:46 -0700402
403 process_media_recorder_call(env, mr->setParameters(String8(params)), "java/lang/RuntimeException", "setMaxFileSize failed.");
404}
405
406static void
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407android_media_MediaRecorder_prepare(JNIEnv *env, jobject thiz)
408{
Steve Block71f2cf12011-10-20 11:56:00 +0100409 ALOGV("prepare");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800411 if (mr == NULL) {
412 jniThrowException(env, "java/lang/IllegalStateException", NULL);
413 return;
414 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415
416 jobject surface = env->GetObjectField(thiz, fields.surface);
417 if (surface != NULL) {
James Dong457d5ae2010-06-09 10:19:33 -0700418 const sp<Surface> native_surface = get_surface(env, surface);
James Dongd790c6482010-08-12 10:18:01 -0700419
420 // The application may misbehave and
421 // the preview surface becomes unavailable
422 if (native_surface.get() == 0) {
Steve Block3762c312012-01-06 19:20:56 +0000423 ALOGE("Application lost the surface");
James Dongd790c6482010-08-12 10:18:01 -0700424 jniThrowException(env, "java/io/IOException", "invalid preview surface");
425 return;
426 }
427
Mathias Agopianbfcae352013-02-14 15:32:50 -0800428 ALOGI("prepare: surface=%p", native_surface.get());
Mathias Agopian4a05f432013-03-12 18:43:34 -0700429 if (process_media_recorder_call(env, mr->setPreviewSurface(native_surface->getIGraphicBufferProducer()), "java/lang/RuntimeException", "setPreviewSurface failed.")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 return;
431 }
432 }
433 process_media_recorder_call(env, mr->prepare(), "java/io/IOException", "prepare failed.");
434}
435
Ashok Bhat075e9a12014-01-06 13:45:09 +0000436static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437android_media_MediaRecorder_native_getMaxAmplitude(JNIEnv *env, jobject thiz)
438{
Steve Block71f2cf12011-10-20 11:56:00 +0100439 ALOGV("getMaxAmplitude");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800441 if (mr == NULL) {
442 jniThrowException(env, "java/lang/IllegalStateException", NULL);
443 return 0;
444 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 int result = 0;
446 process_media_recorder_call(env, mr->getMaxAmplitude(&result), "java/lang/RuntimeException", "getMaxAmplitude failed.");
Ashok Bhat075e9a12014-01-06 13:45:09 +0000447 return (jint) result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448}
449
Chong Zhang83cc9942014-01-02 12:10:04 -0800450static jobject
451android_media_MediaRecorder_getSurface(JNIEnv *env, jobject thiz)
452{
453 ALOGV("getSurface");
454 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800455 if (mr == NULL) {
456 jniThrowException(env, "java/lang/IllegalStateException", NULL);
457 return NULL;
458 }
Chong Zhang83cc9942014-01-02 12:10:04 -0800459
460 sp<IGraphicBufferProducer> bufferProducer = mr->querySurfaceMediaSourceFromMediaServer();
461 if (bufferProducer == NULL) {
462 jniThrowException(
463 env,
464 "java/lang/IllegalStateException",
465 "failed to get surface");
466 return NULL;
467 }
468
469 // Wrap the IGBP in a Java-language Surface.
470 return android_view_Surface_createFromIGraphicBufferProducer(env,
471 bufferProducer);
472}
473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474static void
475android_media_MediaRecorder_start(JNIEnv *env, jobject thiz)
476{
Steve Block71f2cf12011-10-20 11:56:00 +0100477 ALOGV("start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800479 if (mr == NULL) {
480 jniThrowException(env, "java/lang/IllegalStateException", NULL);
481 return;
482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 process_media_recorder_call(env, mr->start(), "java/lang/RuntimeException", "start failed.");
484}
485
486static void
487android_media_MediaRecorder_stop(JNIEnv *env, jobject thiz)
488{
Steve Block71f2cf12011-10-20 11:56:00 +0100489 ALOGV("stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800491 if (mr == NULL) {
492 jniThrowException(env, "java/lang/IllegalStateException", NULL);
493 return;
494 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 process_media_recorder_call(env, mr->stop(), "java/lang/RuntimeException", "stop failed.");
496}
497
498static void
Wonsik Kim83995062015-08-31 17:49:21 +0900499android_media_MediaRecorder_pause(JNIEnv *env, jobject thiz)
500{
501 ALOGV("pause");
502 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800503 if (mr == NULL) {
504 jniThrowException(env, "java/lang/IllegalStateException", NULL);
505 return;
506 }
Wonsik Kim83995062015-08-31 17:49:21 +0900507 process_media_recorder_call(env, mr->pause(), "java/lang/RuntimeException", "pause failed.");
508}
509
510static void
511android_media_MediaRecorder_resume(JNIEnv *env, jobject thiz)
512{
513 ALOGV("resume");
514 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800515 if (mr == NULL) {
516 jniThrowException(env, "java/lang/IllegalStateException", NULL);
517 return;
518 }
Wonsik Kim83995062015-08-31 17:49:21 +0900519 process_media_recorder_call(env, mr->resume(), "java/lang/RuntimeException", "resume failed.");
520}
521
522static void
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523android_media_MediaRecorder_native_reset(JNIEnv *env, jobject thiz)
524{
Steve Block71f2cf12011-10-20 11:56:00 +0100525 ALOGV("native_reset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800527 if (mr == NULL) {
528 jniThrowException(env, "java/lang/IllegalStateException", NULL);
529 return;
530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 process_media_recorder_call(env, mr->reset(), "java/lang/RuntimeException", "native_reset failed.");
532}
533
534static void
535android_media_MediaRecorder_release(JNIEnv *env, jobject thiz)
536{
Steve Block71f2cf12011-10-20 11:56:00 +0100537 ALOGV("release");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 sp<MediaRecorder> mr = setMediaRecorder(env, thiz, 0);
539 if (mr != NULL) {
540 mr->setListener(NULL);
The Android Open Source Project4df24232009-03-05 14:34:35 -0800541 mr->release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 }
543}
544
Marco Nelissen4935d052009-08-03 11:12:58 -0700545// This function gets some field IDs, which in turn causes class initialization.
546// It is called from a static block in MediaRecorder, which won't run until the
547// first time an instance of this class is used.
548static void
549android_media_MediaRecorder_native_init(JNIEnv *env)
550{
551 jclass clazz;
552
553 clazz = env->FindClass("android/media/MediaRecorder");
554 if (clazz == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700555 return;
556 }
557
Ashok Bhat075e9a12014-01-06 13:45:09 +0000558 fields.context = env->GetFieldID(clazz, "mNativeContext", "J");
Marco Nelissen4935d052009-08-03 11:12:58 -0700559 if (fields.context == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700560 return;
561 }
562
563 fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
564 if (fields.surface == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700565 return;
566 }
567
568 jclass surface = env->FindClass("android/view/Surface");
569 if (surface == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700570 return;
571 }
572
Marco Nelissen4935d052009-08-03 11:12:58 -0700573 fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
574 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
575 if (fields.post_event == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700576 return;
577 }
jiabin589f6a22018-01-23 12:22:47 -0800578
579 clazz = env->FindClass("java/util/ArrayList");
580 if (clazz == NULL) {
581 return;
582 }
583 gArrayListFields.add = env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z");
584 gArrayListFields.classId = static_cast<jclass>(env->NewGlobalRef(clazz));
Marco Nelissen4935d052009-08-03 11:12:58 -0700585}
586
587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588static void
Eino-Ville Talvala788717c2013-02-15 18:30:15 -0800589android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
Svet Ganovfa5ecdc2015-04-28 12:03:28 -0700590 jstring packageName, jstring opPackageName)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591{
Steve Block71f2cf12011-10-20 11:56:00 +0100592 ALOGV("setup");
Eino-Ville Talvala788717c2013-02-15 18:30:15 -0800593
Svet Ganovfa5ecdc2015-04-28 12:03:28 -0700594 ScopedUtfChars opPackageNameStr(env, opPackageName);
595
596 sp<MediaRecorder> mr = new MediaRecorder(String16(opPackageNameStr.c_str()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 if (mr == NULL) {
598 jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
599 return;
600 }
601 if (mr->initCheck() != NO_ERROR) {
James Dong8d3b9102010-09-09 18:43:48 -0700602 jniThrowException(env, "java/lang/RuntimeException", "Unable to initialize media recorder");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 return;
604 }
605
606 // create new listener and give it to MediaRecorder
607 sp<JNIMediaRecorderListener> listener = new JNIMediaRecorderListener(env, thiz, weak_this);
608 mr->setListener(listener);
609
Dan Albert66987492014-11-20 11:41:21 -0800610 // Convert client name jstring to String16
611 const char16_t *rawClientName = reinterpret_cast<const char16_t*>(
612 env->GetStringChars(packageName, NULL));
Eino-Ville Talvala788717c2013-02-15 18:30:15 -0800613 jsize rawClientNameLen = env->GetStringLength(packageName);
614 String16 clientName(rawClientName, rawClientNameLen);
Dan Albert66987492014-11-20 11:41:21 -0800615 env->ReleaseStringChars(packageName,
616 reinterpret_cast<const jchar*>(rawClientName));
Eino-Ville Talvala788717c2013-02-15 18:30:15 -0800617
618 // pass client package name for permissions tracking
619 mr->setClientName(clientName);
620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 setMediaRecorder(env, thiz, mr);
622}
623
624static void
625android_media_MediaRecorder_native_finalize(JNIEnv *env, jobject thiz)
626{
Steve Block71f2cf12011-10-20 11:56:00 +0100627 ALOGV("finalize");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 android_media_MediaRecorder_release(env, thiz);
629}
630
Chong Zhang9560ddb2015-05-13 10:25:29 -0700631void android_media_MediaRecorder_setInputSurface(
Chong Zhang03359162015-05-01 12:50:30 -0700632 JNIEnv* env, jobject thiz, jobject object) {
Chong Zhang9560ddb2015-05-13 10:25:29 -0700633 ALOGV("android_media_MediaRecorder_setInputSurface");
Chong Zhang03359162015-05-01 12:50:30 -0700634
635 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
Robert Shih04167d32016-01-26 15:25:26 -0800636 if (mr == NULL) {
637 jniThrowException(env, "java/lang/IllegalStateException", NULL);
638 return;
639 }
Chong Zhang03359162015-05-01 12:50:30 -0700640
641 sp<PersistentSurface> persistentSurface = get_persistentSurface(env, object);
642
Chong Zhang9560ddb2015-05-13 10:25:29 -0700643 process_media_recorder_call(env, mr->setInputSurface(persistentSurface),
644 "java/lang/IllegalArgumentException", "native_setInputSurface failed.");
Chong Zhang03359162015-05-01 12:50:30 -0700645}
646
Ray Essickb0bd62f2017-02-12 19:22:48 -0800647static jobject
Ray Essickf2d0e402017-03-09 10:17:51 -0800648android_media_MediaRecorder_native_getMetrics(JNIEnv *env, jobject thiz)
Ray Essickb0bd62f2017-02-12 19:22:48 -0800649{
Ray Essickf2d0e402017-03-09 10:17:51 -0800650 ALOGV("android_media_MediaRecorder_native_getMetrics");
Ray Essickb0bd62f2017-02-12 19:22:48 -0800651
652 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
653 if (mr == NULL) {
654 jniThrowException(env, "java/lang/IllegalStateException", NULL);
655 return NULL;
656 }
657
658 // get what we have for the metrics from the codec
659 Parcel reply;
660 status_t err = mr->getMetrics(&reply);
661 if (err != OK) {
662 ALOGE("getMetrics failed");
663 return (jobject) NULL;
664 }
665
666 // build and return the Bundle
Ray Essicke9b9c982019-01-28 20:34:42 -0800667 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create());
Ray Essickb0bd62f2017-02-12 19:22:48 -0800668 item->readFromParcel(reply);
Ray Essicke9b9c982019-01-28 20:34:42 -0800669 jobject mybundle = MediaMetricsJNI::writeMetricsToBundle(env, item.get(), NULL);
Ray Essickb0bd62f2017-02-12 19:22:48 -0800670
Ray Essickb0bd62f2017-02-12 19:22:48 -0800671 return mybundle;
Ray Essickb0bd62f2017-02-12 19:22:48 -0800672}
jiabinfe3e6022017-10-24 11:34:32 -0700673
674static jboolean
675android_media_MediaRecorder_setInputDevice(JNIEnv *env, jobject thiz, jint device_id)
676{
677 ALOGV("android_media_MediaRecorder_setInputDevice");
678
679 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
680 if (mr == NULL) {
681 jniThrowException(env, "java/lang/IllegalStateException", NULL);
682 return false;
683 }
684
685 if (process_media_recorder_call(env, mr->setInputDevice(device_id),
686 "java/lang/RuntimeException", "setInputDevice failed.")) {
687 return false;
688 }
689 return true;
690}
691
692static jint
693android_media_MediaRecorder_getRoutedDeviceId(JNIEnv *env, jobject thiz)
694{
695 ALOGV("android_media_MediaRecorder_getRoutedDeviceId");
696
697 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
698 if (mr == NULL) {
699 jniThrowException(env, "java/lang/IllegalStateException", NULL);
700 return AUDIO_PORT_HANDLE_NONE;
701 }
702
703 audio_port_handle_t deviceId;
704 process_media_recorder_call(env, mr->getRoutedDeviceId(&deviceId),
705 "java/lang/RuntimeException", "getRoutedDeviceId failed.");
706 return (jint) deviceId;
707}
708
709static void
710android_media_MediaRecorder_enableDeviceCallback(JNIEnv *env, jobject thiz, jboolean enabled)
711{
712 ALOGV("android_media_MediaRecorder_enableDeviceCallback %d", enabled);
713
714 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
715 if (mr == NULL) {
716 jniThrowException(env, "java/lang/IllegalStateException", NULL);
717 return;
718 }
719
720 process_media_recorder_call(env, mr->enableAudioDeviceCallback(enabled),
721 "java/lang/RuntimeException", "enableDeviceCallback failed.");
722}
jiabin589f6a22018-01-23 12:22:47 -0800723
724static jint
725android_media_MediaRecord_getActiveMicrophones(JNIEnv *env,
726 jobject thiz, jobject jActiveMicrophones) {
727 if (jActiveMicrophones == NULL) {
728 ALOGE("jActiveMicrophones is null");
729 return (jint)AUDIO_JAVA_BAD_VALUE;
730 }
731 if (!env->IsInstanceOf(jActiveMicrophones, gArrayListFields.classId)) {
732 ALOGE("getActiveMicrophones not an arraylist");
733 return (jint)AUDIO_JAVA_BAD_VALUE;
734 }
735
736 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
737 if (mr == NULL) {
738 jniThrowException(env, "java/lang/IllegalStateException", NULL);
739 return (jint)AUDIO_JAVA_NO_INIT;
740 }
741
742 jint jStatus = AUDIO_JAVA_SUCCESS;
743 std::vector<media::MicrophoneInfo> activeMicrophones;
744 status_t status = mr->getActiveMicrophones(&activeMicrophones);
745 if (status != NO_ERROR) {
746 ALOGE_IF(status != NO_ERROR, "MediaRecorder::getActiveMicrophones error %d", status);
747 jStatus = nativeToJavaStatus(status);
748 return jStatus;
749 }
750
751 for (size_t i = 0; i < activeMicrophones.size(); i++) {
752 jobject jMicrophoneInfo;
753 jStatus = convertMicrophoneInfoFromNative(env, &jMicrophoneInfo, &activeMicrophones[i]);
754 if (jStatus != AUDIO_JAVA_SUCCESS) {
755 return jStatus;
756 }
757 env->CallBooleanMethod(jActiveMicrophones, gArrayListFields.add, jMicrophoneInfo);
758 env->DeleteLocalRef(jMicrophoneInfo);
759 }
760 return jStatus;
761}
Eric Laurent333dfad2018-12-14 17:22:22 -0800762
Paul McLeanb6a7bde2019-02-25 10:30:40 -0700763static jint android_media_MediaRecord_setMicrophoneDirection(
764 JNIEnv *env, jobject thiz, jint direction) {
765 ALOGV("setMicrophoneDirection(%d)", direction);
766 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
767 if (mr == NULL) {
768 jniThrowException(env, "java/lang/IllegalStateException", NULL);
769 return (jint)AUDIO_JAVA_NO_INIT;
770 }
771
772 jint jStatus = AUDIO_JAVA_SUCCESS;
773 status_t status =
774 mr->setMicrophoneDirection(static_cast<audio_microphone_direction_t>(direction));
775 if (status != NO_ERROR) {
776 jStatus = nativeToJavaStatus(status);
777 }
778
779 return jStatus;
780}
781
782static jint android_media_MediaRecord_setMicrophoneFieldDimension(
783 JNIEnv *env, jobject thiz, jfloat zoom) {
784 ALOGV("setMicrophoneFieldDimension(%f)", zoom);
785 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
786 if (mr == NULL) {
787 jniThrowException(env, "java/lang/IllegalStateException", NULL);
788 return (jint)AUDIO_JAVA_NO_INIT;
789 }
790
791 jint jStatus = AUDIO_JAVA_SUCCESS;
792 status_t status = mr->setMicrophoneFieldDimension(zoom);
793 if (status != NO_ERROR) {
794 jStatus = nativeToJavaStatus(status);
795 }
796
797 return jStatus;
798
799}
800
Eric Laurent333dfad2018-12-14 17:22:22 -0800801static jint android_media_MediaRecord_getPortId(JNIEnv *env, jobject thiz) {
802 sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
803 if (mr == NULL) {
804 jniThrowException(env, "java/lang/IllegalStateException", NULL);
805 return (jint)AUDIO_PORT_HANDLE_NONE;
806 }
807
808 audio_port_handle_t portId;
809 process_media_recorder_call(env, mr->getPortId(&portId),
810 "java/lang/RuntimeException", "getPortId failed.");
811 return (jint)portId;
812}
813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814// ----------------------------------------------------------------------------
815
Daniel Micay76f6a862015-09-19 17:31:01 -0400816static const JNINativeMethod gMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 {"setCamera", "(Landroid/hardware/Camera;)V", (void *)android_media_MediaRecorder_setCamera},
818 {"setVideoSource", "(I)V", (void *)android_media_MediaRecorder_setVideoSource},
819 {"setAudioSource", "(I)V", (void *)android_media_MediaRecorder_setAudioSource},
820 {"setOutputFormat", "(I)V", (void *)android_media_MediaRecorder_setOutputFormat},
821 {"setVideoEncoder", "(I)V", (void *)android_media_MediaRecorder_setVideoEncoder},
822 {"setAudioEncoder", "(I)V", (void *)android_media_MediaRecorder_setAudioEncoder},
James Dong0fc6bc42010-02-26 19:36:35 -0800823 {"setParameter", "(Ljava/lang/String;)V", (void *)android_media_MediaRecorder_setParameter},
Hangyu Kuange176ee12017-01-03 17:25:50 -0800824 {"_setOutputFile", "(Ljava/io/FileDescriptor;)V", (void *)android_media_MediaRecorder_setOutputFileFD},
825 {"_setNextOutputFile", "(Ljava/io/FileDescriptor;)V", (void *)android_media_MediaRecorder_setNextOutputFileFD},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 {"setVideoSize", "(II)V", (void *)android_media_MediaRecorder_setVideoSize},
827 {"setVideoFrameRate", "(I)V", (void *)android_media_MediaRecorder_setVideoFrameRate},
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700828 {"setMaxDuration", "(I)V", (void *)android_media_MediaRecorder_setMaxDuration},
The Android Open Source Project10592532009-03-18 17:39:46 -0700829 {"setMaxFileSize", "(J)V", (void *)android_media_MediaRecorder_setMaxFileSize},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 {"_prepare", "()V", (void *)android_media_MediaRecorder_prepare},
Chong Zhang83cc9942014-01-02 12:10:04 -0800831 {"getSurface", "()Landroid/view/Surface;", (void *)android_media_MediaRecorder_getSurface},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 {"getMaxAmplitude", "()I", (void *)android_media_MediaRecorder_native_getMaxAmplitude},
833 {"start", "()V", (void *)android_media_MediaRecorder_start},
834 {"stop", "()V", (void *)android_media_MediaRecorder_stop},
Wonsik Kim83995062015-08-31 17:49:21 +0900835 {"pause", "()V", (void *)android_media_MediaRecorder_pause},
836 {"resume", "()V", (void *)android_media_MediaRecorder_resume},
Marco Nelissen4935d052009-08-03 11:12:58 -0700837 {"native_reset", "()V", (void *)android_media_MediaRecorder_native_reset},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838 {"release", "()V", (void *)android_media_MediaRecorder_release},
Marco Nelissen4935d052009-08-03 11:12:58 -0700839 {"native_init", "()V", (void *)android_media_MediaRecorder_native_init},
Svet Ganovfa5ecdc2015-04-28 12:03:28 -0700840 {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V",
841 (void *)android_media_MediaRecorder_native_setup},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 {"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize},
Chong Zhang9560ddb2015-05-13 10:25:29 -0700843 {"native_setInputSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_setInputSurface },
Ray Essickb0bd62f2017-02-12 19:22:48 -0800844
Ray Essick10353e32017-04-14 10:22:55 -0700845 {"native_getMetrics", "()Landroid/os/PersistableBundle;", (void *)android_media_MediaRecorder_native_getMetrics},
jiabinfe3e6022017-10-24 11:34:32 -0700846
847 {"native_setInputDevice", "(I)Z", (void *)android_media_MediaRecorder_setInputDevice},
848 {"native_getRoutedDeviceId", "()I", (void *)android_media_MediaRecorder_getRoutedDeviceId},
jiabin589f6a22018-01-23 12:22:47 -0800849 {"native_enableDeviceCallback", "(Z)V", (void *)android_media_MediaRecorder_enableDeviceCallback},
850
851 {"native_getActiveMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_MediaRecord_getActiveMicrophones},
Eric Laurent333dfad2018-12-14 17:22:22 -0800852 {"native_getPortId", "()I", (void *)android_media_MediaRecord_getPortId},
Paul McLeanb6a7bde2019-02-25 10:30:40 -0700853 {"native_setMicrophoneDirection", "(I)I", (void *)android_media_MediaRecord_setMicrophoneDirection},
854 {"native_setMicrophoneFieldDimension", "(F)I", (void *)android_media_MediaRecord_setMicrophoneFieldDimension},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855};
856
Marco Nelissen4935d052009-08-03 11:12:58 -0700857// This function only registers the native methods, and is called from
858// JNI_OnLoad in android_media_MediaPlayer.cpp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859int register_android_media_MediaRecorder(JNIEnv *env)
860{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 return AndroidRuntime::registerNativeMethods(env,
862 "android/media/MediaRecorder", gMethods, NELEM(gMethods));
863}