blob: 3a25e67f9acaffd97104f3de18497e4801e28647 [file] [log] [blame]
Glenn Kastenb3db2132012-01-19 08:59:58 -08001/*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002**
3** Copyright 2006, 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
Eric Laurent3a241992014-05-19 19:33:26 -070018//#define LOG_NDEBUG 0
19
Eric Laurentb69681c2014-05-19 19:02:51 -070020#define LOG_TAG "AudioSystem-JNI"
Glenn Kastenc81d31c2012-03-13 14:46:23 -070021#include <utils/Log.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
Andy Hung737d9fb2016-08-16 18:38:49 -070023#include <sstream>
jiabinc0f49442018-01-05 10:23:50 -080024#include <vector>
Glenn Kastenc81d31c2012-03-13 14:46:23 -070025#include <jni.h>
Steven Moreland2279b252017-07-19 09:50:45 -070026#include <nativehelper/JNIHelp.h>
Andreas Gampeed6b9df2014-11-20 22:02:20 -080027#include "core_jni_helpers.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
Mikhail Naganova00883d2019-04-18 12:36:27 -070029#include <audiomanager/AudioManager.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030#include <media/AudioSystem.h>
Eric Laurent7f5eb9f2014-12-01 19:36:30 -080031#include <media/AudioPolicy.h>
jiabinc0f49442018-01-05 10:23:50 -080032#include <media/MicrophoneInfo.h>
Andy Hung737d9fb2016-08-16 18:38:49 -070033#include <nativehelper/ScopedLocalRef.h>
Dima Zavin34bb4192011-05-11 14:15:23 -070034#include <system/audio.h>
Dima Zavin290029d2011-06-13 18:16:26 -070035#include <system/audio_policy.h>
Eric Laurentc7a0cdf2018-11-30 12:16:52 -080036#include "android_media_AudioEffectDescriptor.h"
Eric Laurentb69681c2014-05-19 19:02:51 -070037#include "android_media_AudioFormat.h"
38#include "android_media_AudioErrors.h"
jiabinc0f49442018-01-05 10:23:50 -080039#include "android_media_MicrophoneInfo.h"
François Gaffieb4691282018-07-09 13:07:32 +020040#include "android_media_AudioAttributes.h"
Dima Zavin24fc2fb2011-04-19 22:30:36 -070041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042// ----------------------------------------------------------------------------
43
44using namespace android;
45
Glenn Kastened0079d2011-04-04 10:50:50 -070046static const char* const kClassPathName = "android/media/AudioSystem";
47
Eric Laurentb69681c2014-05-19 19:02:51 -070048static jclass gArrayListClass;
49static struct {
50 jmethodID add;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -080051 jmethodID toArray;
Eric Laurentb69681c2014-05-19 19:02:51 -070052} gArrayListMethods;
53
jiabin39940752018-04-02 18:18:45 -070054static jclass gBooleanClass;
55static jmethodID gBooleanCstor;
56
57static jclass gIntegerClass;
58static jmethodID gIntegerCstor;
59
60static jclass gMapClass;
61static jmethodID gMapPut;
62
Eric Laurentb69681c2014-05-19 19:02:51 -070063static jclass gAudioHandleClass;
64static jmethodID gAudioHandleCstor;
65static struct {
66 jfieldID mId;
67} gAudioHandleFields;
68
69static jclass gAudioPortClass;
70static jmethodID gAudioPortCstor;
71static struct {
72 jfieldID mHandle;
73 jfieldID mRole;
74 jfieldID mGains;
75 jfieldID mActiveConfig;
Hongwei Wangf44a5682018-08-24 10:37:56 -070076 // Valid only if an AudioDevicePort
77 jfieldID mType;
78 jfieldID mAddress;
Eric Laurentb69681c2014-05-19 19:02:51 -070079 // other fields unused by JNI
80} gAudioPortFields;
81
82static jclass gAudioPortConfigClass;
83static jmethodID gAudioPortConfigCstor;
84static struct {
85 jfieldID mPort;
86 jfieldID mSamplingRate;
87 jfieldID mChannelMask;
88 jfieldID mFormat;
89 jfieldID mGain;
Eric Laurent3a241992014-05-19 19:33:26 -070090 jfieldID mConfigMask;
Eric Laurentb69681c2014-05-19 19:02:51 -070091} gAudioPortConfigFields;
92
93static jclass gAudioDevicePortClass;
94static jmethodID gAudioDevicePortCstor;
95
96static jclass gAudioDevicePortConfigClass;
97static jmethodID gAudioDevicePortConfigCstor;
98
99static jclass gAudioMixPortClass;
100static jmethodID gAudioMixPortCstor;
101
102static jclass gAudioMixPortConfigClass;
103static jmethodID gAudioMixPortConfigCstor;
104
105static jclass gAudioGainClass;
106static jmethodID gAudioGainCstor;
107
108static jclass gAudioGainConfigClass;
109static jmethodID gAudioGainConfigCstor;
110static struct {
111 jfieldID mIndex;
112 jfieldID mMode;
113 jfieldID mChannelMask;
114 jfieldID mValues;
115 jfieldID mRampDurationMs;
116 // other fields unused by JNI
117} gAudioGainConfigFields;
118
119static jclass gAudioPatchClass;
120static jmethodID gAudioPatchCstor;
121static struct {
122 jfieldID mHandle;
123 // other fields unused by JNI
124} gAudioPatchFields;
125
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800126static jclass gAudioMixClass;
127static struct {
128 jfieldID mRule;
129 jfieldID mFormat;
130 jfieldID mRouteFlags;
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -0700131 jfieldID mDeviceType;
132 jfieldID mDeviceAddress;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800133 jfieldID mMixType;
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700134 jfieldID mCallbackFlags;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800135} gAudioMixFields;
136
137static jclass gAudioFormatClass;
138static struct {
139 jfieldID mEncoding;
140 jfieldID mSampleRate;
141 jfieldID mChannelMask;
142 // other fields unused by JNI
143} gAudioFormatFields;
144
145static jclass gAudioMixingRuleClass;
146static struct {
147 jfieldID mCriteria;
Kevin Rocarda3a4bbb2019-03-07 18:29:48 -0800148 jfieldID mAllowPrivilegedPlaybackCapture;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800149 // other fields unused by JNI
150} gAudioMixingRuleFields;
151
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800152static jclass gAudioMixMatchCriterionClass;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800153static struct {
154 jfieldID mAttr;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800155 jfieldID mIntProp;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800156 jfieldID mRule;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800157} gAudioMixMatchCriterionFields;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800158
Eric Laurent700e7342014-05-02 18:33:15 -0700159static const char* const kEventHandlerClassPathName =
160 "android/media/AudioPortEventHandler";
Eric Laurent2615afb2015-03-25 14:51:08 -0700161static struct {
162 jfieldID mJniCallback;
163} gEventHandlerFields;
164static struct {
165 jmethodID postEventFromNative;
166} gAudioPortEventHandlerMethods;
167
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700168static struct {
169 jmethodID postDynPolicyEventFromNative;
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800170 jmethodID postRecordConfigEventFromNative;
171} gAudioPolicyEventHandlerMethods;
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700172
Paul McLeanb3ae6d92018-11-05 15:16:59 -0700173//
174// JNI Initialization for OpenSLES routing
175//
176jmethodID gMidAudioTrackRoutingProxy_ctor;
177jmethodID gMidAudioTrackRoutingProxy_release;
178jmethodID gMidAudioRecordRoutingProxy_ctor;
179jmethodID gMidAudioRecordRoutingProxy_release;
180
181jclass gClsAudioTrackRoutingProxy;
182jclass gClsAudioRecordRoutingProxy;
183
Eric Laurent2615afb2015-03-25 14:51:08 -0700184static Mutex gLock;
Eric Laurentb69681c2014-05-19 19:02:51 -0700185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186enum AudioError {
187 kAudioStatusOk = 0,
188 kAudioStatusError = 1,
189 kAudioStatusMediaServerDied = 100
190};
191
Eric Laurent700e7342014-05-02 18:33:15 -0700192enum {
193 AUDIOPORT_EVENT_PORT_LIST_UPDATED = 1,
194 AUDIOPORT_EVENT_PATCH_LIST_UPDATED = 2,
195 AUDIOPORT_EVENT_SERVICE_DIED = 3,
196};
197
Eric Laurentb69681c2014-05-19 19:02:51 -0700198#define MAX_PORT_GENERATION_SYNC_ATTEMPTS 5
199
Eric Laurent700e7342014-05-02 18:33:15 -0700200// ----------------------------------------------------------------------------
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700201// ref-counted object for audio port callbacks
Eric Laurent700e7342014-05-02 18:33:15 -0700202class JNIAudioPortCallback: public AudioSystem::AudioPortCallback
203{
204public:
205 JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
206 ~JNIAudioPortCallback();
207
208 virtual void onAudioPortListUpdate();
209 virtual void onAudioPatchListUpdate();
210 virtual void onServiceDied();
211
212private:
213 void sendEvent(int event);
214
Eric Laurent2615afb2015-03-25 14:51:08 -0700215 jclass mClass; // Reference to AudioPortEventHandler class
216 jobject mObject; // Weak ref to AudioPortEventHandler Java object to call on
Eric Laurent700e7342014-05-02 18:33:15 -0700217};
218
219JNIAudioPortCallback::JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
220{
221
Eric Laurent2615afb2015-03-25 14:51:08 -0700222 // Hold onto the AudioPortEventHandler class for use in calling the static method
Eric Laurent700e7342014-05-02 18:33:15 -0700223 // that posts events to the application thread.
224 jclass clazz = env->GetObjectClass(thiz);
225 if (clazz == NULL) {
226 ALOGE("Can't find class %s", kEventHandlerClassPathName);
227 return;
228 }
229 mClass = (jclass)env->NewGlobalRef(clazz);
230
Eric Laurent2615afb2015-03-25 14:51:08 -0700231 // We use a weak reference so the AudioPortEventHandler object can be garbage collected.
Eric Laurent700e7342014-05-02 18:33:15 -0700232 // The reference is only used as a proxy for callbacks.
233 mObject = env->NewGlobalRef(weak_thiz);
234}
235
236JNIAudioPortCallback::~JNIAudioPortCallback()
237{
238 // remove global references
239 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent449c5882014-11-12 11:07:48 -0800240 if (env == NULL) {
241 return;
242 }
Eric Laurent700e7342014-05-02 18:33:15 -0700243 env->DeleteGlobalRef(mObject);
244 env->DeleteGlobalRef(mClass);
245}
246
247void JNIAudioPortCallback::sendEvent(int event)
248{
249 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent449c5882014-11-12 11:07:48 -0800250 if (env == NULL) {
251 return;
252 }
Eric Laurent2615afb2015-03-25 14:51:08 -0700253 env->CallStaticVoidMethod(mClass, gAudioPortEventHandlerMethods.postEventFromNative, mObject,
Eric Laurent700e7342014-05-02 18:33:15 -0700254 event, 0, 0, NULL);
255 if (env->ExceptionCheck()) {
256 ALOGW("An exception occurred while notifying an event.");
257 env->ExceptionClear();
258 }
259}
260
261void JNIAudioPortCallback::onAudioPortListUpdate()
262{
263 sendEvent(AUDIOPORT_EVENT_PORT_LIST_UPDATED);
264}
265
266void JNIAudioPortCallback::onAudioPatchListUpdate()
267{
268 sendEvent(AUDIOPORT_EVENT_PATCH_LIST_UPDATED);
269}
270
271void JNIAudioPortCallback::onServiceDied()
272{
273 sendEvent(AUDIOPORT_EVENT_SERVICE_DIED);
274}
275
Eric Laurent2615afb2015-03-25 14:51:08 -0700276static sp<JNIAudioPortCallback> setJniCallback(JNIEnv* env,
277 jobject thiz,
278 const sp<JNIAudioPortCallback>& callback)
279{
280 Mutex::Autolock l(gLock);
281 sp<JNIAudioPortCallback> old =
282 (JNIAudioPortCallback*)env->GetLongField(thiz, gEventHandlerFields.mJniCallback);
283 if (callback.get()) {
284 callback->incStrong((void*)setJniCallback);
285 }
286 if (old != 0) {
287 old->decStrong((void*)setJniCallback);
288 }
289 env->SetLongField(thiz, gEventHandlerFields.mJniCallback, (jlong)callback.get());
290 return old;
291}
292
Mikhail Naganov5caa57d2018-04-02 10:35:45 -0700293#define check_AudioSystem_Command(status) _check_AudioSystem_Command(__func__, (status))
294
295static int _check_AudioSystem_Command(const char* caller, status_t status)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296{
Mikhail Naganov5caa57d2018-04-02 10:35:45 -0700297 ALOGE_IF(status, "Command failed for %s: %d", caller, status);
Eric Laurentdfb881f2013-07-18 14:41:39 -0700298 switch (status) {
299 case DEAD_OBJECT:
300 return kAudioStatusMediaServerDied;
301 case NO_ERROR:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302 return kAudioStatusOk;
Eric Laurentdfb881f2013-07-18 14:41:39 -0700303 default:
304 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 }
Eric Laurentdfb881f2013-07-18 14:41:39 -0700306 return kAudioStatusError;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307}
308
Ashok Bhat075e9a12014-01-06 13:45:09 +0000309static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
311{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000312 return (jint) check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313}
314
315static jboolean
316android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
317{
318 bool state = false;
319 AudioSystem::isMicrophoneMuted(&state);
320 return state;
321}
322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323static jboolean
Eric Laurent25101b02011-02-02 09:33:30 -0800324android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325{
326 bool state = false;
Glenn Kastenbc1d77b2012-01-12 16:38:12 -0800327 AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 return state;
329}
330
Jean-Michel Trivid6770542012-10-10 12:03:41 -0700331static jboolean
Jean-Michel Trivi679d5042013-02-04 16:24:09 -0800332android_media_AudioSystem_isStreamActiveRemotely(JNIEnv *env, jobject thiz, jint stream,
333 jint inPastMs)
334{
335 bool state = false;
336 AudioSystem::isStreamActiveRemotely((audio_stream_type_t) stream, &state, inPastMs);
337 return state;
338}
339
340static jboolean
Jean-Michel Trivid6770542012-10-10 12:03:41 -0700341android_media_AudioSystem_isSourceActive(JNIEnv *env, jobject thiz, jint source)
342{
343 bool state = false;
344 AudioSystem::isSourceActive((audio_source_t) source, &state);
345 return state;
346}
347
Ashok Bhat075e9a12014-01-06 13:45:09 +0000348static jint
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -0700349android_media_AudioSystem_newAudioSessionId(JNIEnv *env, jobject thiz)
350{
Glenn Kasten211d9052016-02-26 16:22:40 -0800351 return AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -0700352}
353
354static jint
Jean-Michel Trivi292a6a42016-12-01 08:32:15 -0800355android_media_AudioSystem_newAudioPlayerId(JNIEnv *env, jobject thiz)
356{
Mikhail Naganova00883d2019-04-18 12:36:27 -0700357 int id = AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_CLIENT);
358 return id != AUDIO_UNIQUE_ID_ALLOCATE ? id : PLAYER_PIID_INVALID;
359}
360
361static jint
362android_media_AudioSystem_newAudioRecorderId(JNIEnv *env, jobject thiz)
363{
364 int id = AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_CLIENT);
365 return id != AUDIO_UNIQUE_ID_ALLOCATE ? id : RECORD_RIID_INVALID;
Jean-Michel Trivi292a6a42016-12-01 08:32:15 -0800366}
367
368static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700369android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370{
Eric Laurenta553c252009-07-17 12:17:14 -0700371 const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
372 String8 c_keyValuePairs8;
373 if (keyValuePairs) {
Dan Albert66987492014-11-20 11:41:21 -0800374 c_keyValuePairs8 = String8(
375 reinterpret_cast<const char16_t*>(c_keyValuePairs),
376 env->GetStringLength(keyValuePairs));
Eric Laurenta553c252009-07-17 12:17:14 -0700377 env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
378 }
Glenn Kastenc94752a2013-12-19 12:40:33 -0800379 int status = check_AudioSystem_Command(AudioSystem::setParameters(c_keyValuePairs8));
Ashok Bhat075e9a12014-01-06 13:45:09 +0000380 return (jint) status;
Eric Laurenta553c252009-07-17 12:17:14 -0700381}
382
383static jstring
384android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
385{
386 const jchar* c_keys = env->GetStringCritical(keys, 0);
387 String8 c_keys8;
388 if (keys) {
Dan Albert66987492014-11-20 11:41:21 -0800389 c_keys8 = String8(reinterpret_cast<const char16_t*>(c_keys),
390 env->GetStringLength(keys));
Eric Laurenta553c252009-07-17 12:17:14 -0700391 env->ReleaseStringCritical(keys, c_keys);
392 }
Glenn Kastenc94752a2013-12-19 12:40:33 -0800393 return env->NewStringUTF(AudioSystem::getParameters(c_keys8).string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394}
395
Glenn Kastened0079d2011-04-04 10:50:50 -0700396static void
397android_media_AudioSystem_error_callback(status_t err)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398{
Eric Laurent539719a2013-07-18 14:08:00 -0700399 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent0e7a4d92010-10-15 12:33:16 -0700400 if (env == NULL) {
401 return;
402 }
403
Glenn Kastened0079d2011-04-04 10:50:50 -0700404 jclass clazz = env->FindClass(kClassPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405
Eric Laurentdfb881f2013-07-18 14:41:39 -0700406 env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz,
407 "errorCallbackFromNative","(I)V"),
408 check_AudioSystem_Command(err));
Viorel Sumanb637ccf2014-05-30 16:51:07 +0300409
410 env->DeleteLocalRef(clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411}
412
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700413static void
414android_media_AudioSystem_dyn_policy_callback(int event, String8 regId, int val)
415{
416 JNIEnv *env = AndroidRuntime::getJNIEnv();
417 if (env == NULL) {
418 return;
419 }
420
421 jclass clazz = env->FindClass(kClassPathName);
422 const char* zechars = regId.string();
423 jstring zestring = env->NewStringUTF(zechars);
424
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800425 env->CallStaticVoidMethod(clazz, gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative,
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700426 event, zestring, val);
427
428 env->ReleaseStringUTFChars(zestring, zechars);
429 env->DeleteLocalRef(clazz);
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800430}
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700431
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800432static void
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800433android_media_AudioSystem_recording_callback(int event,
434 const record_client_info_t *clientInfo,
435 const audio_config_base_t *clientConfig,
436 std::vector<effect_descriptor_t> clientEffects,
437 const audio_config_base_t *deviceConfig,
438 std::vector<effect_descriptor_t> effects __unused,
439 audio_patch_handle_t patchHandle,
440 audio_source_t source)
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800441{
442 JNIEnv *env = AndroidRuntime::getJNIEnv();
443 if (env == NULL) {
444 return;
445 }
Jean-Michel Trivi66ffacf2017-02-04 17:25:31 -0800446 if (clientInfo == NULL || clientConfig == NULL || deviceConfig == NULL) {
447 ALOGE("Unexpected null client/device info or configurations in recording callback");
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800448 return;
449 }
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800450
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800451 // create an array for 2*3 integers to store the record configurations (client + device)
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800452 // plus 1 integer for the patch handle
453 const int REC_PARAM_SIZE = 7;
454 jintArray recParamArray = env->NewIntArray(REC_PARAM_SIZE);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800455 if (recParamArray == NULL) {
456 ALOGE("recording callback: Couldn't allocate int array for configuration data");
457 return;
458 }
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800459 jint recParamData[REC_PARAM_SIZE];
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800460 recParamData[0] = (jint) audioFormatFromNative(clientConfig->format);
461 // FIXME this doesn't support index-based masks
462 recParamData[1] = (jint) inChannelMaskFromNative(clientConfig->channel_mask);
463 recParamData[2] = (jint) clientConfig->sample_rate;
464 recParamData[3] = (jint) audioFormatFromNative(deviceConfig->format);
465 // FIXME this doesn't support index-based masks
466 recParamData[4] = (jint) inChannelMaskFromNative(deviceConfig->channel_mask);
467 recParamData[5] = (jint) deviceConfig->sample_rate;
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800468 recParamData[6] = (jint) patchHandle;
469 env->SetIntArrayRegion(recParamArray, 0, REC_PARAM_SIZE, recParamData);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800470
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800471 jobjectArray jClientEffects;
472 convertAudioEffectDescriptorVectorFromNative(env, &jClientEffects, clientEffects);
473
474 jobjectArray jEffects;
475 convertAudioEffectDescriptorVectorFromNative(env, &jEffects, effects);
476
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800477 // callback into java
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800478 jclass clazz = env->FindClass(kClassPathName);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800479
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800480 env->CallStaticVoidMethod(clazz,
481 gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative,
Mikhail Naganova00883d2019-04-18 12:36:27 -0700482 event, (jint) clientInfo->riid, (jint) clientInfo->uid,
483 clientInfo->session, clientInfo->source, clientInfo->port_id,
484 clientInfo->silenced, recParamArray, jClientEffects, jEffects,
485 source);
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800486 env->DeleteLocalRef(clazz);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800487 env->DeleteLocalRef(recParamArray);
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800488 env->DeleteLocalRef(jClientEffects);
489 env->DeleteLocalRef(jEffects);
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700490}
491
Ashok Bhat075e9a12014-01-06 13:45:09 +0000492static jint
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -0800493android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name,
Eric Laurent1d43aec2019-01-16 18:24:08 -0800494 jint codec)
Eric Laurenta553c252009-07-17 12:17:14 -0700495{
496 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Paul McLean10804eb2015-01-28 11:16:35 -0800497 const char *c_name = env->GetStringUTFChars(device_name, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700498 int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
499 static_cast <audio_policy_dev_state_t>(state),
Eric Laurent1d43aec2019-01-16 18:24:08 -0800500 c_address, c_name,
501 static_cast <audio_format_t>(codec)));
Eric Laurenta553c252009-07-17 12:17:14 -0700502 env->ReleaseStringUTFChars(device_address, c_address);
Paul McLean10804eb2015-01-28 11:16:35 -0800503 env->ReleaseStringUTFChars(device_name, c_name);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000504 return (jint) status;
Eric Laurenta553c252009-07-17 12:17:14 -0700505}
506
Ashok Bhat075e9a12014-01-06 13:45:09 +0000507static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700508android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
509{
510 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700511 int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
Eric Laurenta553c252009-07-17 12:17:14 -0700512 c_address));
513 env->ReleaseStringUTFChars(device_address, c_address);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000514 return (jint) state;
Eric Laurenta553c252009-07-17 12:17:14 -0700515}
516
Ashok Bhat075e9a12014-01-06 13:45:09 +0000517static jint
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -0800518android_media_AudioSystem_handleDeviceConfigChange(JNIEnv *env, jobject thiz, jint device, jstring device_address, jstring device_name,
Eric Laurent1d43aec2019-01-16 18:24:08 -0800519 jint codec)
Pavlin Radoslavov44a4ef02016-12-21 12:05:51 -0800520{
521 const char *c_address = env->GetStringUTFChars(device_address, NULL);
522 const char *c_name = env->GetStringUTFChars(device_name, NULL);
523 int status = check_AudioSystem_Command(AudioSystem::handleDeviceConfigChange(static_cast <audio_devices_t>(device),
Eric Laurent1d43aec2019-01-16 18:24:08 -0800524 c_address, c_name, static_cast <audio_format_t>(codec)));
Pavlin Radoslavov44a4ef02016-12-21 12:05:51 -0800525 env->ReleaseStringUTFChars(device_address, c_address);
526 env->ReleaseStringUTFChars(device_name, c_name);
527 return (jint) status;
528}
529
530static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700531android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
532{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000533 return (jint) check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state));
Eric Laurenta553c252009-07-17 12:17:14 -0700534}
535
Ashok Bhat075e9a12014-01-06 13:45:09 +0000536static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700537android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
538{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000539 return (jint) check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700540 static_cast <audio_policy_forced_cfg_t>(config)));
Eric Laurenta553c252009-07-17 12:17:14 -0700541}
542
Ashok Bhat075e9a12014-01-06 13:45:09 +0000543static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700544android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
545{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000546 return static_cast <jint>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
Eric Laurenta553c252009-07-17 12:17:14 -0700547}
548
Ashok Bhat075e9a12014-01-06 13:45:09 +0000549static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700550android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
551{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000552 return (jint) check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
Eric Laurenta553c252009-07-17 12:17:14 -0700553 indexMin,
554 indexMax));
555}
556
Ashok Bhat075e9a12014-01-06 13:45:09 +0000557static jint
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800558android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
559 jobject thiz,
560 jint stream,
561 jint index,
562 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700563{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000564 return (jint) check_AudioSystem_Command(
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800565 AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
566 index,
567 (audio_devices_t)device));
Eric Laurenta553c252009-07-17 12:17:14 -0700568}
569
Ashok Bhat075e9a12014-01-06 13:45:09 +0000570static jint
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800571android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env,
572 jobject thiz,
573 jint stream,
574 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700575{
576 int index;
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800577 if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
578 &index,
579 (audio_devices_t)device)
580 != NO_ERROR) {
Eric Laurenta553c252009-07-17 12:17:14 -0700581 index = -1;
582 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000583 return (jint) index;
Eric Laurenta553c252009-07-17 12:17:14 -0700584}
585
Ashok Bhat075e9a12014-01-06 13:45:09 +0000586static jint
François Gaffieebb67d02018-09-14 15:05:04 +0200587android_media_AudioSystem_setVolumeIndexForAttributes(JNIEnv *env,
588 jobject thiz,
589 jobject jaa,
590 jint index,
591 jint device)
592{
593 // read the AudioAttributes values
594 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
595 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
596 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
597 return jStatus;
598 }
599 return (jint) check_AudioSystem_Command(
600 AudioSystem::setVolumeIndexForAttributes(*(paa.get()), index, (audio_devices_t)device));
601}
602
603static jint
604android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env,
605 jobject thiz,
606 jobject jaa,
607 jint device)
608{
609 // read the AudioAttributes values
610 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
611 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
612 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
613 return jStatus;
614 }
615 int index;
616 if (AudioSystem::getVolumeIndexForAttributes(*(paa.get()), index, (audio_devices_t)device)
617 != NO_ERROR) {
618 index = -1;
619 }
620 return (jint) index;
621}
622
623static jint
624android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env,
625 jobject thiz,
626 jobject jaa)
627{
628 // read the AudioAttributes values
629 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
630 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
631 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
632 return jStatus;
633 }
634 int index;
635 if (AudioSystem::getMinVolumeIndexForAttributes(*(paa.get()), index)
636 != NO_ERROR) {
637 index = -1;
638 }
639 return (jint) index;
640}
641
642static jint
643android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env,
644 jobject thiz,
645 jobject jaa)
646{
647 // read the AudioAttributes values
648 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
649 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
650 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
651 return jStatus;
652 }
653 int index;
654 if (AudioSystem::getMaxVolumeIndexForAttributes(*(paa.get()), index)
655 != NO_ERROR) {
656 index = -1;
657 }
658 return (jint) index;
659}
660
661static jint
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400662android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
663{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000664 return (jint) check_AudioSystem_Command(AudioSystem::setMasterVolume(value));
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400665}
666
667static jfloat
668android_media_AudioSystem_getMasterVolume(JNIEnv *env, jobject thiz)
669{
670 float value;
671 if (AudioSystem::getMasterVolume(&value) != NO_ERROR) {
672 value = -1.0;
673 }
674 return value;
675}
676
Ashok Bhat075e9a12014-01-06 13:45:09 +0000677static jint
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400678android_media_AudioSystem_setMasterMute(JNIEnv *env, jobject thiz, jboolean mute)
679{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000680 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMute(mute));
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400681}
682
Vladimir Markoc1bcdbb2014-10-29 20:34:15 +0000683static jboolean
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400684android_media_AudioSystem_getMasterMute(JNIEnv *env, jobject thiz)
685{
686 bool mute;
687 if (AudioSystem::getMasterMute(&mute) != NO_ERROR) {
688 mute = false;
689 }
690 return mute;
691}
692
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800693static jint
Andy Hungf04b84d2015-12-18 17:33:27 -0800694android_media_AudioSystem_setMasterMono(JNIEnv *env, jobject thiz, jboolean mono)
695{
696 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMono(mono));
697}
698
699static jboolean
700android_media_AudioSystem_getMasterMono(JNIEnv *env, jobject thiz)
701{
702 bool mono;
703 if (AudioSystem::getMasterMono(&mono) != NO_ERROR) {
704 mono = false;
705 }
706 return mono;
707}
708
709static jint
Edward Savage-Jones35c292f2017-01-13 09:04:34 +0100710android_media_AudioSystem_setMasterBalance(JNIEnv *env, jobject thiz, jfloat balance)
711{
712 return (jint) check_AudioSystem_Command(AudioSystem::setMasterBalance(balance));
713}
714
715static jfloat
716android_media_AudioSystem_getMasterBalance(JNIEnv *env, jobject thiz)
717{
718 float balance;
719 const status_t status = AudioSystem::getMasterBalance(&balance);
720 if (status != NO_ERROR) {
721 ALOGW("%s getMasterBalance error %d, returning 0.f, audioserver down?", __func__, status);
722 balance = 0.f;
723 }
724 return balance;
725}
726
727static jint
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800728android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
729{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700730 return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800731}
732
Glenn Kastenc6c43652012-09-24 17:32:30 -0700733static jint
734android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz)
735{
736 return (jint) AudioSystem::getPrimaryOutputSamplingRate();
737}
738
739static jint
740android_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv *env, jobject clazz)
741{
742 return (jint) AudioSystem::getPrimaryOutputFrameCount();
743}
744
Oliver Woodman61dcdf32013-06-26 12:43:36 +0100745static jint
746android_media_AudioSystem_getOutputLatency(JNIEnv *env, jobject clazz, jint stream)
747{
748 uint32_t afLatency;
749 if (AudioSystem::getOutputLatency(&afLatency, static_cast <audio_stream_type_t>(stream))
750 != NO_ERROR) {
751 afLatency = -1;
752 }
753 return (jint) afLatency;
754}
755
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700756static jint
Andy Hung79583582018-01-23 13:58:02 -0800757android_media_AudioSystem_setLowRamDevice(
758 JNIEnv *env, jobject clazz, jboolean isLowRamDevice, jlong totalMemory)
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700759{
Andy Hung79583582018-01-23 13:58:02 -0800760 return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice, (int64_t) totalMemory);
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700761}
762
Ashok Bhat075e9a12014-01-06 13:45:09 +0000763static jint
Eric Laurentdfb881f2013-07-18 14:41:39 -0700764android_media_AudioSystem_checkAudioFlinger(JNIEnv *env, jobject clazz)
765{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000766 return (jint) check_AudioSystem_Command(AudioSystem::checkAudioFlinger());
Eric Laurentdfb881f2013-07-18 14:41:39 -0700767}
768
Eric Laurentb69681c2014-05-19 19:02:51 -0700769
770static bool useInChannelMask(audio_port_type_t type, audio_port_role_t role)
771{
772 return ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) ||
773 ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK));
774}
775
Eric Laurent3a241992014-05-19 19:33:26 -0700776static void convertAudioGainConfigToNative(JNIEnv *env,
777 struct audio_gain_config *nAudioGainConfig,
778 const jobject jAudioGainConfig,
779 bool useInMask)
780{
781 nAudioGainConfig->index = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mIndex);
782 nAudioGainConfig->mode = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mMode);
783 ALOGV("convertAudioGainConfigToNative got gain index %d", nAudioGainConfig->index);
784 jint jMask = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mChannelMask);
785 audio_channel_mask_t nMask;
786 if (useInMask) {
787 nMask = inChannelMaskToNative(jMask);
788 ALOGV("convertAudioGainConfigToNative IN mask java %x native %x", jMask, nMask);
789 } else {
790 nMask = outChannelMaskToNative(jMask);
791 ALOGV("convertAudioGainConfigToNative OUT mask java %x native %x", jMask, nMask);
792 }
793 nAudioGainConfig->channel_mask = nMask;
794 nAudioGainConfig->ramp_duration_ms = env->GetIntField(jAudioGainConfig,
795 gAudioGainConfigFields.mRampDurationMs);
796 jintArray jValues = (jintArray)env->GetObjectField(jAudioGainConfig,
797 gAudioGainConfigFields.mValues);
798 int *nValues = env->GetIntArrayElements(jValues, NULL);
799 size_t size = env->GetArrayLength(jValues);
800 memcpy(nAudioGainConfig->values, nValues, size * sizeof(int));
801 env->DeleteLocalRef(jValues);
802}
803
Eric Laurentb69681c2014-05-19 19:02:51 -0700804static jint convertAudioPortConfigToNative(JNIEnv *env,
805 struct audio_port_config *nAudioPortConfig,
Eric Laurent6368a7d2014-11-19 12:18:32 -0800806 const jobject jAudioPortConfig,
807 bool useConfigMask)
Eric Laurentb69681c2014-05-19 19:02:51 -0700808{
809 jobject jAudioPort = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mPort);
810 jobject jHandle = env->GetObjectField(jAudioPort, gAudioPortFields.mHandle);
811 nAudioPortConfig->id = env->GetIntField(jHandle, gAudioHandleFields.mId);
812 nAudioPortConfig->role = (audio_port_role_t)env->GetIntField(jAudioPort,
813 gAudioPortFields.mRole);
814 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
815 nAudioPortConfig->type = AUDIO_PORT_TYPE_DEVICE;
816 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
817 nAudioPortConfig->type = AUDIO_PORT_TYPE_MIX;
818 } else {
819 env->DeleteLocalRef(jAudioPort);
820 env->DeleteLocalRef(jHandle);
821 return (jint)AUDIO_JAVA_ERROR;
822 }
823 ALOGV("convertAudioPortConfigToNative handle %d role %d type %d",
824 nAudioPortConfig->id, nAudioPortConfig->role, nAudioPortConfig->type);
825
Eric Laurent6368a7d2014-11-19 12:18:32 -0800826 unsigned int configMask = 0;
827
Eric Laurentb69681c2014-05-19 19:02:51 -0700828 nAudioPortConfig->sample_rate = env->GetIntField(jAudioPortConfig,
829 gAudioPortConfigFields.mSamplingRate);
Eric Laurent6368a7d2014-11-19 12:18:32 -0800830 if (nAudioPortConfig->sample_rate != 0) {
831 configMask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
832 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700833
834 bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role);
835 audio_channel_mask_t nMask;
836 jint jMask = env->GetIntField(jAudioPortConfig,
837 gAudioPortConfigFields.mChannelMask);
838 if (useInMask) {
839 nMask = inChannelMaskToNative(jMask);
840 ALOGV("convertAudioPortConfigToNative IN mask java %x native %x", jMask, nMask);
841 } else {
842 nMask = outChannelMaskToNative(jMask);
843 ALOGV("convertAudioPortConfigToNative OUT mask java %x native %x", jMask, nMask);
844 }
845 nAudioPortConfig->channel_mask = nMask;
Eric Laurent6368a7d2014-11-19 12:18:32 -0800846 if (nAudioPortConfig->channel_mask != AUDIO_CHANNEL_NONE) {
847 configMask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
848 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700849
850 jint jFormat = env->GetIntField(jAudioPortConfig, gAudioPortConfigFields.mFormat);
851 audio_format_t nFormat = audioFormatToNative(jFormat);
852 ALOGV("convertAudioPortConfigToNative format %d native %d", jFormat, nFormat);
853 nAudioPortConfig->format = nFormat;
Eric Laurent6368a7d2014-11-19 12:18:32 -0800854 if (nAudioPortConfig->format != AUDIO_FORMAT_DEFAULT &&
855 nAudioPortConfig->format != AUDIO_FORMAT_INVALID) {
856 configMask |= AUDIO_PORT_CONFIG_FORMAT;
857 }
858
Eric Laurentb69681c2014-05-19 19:02:51 -0700859 jobject jGain = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mGain);
860 if (jGain != NULL) {
Eric Laurent3a241992014-05-19 19:33:26 -0700861 convertAudioGainConfigToNative(env, &nAudioPortConfig->gain, jGain, useInMask);
Eric Laurentb69681c2014-05-19 19:02:51 -0700862 env->DeleteLocalRef(jGain);
Eric Laurent6368a7d2014-11-19 12:18:32 -0800863 configMask |= AUDIO_PORT_CONFIG_GAIN;
Eric Laurentb69681c2014-05-19 19:02:51 -0700864 } else {
865 ALOGV("convertAudioPortConfigToNative no gain");
866 nAudioPortConfig->gain.index = -1;
867 }
Eric Laurent6368a7d2014-11-19 12:18:32 -0800868 if (useConfigMask) {
869 nAudioPortConfig->config_mask = env->GetIntField(jAudioPortConfig,
870 gAudioPortConfigFields.mConfigMask);
871 } else {
872 nAudioPortConfig->config_mask = configMask;
873 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700874 env->DeleteLocalRef(jAudioPort);
875 env->DeleteLocalRef(jHandle);
876 return (jint)AUDIO_JAVA_SUCCESS;
877}
878
Hongwei Wangf44a5682018-08-24 10:37:56 -0700879/**
880 * Extends convertAudioPortConfigToNative with extra device port info.
881 * Mix / Session specific info is not fulfilled.
882 */
883static jint convertAudioPortConfigToNativeWithDevicePort(JNIEnv *env,
884 struct audio_port_config *nAudioPortConfig,
885 const jobject jAudioPortConfig,
886 bool useConfigMask)
887{
888 jint jStatus = convertAudioPortConfigToNative(env,
889 nAudioPortConfig,
890 jAudioPortConfig,
891 useConfigMask);
892 if (jStatus != AUDIO_JAVA_SUCCESS) {
893 return jStatus;
894 }
895 // Supports AUDIO_PORT_TYPE_DEVICE only
896 if (nAudioPortConfig->type != AUDIO_PORT_TYPE_DEVICE) {
897 return (jint)AUDIO_JAVA_BAD_VALUE;
898 }
899
900 jobject jAudioDevicePort = env->GetObjectField(jAudioPortConfig,
901 gAudioPortConfigFields.mPort);
902 nAudioPortConfig->ext.device.type = env->GetIntField(jAudioDevicePort,
903 gAudioPortFields.mType);
904 jstring jDeviceAddress = (jstring)env->GetObjectField(jAudioDevicePort,
905 gAudioPortFields.mAddress);
906 const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
907 strncpy(nAudioPortConfig->ext.device.address,
908 nDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN - 1);
909 env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
910 env->DeleteLocalRef(jDeviceAddress);
911 env->DeleteLocalRef(jAudioDevicePort);
912 return jStatus;
913}
914
Eric Laurentb69681c2014-05-19 19:02:51 -0700915static jint convertAudioPortConfigFromNative(JNIEnv *env,
916 jobject jAudioPort,
917 jobject *jAudioPortConfig,
918 const struct audio_port_config *nAudioPortConfig)
919{
920 jint jStatus = AUDIO_JAVA_SUCCESS;
921 jobject jAudioGainConfig = NULL;
922 jobject jAudioGain = NULL;
923 jintArray jGainValues;
924 bool audioportCreated = false;
925
926 ALOGV("convertAudioPortConfigFromNative jAudioPort %p", jAudioPort);
927
928 if (jAudioPort == NULL) {
929 jobject jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
930 nAudioPortConfig->id);
931
932 ALOGV("convertAudioPortConfigFromNative handle %d is a %s", nAudioPortConfig->id,
933 nAudioPortConfig->type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix");
934
935 if (jHandle == NULL) {
936 return (jint)AUDIO_JAVA_ERROR;
937 }
938 // create dummy port and port config objects with just the correct handle
939 // and configuration data. The actual AudioPortConfig objects will be
940 // constructed by java code with correct class type (device, mix etc...)
941 // and reference to AudioPort instance in this client
942 jAudioPort = env->NewObject(gAudioPortClass, gAudioPortCstor,
Paul McLeanf29e5f32015-06-15 10:19:22 -0700943 jHandle, // handle
944 0, // role
945 NULL, // name
946 NULL, // samplingRates
947 NULL, // channelMasks
948 NULL, // channelIndexMasks
949 NULL, // formats
950 NULL); // gains
Eric Laurentb69681c2014-05-19 19:02:51 -0700951 env->DeleteLocalRef(jHandle);
952 if (jAudioPort == NULL) {
953 return (jint)AUDIO_JAVA_ERROR;
954 }
955 ALOGV("convertAudioPortConfigFromNative jAudioPort created for handle %d",
956 nAudioPortConfig->id);
957
958 audioportCreated = true;
959 }
960
961 bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role);
962
963 audio_channel_mask_t nMask;
964 jint jMask;
965
966 int gainIndex = nAudioPortConfig->gain.index;
967 if (gainIndex >= 0) {
968 ALOGV("convertAudioPortConfigFromNative gain found with index %d mode %x",
969 gainIndex, nAudioPortConfig->gain.mode);
970 if (audioportCreated) {
971 ALOGV("convertAudioPortConfigFromNative creating gain");
972 jAudioGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
973 gainIndex,
974 0,
975 0,
976 0,
977 0,
978 0,
979 0,
980 0,
981 0);
982 if (jAudioGain == NULL) {
983 ALOGV("convertAudioPortConfigFromNative creating gain FAILED");
984 jStatus = (jint)AUDIO_JAVA_ERROR;
985 goto exit;
986 }
987 } else {
988 ALOGV("convertAudioPortConfigFromNative reading gain from port");
989 jobjectArray jGains = (jobjectArray)env->GetObjectField(jAudioPort,
990 gAudioPortFields.mGains);
991 if (jGains == NULL) {
992 ALOGV("convertAudioPortConfigFromNative could not get gains from port");
993 jStatus = (jint)AUDIO_JAVA_ERROR;
994 goto exit;
995 }
996 jAudioGain = env->GetObjectArrayElement(jGains, gainIndex);
997 env->DeleteLocalRef(jGains);
998 if (jAudioGain == NULL) {
999 ALOGV("convertAudioPortConfigFromNative could not get gain at index %d", gainIndex);
1000 jStatus = (jint)AUDIO_JAVA_ERROR;
1001 goto exit;
1002 }
1003 }
Eric Laurent0078c7c2014-06-04 09:49:52 -07001004 int numValues;
1005 if (useInMask) {
1006 numValues = audio_channel_count_from_in_mask(nAudioPortConfig->gain.channel_mask);
1007 } else {
1008 numValues = audio_channel_count_from_out_mask(nAudioPortConfig->gain.channel_mask);
1009 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001010 jGainValues = env->NewIntArray(numValues);
1011 if (jGainValues == NULL) {
1012 ALOGV("convertAudioPortConfigFromNative could not create gain values %d", numValues);
1013 jStatus = (jint)AUDIO_JAVA_ERROR;
1014 goto exit;
1015 }
1016 env->SetIntArrayRegion(jGainValues, 0, numValues,
1017 nAudioPortConfig->gain.values);
1018
1019 nMask = nAudioPortConfig->gain.channel_mask;
1020 if (useInMask) {
1021 jMask = inChannelMaskFromNative(nMask);
1022 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1023 } else {
1024 jMask = outChannelMaskFromNative(nMask);
1025 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1026 }
1027
1028 jAudioGainConfig = env->NewObject(gAudioGainConfigClass,
1029 gAudioGainConfigCstor,
1030 gainIndex,
1031 jAudioGain,
1032 nAudioPortConfig->gain.mode,
1033 jMask,
1034 jGainValues,
1035 nAudioPortConfig->gain.ramp_duration_ms);
1036 env->DeleteLocalRef(jGainValues);
1037 if (jAudioGainConfig == NULL) {
1038 ALOGV("convertAudioPortConfigFromNative could not create gain config");
1039 jStatus = (jint)AUDIO_JAVA_ERROR;
1040 goto exit;
1041 }
1042 }
1043 jclass clazz;
1044 jmethodID methodID;
1045 if (audioportCreated) {
1046 clazz = gAudioPortConfigClass;
1047 methodID = gAudioPortConfigCstor;
1048 ALOGV("convertAudioPortConfigFromNative building a generic port config");
1049 } else {
1050 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
1051 clazz = gAudioDevicePortConfigClass;
1052 methodID = gAudioDevicePortConfigCstor;
1053 ALOGV("convertAudioPortConfigFromNative building a device config");
1054 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
1055 clazz = gAudioMixPortConfigClass;
1056 methodID = gAudioMixPortConfigCstor;
1057 ALOGV("convertAudioPortConfigFromNative building a mix config");
1058 } else {
1059 jStatus = (jint)AUDIO_JAVA_ERROR;
1060 goto exit;
1061 }
1062 }
1063 nMask = nAudioPortConfig->channel_mask;
1064 if (useInMask) {
1065 jMask = inChannelMaskFromNative(nMask);
1066 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1067 } else {
1068 jMask = outChannelMaskFromNative(nMask);
1069 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1070 }
1071
1072 *jAudioPortConfig = env->NewObject(clazz, methodID,
1073 jAudioPort,
1074 nAudioPortConfig->sample_rate,
1075 jMask,
1076 audioFormatFromNative(nAudioPortConfig->format),
1077 jAudioGainConfig);
1078 if (*jAudioPortConfig == NULL) {
1079 ALOGV("convertAudioPortConfigFromNative could not create new port config");
1080 jStatus = (jint)AUDIO_JAVA_ERROR;
1081 } else {
1082 ALOGV("convertAudioPortConfigFromNative OK");
1083 }
1084
1085exit:
1086 if (audioportCreated) {
1087 env->DeleteLocalRef(jAudioPort);
1088 if (jAudioGain != NULL) {
1089 env->DeleteLocalRef(jAudioGain);
1090 }
1091 }
1092 if (jAudioGainConfig != NULL) {
1093 env->DeleteLocalRef(jAudioGainConfig);
1094 }
1095 return jStatus;
1096}
1097
Paul McLean4e5e9e92015-06-17 10:10:11 -07001098static bool hasFormat(int* formats, size_t size, int format) {
1099 for (size_t index = 0; index < size; index++) {
1100 if (formats[index] == format) {
1101 return true; // found
1102 }
1103 }
1104 return false; // not found
1105}
1106
Andy Hung737d9fb2016-08-16 18:38:49 -07001107// TODO: pull out to separate file
1108template <typename T, size_t N>
1109static constexpr size_t array_size(const T (&)[N]) {
1110 return N;
1111}
1112
Eric Laurentb69681c2014-05-19 19:02:51 -07001113static jint convertAudioPortFromNative(JNIEnv *env,
1114 jobject *jAudioPort, const struct audio_port *nAudioPort)
1115{
1116 jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
1117 jintArray jSamplingRates = NULL;
1118 jintArray jChannelMasks = NULL;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001119 jintArray jChannelIndexMasks = NULL;
Paul McLean4e5e9e92015-06-17 10:10:11 -07001120 int* cFormats = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001121 jintArray jFormats = NULL;
1122 jobjectArray jGains = NULL;
1123 jobject jHandle = NULL;
xiaomi/hanli82840c42017-07-19 18:53:03 +08001124 jobject jAudioPortConfig = NULL;
Paul McLean10804eb2015-01-28 11:16:35 -08001125 jstring jDeviceName = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001126 bool useInMask;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001127 size_t numPositionMasks = 0;
1128 size_t numIndexMasks = 0;
Paul McLean2db94372015-06-18 12:47:34 -07001129 size_t numUniqueFormats = 0;
1130
Paul McLean10804eb2015-01-28 11:16:35 -08001131 ALOGV("convertAudioPortFromNative id %d role %d type %d name %s",
1132 nAudioPort->id, nAudioPort->role, nAudioPort->type, nAudioPort->name);
Eric Laurentb69681c2014-05-19 19:02:51 -07001133
Andy Hung737d9fb2016-08-16 18:38:49 -07001134 // Verify audio port array count info.
1135 if (nAudioPort->num_sample_rates > array_size(nAudioPort->sample_rates)
1136 || nAudioPort->num_channel_masks > array_size(nAudioPort->channel_masks)
1137 || nAudioPort->num_formats > array_size(nAudioPort->formats)
1138 || nAudioPort->num_gains > array_size(nAudioPort->gains)) {
1139
1140 std::stringstream ss;
1141 ss << "convertAudioPortFromNative array count out of bounds:"
1142 << " num_sample_rates " << nAudioPort->num_sample_rates
1143 << " num_channel_masks " << nAudioPort->num_channel_masks
1144 << " num_formats " << nAudioPort->num_formats
1145 << " num_gains " << nAudioPort->num_gains
1146 ;
1147 std::string s = ss.str();
1148
1149 // Prefer to log through Java wtf instead of native ALOGE.
1150 ScopedLocalRef<jclass> jLogClass(env, env->FindClass("android/util/Log"));
1151 jmethodID jWtfId = (jLogClass.get() == nullptr)
1152 ? nullptr
1153 : env->GetStaticMethodID(jLogClass.get(), "wtf",
1154 "(Ljava/lang/String;Ljava/lang/String;)I");
1155 if (jWtfId != nullptr) {
1156 ScopedLocalRef<jstring> jMessage(env, env->NewStringUTF(s.c_str()));
1157 ScopedLocalRef<jstring> jTag(env, env->NewStringUTF(LOG_TAG));
1158 (void)env->CallStaticIntMethod(jLogClass.get(), jWtfId, jTag.get(), jMessage.get());
1159 } else {
1160 ALOGE("%s", s.c_str());
1161 }
1162 jStatus = (jint)AUDIO_JAVA_ERROR;
1163 goto exit;
1164 }
1165
Eric Laurentb69681c2014-05-19 19:02:51 -07001166 jSamplingRates = env->NewIntArray(nAudioPort->num_sample_rates);
1167 if (jSamplingRates == NULL) {
1168 jStatus = (jint)AUDIO_JAVA_ERROR;
1169 goto exit;
1170 }
1171 if (nAudioPort->num_sample_rates) {
1172 env->SetIntArrayRegion(jSamplingRates, 0, nAudioPort->num_sample_rates,
1173 (jint *)nAudioPort->sample_rates);
1174 }
1175
Paul McLeanf29e5f32015-06-15 10:19:22 -07001176 // count up how many masks are positional and indexed
1177 for(size_t index = 0; index < nAudioPort->num_channel_masks; index++) {
1178 const audio_channel_mask_t mask = nAudioPort->channel_masks[index];
1179 if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1180 numIndexMasks++;
1181 } else {
1182 numPositionMasks++;
1183 }
1184 }
1185
1186 jChannelMasks = env->NewIntArray(numPositionMasks);
Eric Laurentb69681c2014-05-19 19:02:51 -07001187 if (jChannelMasks == NULL) {
1188 jStatus = (jint)AUDIO_JAVA_ERROR;
1189 goto exit;
1190 }
Paul McLeanf29e5f32015-06-15 10:19:22 -07001191 jChannelIndexMasks = env->NewIntArray(numIndexMasks);
1192 if (jChannelIndexMasks == NULL) {
1193 jStatus = (jint)AUDIO_JAVA_ERROR;
1194 goto exit;
1195 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001196 useInMask = useInChannelMask(nAudioPort->type, nAudioPort->role);
1197
Paul McLeanf29e5f32015-06-15 10:19:22 -07001198 // put the masks in the output arrays
1199 for (size_t maskIndex = 0, posMaskIndex = 0, indexedMaskIndex = 0;
1200 maskIndex < nAudioPort->num_channel_masks; maskIndex++) {
1201 const audio_channel_mask_t mask = nAudioPort->channel_masks[maskIndex];
1202 if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1203 jint jMask = audio_channel_mask_get_bits(mask);
1204 env->SetIntArrayRegion(jChannelIndexMasks, indexedMaskIndex++, 1, &jMask);
Eric Laurentb69681c2014-05-19 19:02:51 -07001205 } else {
Paul McLeanf29e5f32015-06-15 10:19:22 -07001206 jint jMask = useInMask ? inChannelMaskFromNative(mask)
1207 : outChannelMaskFromNative(mask);
1208 env->SetIntArrayRegion(jChannelMasks, posMaskIndex++, 1, &jMask);
Eric Laurentb69681c2014-05-19 19:02:51 -07001209 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001210 }
1211
Paul McLeanf29e5f32015-06-15 10:19:22 -07001212 // formats
Paul McLean2db94372015-06-18 12:47:34 -07001213 if (nAudioPort->num_formats != 0) {
1214 cFormats = new int[nAudioPort->num_formats];
1215 for (size_t index = 0; index < nAudioPort->num_formats; index++) {
1216 int format = audioFormatFromNative(nAudioPort->formats[index]);
1217 if (!hasFormat(cFormats, numUniqueFormats, format)) {
1218 cFormats[numUniqueFormats++] = format;
1219 }
Paul McLean4e5e9e92015-06-17 10:10:11 -07001220 }
1221 }
1222 jFormats = env->NewIntArray(numUniqueFormats);
Eric Laurentb69681c2014-05-19 19:02:51 -07001223 if (jFormats == NULL) {
1224 jStatus = (jint)AUDIO_JAVA_ERROR;
1225 goto exit;
1226 }
Paul McLean2db94372015-06-18 12:47:34 -07001227 if (numUniqueFormats != 0) {
1228 env->SetIntArrayRegion(jFormats, 0, numUniqueFormats, cFormats);
1229 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001230
Paul McLeanf29e5f32015-06-15 10:19:22 -07001231 // gains
Eric Laurentb69681c2014-05-19 19:02:51 -07001232 jGains = env->NewObjectArray(nAudioPort->num_gains,
1233 gAudioGainClass, NULL);
1234 if (jGains == NULL) {
1235 jStatus = (jint)AUDIO_JAVA_ERROR;
1236 goto exit;
1237 }
Paul McLeanf29e5f32015-06-15 10:19:22 -07001238
Eric Laurentb69681c2014-05-19 19:02:51 -07001239 for (size_t j = 0; j < nAudioPort->num_gains; j++) {
1240 audio_channel_mask_t nMask = nAudioPort->gains[j].channel_mask;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001241 jint jMask;
Eric Laurentb69681c2014-05-19 19:02:51 -07001242 if (useInMask) {
1243 jMask = inChannelMaskFromNative(nMask);
1244 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1245 } else {
1246 jMask = outChannelMaskFromNative(nMask);
1247 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1248 }
1249
1250 jobject jGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
1251 j,
1252 nAudioPort->gains[j].mode,
1253 jMask,
1254 nAudioPort->gains[j].min_value,
1255 nAudioPort->gains[j].max_value,
1256 nAudioPort->gains[j].default_value,
1257 nAudioPort->gains[j].step_value,
1258 nAudioPort->gains[j].min_ramp_ms,
1259 nAudioPort->gains[j].max_ramp_ms);
1260 if (jGain == NULL) {
1261 jStatus = (jint)AUDIO_JAVA_ERROR;
1262 goto exit;
1263 }
1264 env->SetObjectArrayElement(jGains, j, jGain);
1265 env->DeleteLocalRef(jGain);
1266 }
1267
1268 jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1269 nAudioPort->id);
1270 if (jHandle == NULL) {
1271 jStatus = (jint)AUDIO_JAVA_ERROR;
1272 goto exit;
1273 }
1274
Paul McLean10804eb2015-01-28 11:16:35 -08001275 jDeviceName = env->NewStringUTF(nAudioPort->name);
1276
Eric Laurentb69681c2014-05-19 19:02:51 -07001277 if (nAudioPort->type == AUDIO_PORT_TYPE_DEVICE) {
1278 ALOGV("convertAudioPortFromNative is a device %08x", nAudioPort->ext.device.type);
1279 jstring jAddress = env->NewStringUTF(nAudioPort->ext.device.address);
1280 *jAudioPort = env->NewObject(gAudioDevicePortClass, gAudioDevicePortCstor,
Paul McLean10804eb2015-01-28 11:16:35 -08001281 jHandle, jDeviceName,
Paul McLeanf29e5f32015-06-15 10:19:22 -07001282 jSamplingRates, jChannelMasks, jChannelIndexMasks,
1283 jFormats, jGains,
Eric Laurentb69681c2014-05-19 19:02:51 -07001284 nAudioPort->ext.device.type, jAddress);
1285 env->DeleteLocalRef(jAddress);
1286 } else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) {
1287 ALOGV("convertAudioPortFromNative is a mix");
1288 *jAudioPort = env->NewObject(gAudioMixPortClass, gAudioMixPortCstor,
Eric Laurent4bcdba82015-05-01 11:37:49 -07001289 jHandle, nAudioPort->ext.mix.handle,
1290 nAudioPort->role, jDeviceName,
Paul McLeanf29e5f32015-06-15 10:19:22 -07001291 jSamplingRates, jChannelMasks, jChannelIndexMasks,
Eric Laurentb69681c2014-05-19 19:02:51 -07001292 jFormats, jGains);
1293 } else {
1294 ALOGE("convertAudioPortFromNative unknown nAudioPort type %d", nAudioPort->type);
1295 jStatus = (jint)AUDIO_JAVA_ERROR;
1296 goto exit;
1297 }
1298 if (*jAudioPort == NULL) {
1299 jStatus = (jint)AUDIO_JAVA_ERROR;
1300 goto exit;
1301 }
1302
Eric Laurentb69681c2014-05-19 19:02:51 -07001303 jStatus = convertAudioPortConfigFromNative(env,
1304 *jAudioPort,
1305 &jAudioPortConfig,
1306 &nAudioPort->active_config);
1307 if (jStatus != AUDIO_JAVA_SUCCESS) {
Andy Hung737d9fb2016-08-16 18:38:49 -07001308 goto exit;
Eric Laurentb69681c2014-05-19 19:02:51 -07001309 }
1310
1311 env->SetObjectField(*jAudioPort, gAudioPortFields.mActiveConfig, jAudioPortConfig);
1312
1313exit:
Paul McLean10804eb2015-01-28 11:16:35 -08001314 if (jDeviceName != NULL) {
1315 env->DeleteLocalRef(jDeviceName);
1316 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001317 if (jSamplingRates != NULL) {
1318 env->DeleteLocalRef(jSamplingRates);
1319 }
1320 if (jChannelMasks != NULL) {
1321 env->DeleteLocalRef(jChannelMasks);
1322 }
Paul McLean4e5e9e92015-06-17 10:10:11 -07001323 if (jChannelIndexMasks != NULL) {
1324 env->DeleteLocalRef(jChannelIndexMasks);
1325 }
1326 if (cFormats != NULL) {
1327 delete[] cFormats;
1328 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001329 if (jFormats != NULL) {
1330 env->DeleteLocalRef(jFormats);
1331 }
1332 if (jGains != NULL) {
1333 env->DeleteLocalRef(jGains);
1334 }
1335 if (jHandle != NULL) {
1336 env->DeleteLocalRef(jHandle);
1337 }
xiaomi/hanli82840c42017-07-19 18:53:03 +08001338 if (jAudioPortConfig != NULL) {
1339 env->DeleteLocalRef(jAudioPortConfig);
1340 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001341
1342 return jStatus;
1343}
1344
Eric Laurentb69681c2014-05-19 19:02:51 -07001345static jint
1346android_media_AudioSystem_listAudioPorts(JNIEnv *env, jobject clazz,
1347 jobject jPorts, jintArray jGeneration)
1348{
1349 ALOGV("listAudioPorts");
1350
1351 if (jPorts == NULL) {
1352 ALOGE("listAudioPorts NULL AudioPort ArrayList");
1353 return (jint)AUDIO_JAVA_BAD_VALUE;
1354 }
1355 if (!env->IsInstanceOf(jPorts, gArrayListClass)) {
1356 ALOGE("listAudioPorts not an arraylist");
1357 return (jint)AUDIO_JAVA_BAD_VALUE;
1358 }
1359
1360 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1361 return (jint)AUDIO_JAVA_BAD_VALUE;
1362 }
1363
1364 status_t status;
1365 unsigned int generation1;
1366 unsigned int generation;
1367 unsigned int numPorts;
1368 jint *nGeneration;
1369 struct audio_port *nPorts = NULL;
1370 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
Eric Laurentb36d1042016-04-14 18:00:38 -07001371 jint jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001372
1373 // get the port count and all the ports until they both return the same generation
1374 do {
1375 if (attempts-- < 0) {
1376 status = TIMED_OUT;
1377 break;
1378 }
1379
1380 numPorts = 0;
1381 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE,
1382 AUDIO_PORT_TYPE_NONE,
1383 &numPorts,
1384 NULL,
1385 &generation1);
Eric Laurentb36d1042016-04-14 18:00:38 -07001386 if (status != NO_ERROR) {
Eric Laurentb69681c2014-05-19 19:02:51 -07001387 ALOGE_IF(status != NO_ERROR, "AudioSystem::listAudioPorts error %d", status);
1388 break;
1389 }
Eric Laurentb36d1042016-04-14 18:00:38 -07001390 if (numPorts == 0) {
1391 jStatus = (jint)AUDIO_JAVA_SUCCESS;
1392 goto exit;
1393 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001394 nPorts = (struct audio_port *)realloc(nPorts, numPorts * sizeof(struct audio_port));
1395
1396 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE,
1397 AUDIO_PORT_TYPE_NONE,
1398 &numPorts,
1399 nPorts,
1400 &generation);
1401 ALOGV("listAudioPorts AudioSystem::listAudioPorts numPorts %d generation %d generation1 %d",
1402 numPorts, generation, generation1);
1403 } while (generation1 != generation && status == NO_ERROR);
1404
Eric Laurentb36d1042016-04-14 18:00:38 -07001405 jStatus = nativeToJavaStatus(status);
Eric Laurentb69681c2014-05-19 19:02:51 -07001406 if (jStatus != AUDIO_JAVA_SUCCESS) {
1407 goto exit;
1408 }
1409
Eric Laurentb69681c2014-05-19 19:02:51 -07001410 for (size_t i = 0; i < numPorts; i++) {
xiaomi/hanli82840c42017-07-19 18:53:03 +08001411 jobject jAudioPort = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001412 jStatus = convertAudioPortFromNative(env, &jAudioPort, &nPorts[i]);
1413 if (jStatus != AUDIO_JAVA_SUCCESS) {
1414 goto exit;
1415 }
1416 env->CallBooleanMethod(jPorts, gArrayListMethods.add, jAudioPort);
xiaomi/hanli82840c42017-07-19 18:53:03 +08001417 if (jAudioPort != NULL) {
1418 env->DeleteLocalRef(jAudioPort);
1419 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001420 }
1421
1422exit:
Eric Laurentb36d1042016-04-14 18:00:38 -07001423 nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1424 if (nGeneration == NULL) {
1425 jStatus = (jint)AUDIO_JAVA_ERROR;
1426 } else {
1427 nGeneration[0] = generation1;
1428 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1429 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001430 free(nPorts);
1431 return jStatus;
1432}
1433
1434static int
1435android_media_AudioSystem_createAudioPatch(JNIEnv *env, jobject clazz,
1436 jobjectArray jPatches, jobjectArray jSources, jobjectArray jSinks)
1437{
1438 status_t status;
1439 jint jStatus;
1440
1441 ALOGV("createAudioPatch");
1442 if (jPatches == NULL || jSources == NULL || jSinks == NULL) {
1443 return (jint)AUDIO_JAVA_BAD_VALUE;
1444 }
1445
1446 if (env->GetArrayLength(jPatches) != 1) {
1447 return (jint)AUDIO_JAVA_BAD_VALUE;
1448 }
1449 jint numSources = env->GetArrayLength(jSources);
1450 if (numSources == 0 || numSources > AUDIO_PATCH_PORTS_MAX) {
1451 return (jint)AUDIO_JAVA_BAD_VALUE;
1452 }
1453
1454 jint numSinks = env->GetArrayLength(jSinks);
1455 if (numSinks == 0 || numSinks > AUDIO_PATCH_PORTS_MAX) {
1456 return (jint)AUDIO_JAVA_BAD_VALUE;
1457 }
1458
1459 audio_patch_handle_t handle = (audio_patch_handle_t)0;
1460 jobject jPatch = env->GetObjectArrayElement(jPatches, 0);
1461 jobject jPatchHandle = NULL;
1462 if (jPatch != NULL) {
1463 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1464 return (jint)AUDIO_JAVA_BAD_VALUE;
1465 }
1466 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1467 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1468 }
1469
Mikhail Naganov304eafc2018-05-23 16:54:12 -07001470 struct audio_patch nPatch = { .id = handle };
Eric Laurentb69681c2014-05-19 19:02:51 -07001471
Eric Laurentb69681c2014-05-19 19:02:51 -07001472 jobject jSource = NULL;
1473 jobject jSink = NULL;
1474
1475 for (jint i = 0; i < numSources; i++) {
1476 jSource = env->GetObjectArrayElement(jSources, i);
1477 if (!env->IsInstanceOf(jSource, gAudioPortConfigClass)) {
1478 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1479 goto exit;
1480 }
Eric Laurent6368a7d2014-11-19 12:18:32 -08001481 jStatus = convertAudioPortConfigToNative(env, &nPatch.sources[i], jSource, false);
Eric Laurentb69681c2014-05-19 19:02:51 -07001482 env->DeleteLocalRef(jSource);
1483 jSource = NULL;
1484 if (jStatus != AUDIO_JAVA_SUCCESS) {
1485 goto exit;
1486 }
1487 nPatch.num_sources++;
1488 }
1489
1490 for (jint i = 0; i < numSinks; i++) {
1491 jSink = env->GetObjectArrayElement(jSinks, i);
1492 if (!env->IsInstanceOf(jSink, gAudioPortConfigClass)) {
1493 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1494 goto exit;
1495 }
Eric Laurent6368a7d2014-11-19 12:18:32 -08001496 jStatus = convertAudioPortConfigToNative(env, &nPatch.sinks[i], jSink, false);
Eric Laurentb69681c2014-05-19 19:02:51 -07001497 env->DeleteLocalRef(jSink);
1498 jSink = NULL;
1499 if (jStatus != AUDIO_JAVA_SUCCESS) {
1500 goto exit;
1501 }
1502 nPatch.num_sinks++;
1503 }
1504
1505 ALOGV("AudioSystem::createAudioPatch");
1506 status = AudioSystem::createAudioPatch(&nPatch, &handle);
1507 ALOGV("AudioSystem::createAudioPatch() returned %d hande %d", status, handle);
1508
1509 jStatus = nativeToJavaStatus(status);
1510 if (jStatus != AUDIO_JAVA_SUCCESS) {
1511 goto exit;
1512 }
1513
1514 if (jPatchHandle == NULL) {
1515 jPatchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1516 handle);
1517 if (jPatchHandle == NULL) {
1518 jStatus = (jint)AUDIO_JAVA_ERROR;
1519 goto exit;
1520 }
1521 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor, jPatchHandle, jSources, jSinks);
1522 if (jPatch == NULL) {
1523 jStatus = (jint)AUDIO_JAVA_ERROR;
1524 goto exit;
1525 }
1526 env->SetObjectArrayElement(jPatches, 0, jPatch);
1527 } else {
1528 env->SetIntField(jPatchHandle, gAudioHandleFields.mId, handle);
1529 }
1530
1531exit:
1532 if (jPatchHandle != NULL) {
1533 env->DeleteLocalRef(jPatchHandle);
1534 }
1535 if (jPatch != NULL) {
1536 env->DeleteLocalRef(jPatch);
1537 }
1538 if (jSource != NULL) {
1539 env->DeleteLocalRef(jSource);
1540 }
1541 if (jSink != NULL) {
1542 env->DeleteLocalRef(jSink);
1543 }
1544 return jStatus;
1545}
1546
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001547static jint
Eric Laurentb69681c2014-05-19 19:02:51 -07001548android_media_AudioSystem_releaseAudioPatch(JNIEnv *env, jobject clazz,
1549 jobject jPatch)
1550{
1551 ALOGV("releaseAudioPatch");
1552 if (jPatch == NULL) {
1553 return (jint)AUDIO_JAVA_BAD_VALUE;
1554 }
1555
1556 audio_patch_handle_t handle = (audio_patch_handle_t)0;
1557 jobject jPatchHandle = NULL;
1558 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1559 return (jint)AUDIO_JAVA_BAD_VALUE;
1560 }
1561 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1562 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1563 env->DeleteLocalRef(jPatchHandle);
1564
1565 ALOGV("AudioSystem::releaseAudioPatch");
1566 status_t status = AudioSystem::releaseAudioPatch(handle);
1567 ALOGV("AudioSystem::releaseAudioPatch() returned %d", status);
1568 jint jStatus = nativeToJavaStatus(status);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001569 return jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001570}
1571
1572static jint
1573android_media_AudioSystem_listAudioPatches(JNIEnv *env, jobject clazz,
1574 jobject jPatches, jintArray jGeneration)
1575{
1576 ALOGV("listAudioPatches");
1577 if (jPatches == NULL) {
1578 ALOGE("listAudioPatches NULL AudioPatch ArrayList");
1579 return (jint)AUDIO_JAVA_BAD_VALUE;
1580 }
1581 if (!env->IsInstanceOf(jPatches, gArrayListClass)) {
1582 ALOGE("listAudioPatches not an arraylist");
1583 return (jint)AUDIO_JAVA_BAD_VALUE;
1584 }
1585
1586 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1587 return (jint)AUDIO_JAVA_BAD_VALUE;
1588 }
1589
1590 status_t status;
1591 unsigned int generation1;
1592 unsigned int generation;
1593 unsigned int numPatches;
1594 jint *nGeneration;
1595 struct audio_patch *nPatches = NULL;
1596 jobjectArray jSources = NULL;
1597 jobject jSource = NULL;
1598 jobjectArray jSinks = NULL;
1599 jobject jSink = NULL;
1600 jobject jPatch = NULL;
1601 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
Eric Laurentb36d1042016-04-14 18:00:38 -07001602 jint jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001603
1604 // get the patch count and all the patches until they both return the same generation
1605 do {
1606 if (attempts-- < 0) {
1607 status = TIMED_OUT;
1608 break;
1609 }
1610
1611 numPatches = 0;
1612 status = AudioSystem::listAudioPatches(&numPatches,
1613 NULL,
1614 &generation1);
Eric Laurentb36d1042016-04-14 18:00:38 -07001615 if (status != NO_ERROR) {
Eric Laurentb69681c2014-05-19 19:02:51 -07001616 ALOGE_IF(status != NO_ERROR, "listAudioPatches AudioSystem::listAudioPatches error %d",
1617 status);
1618 break;
1619 }
Eric Laurentb36d1042016-04-14 18:00:38 -07001620 if (numPatches == 0) {
1621 jStatus = (jint)AUDIO_JAVA_SUCCESS;
1622 goto exit;
1623 }
1624
Eric Laurentb69681c2014-05-19 19:02:51 -07001625 nPatches = (struct audio_patch *)realloc(nPatches, numPatches * sizeof(struct audio_patch));
1626
1627 status = AudioSystem::listAudioPatches(&numPatches,
1628 nPatches,
1629 &generation);
1630 ALOGV("listAudioPatches AudioSystem::listAudioPatches numPatches %d generation %d generation1 %d",
1631 numPatches, generation, generation1);
1632
1633 } while (generation1 != generation && status == NO_ERROR);
1634
Eric Laurentb36d1042016-04-14 18:00:38 -07001635 jStatus = nativeToJavaStatus(status);
Eric Laurentb69681c2014-05-19 19:02:51 -07001636 if (jStatus != AUDIO_JAVA_SUCCESS) {
1637 goto exit;
1638 }
1639
Eric Laurentb69681c2014-05-19 19:02:51 -07001640 for (size_t i = 0; i < numPatches; i++) {
1641 jobject patchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1642 nPatches[i].id);
1643 if (patchHandle == NULL) {
1644 jStatus = AUDIO_JAVA_ERROR;
1645 goto exit;
1646 }
Dan Albert46d84442014-11-18 16:07:51 -08001647 ALOGV("listAudioPatches patch %zu num_sources %d num_sinks %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001648 i, nPatches[i].num_sources, nPatches[i].num_sinks);
1649
1650 env->SetIntField(patchHandle, gAudioHandleFields.mId, nPatches[i].id);
1651
1652 // load sources
1653 jSources = env->NewObjectArray(nPatches[i].num_sources,
1654 gAudioPortConfigClass, NULL);
1655 if (jSources == NULL) {
1656 jStatus = AUDIO_JAVA_ERROR;
1657 goto exit;
1658 }
1659
1660 for (size_t j = 0; j < nPatches[i].num_sources; j++) {
1661 jStatus = convertAudioPortConfigFromNative(env,
1662 NULL,
1663 &jSource,
1664 &nPatches[i].sources[j]);
1665 if (jStatus != AUDIO_JAVA_SUCCESS) {
1666 goto exit;
1667 }
1668 env->SetObjectArrayElement(jSources, j, jSource);
1669 env->DeleteLocalRef(jSource);
1670 jSource = NULL;
Dan Albert46d84442014-11-18 16:07:51 -08001671 ALOGV("listAudioPatches patch %zu source %zu is a %s handle %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001672 i, j,
1673 nPatches[i].sources[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1674 nPatches[i].sources[j].id);
1675 }
1676 // load sinks
1677 jSinks = env->NewObjectArray(nPatches[i].num_sinks,
1678 gAudioPortConfigClass, NULL);
1679 if (jSinks == NULL) {
1680 jStatus = AUDIO_JAVA_ERROR;
1681 goto exit;
1682 }
1683
1684 for (size_t j = 0; j < nPatches[i].num_sinks; j++) {
1685 jStatus = convertAudioPortConfigFromNative(env,
1686 NULL,
1687 &jSink,
1688 &nPatches[i].sinks[j]);
1689
1690 if (jStatus != AUDIO_JAVA_SUCCESS) {
1691 goto exit;
1692 }
1693 env->SetObjectArrayElement(jSinks, j, jSink);
1694 env->DeleteLocalRef(jSink);
1695 jSink = NULL;
Dan Albert46d84442014-11-18 16:07:51 -08001696 ALOGV("listAudioPatches patch %zu sink %zu is a %s handle %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001697 i, j,
1698 nPatches[i].sinks[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1699 nPatches[i].sinks[j].id);
1700 }
1701
1702 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor,
1703 patchHandle, jSources, jSinks);
1704 env->DeleteLocalRef(jSources);
1705 jSources = NULL;
1706 env->DeleteLocalRef(jSinks);
1707 jSinks = NULL;
1708 if (jPatch == NULL) {
1709 jStatus = AUDIO_JAVA_ERROR;
1710 goto exit;
1711 }
1712 env->CallBooleanMethod(jPatches, gArrayListMethods.add, jPatch);
1713 env->DeleteLocalRef(jPatch);
1714 jPatch = NULL;
1715 }
1716
1717exit:
Eric Laurentb36d1042016-04-14 18:00:38 -07001718
1719 nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1720 if (nGeneration == NULL) {
1721 jStatus = AUDIO_JAVA_ERROR;
1722 } else {
1723 nGeneration[0] = generation1;
1724 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1725 }
1726
Eric Laurentb69681c2014-05-19 19:02:51 -07001727 if (jSources != NULL) {
1728 env->DeleteLocalRef(jSources);
1729 }
1730 if (jSource != NULL) {
1731 env->DeleteLocalRef(jSource);
1732 }
1733 if (jSinks != NULL) {
1734 env->DeleteLocalRef(jSinks);
1735 }
1736 if (jSink != NULL) {
1737 env->DeleteLocalRef(jSink);
1738 }
1739 if (jPatch != NULL) {
1740 env->DeleteLocalRef(jPatch);
1741 }
1742 free(nPatches);
1743 return jStatus;
1744}
1745
Eric Laurent3a241992014-05-19 19:33:26 -07001746static jint
1747android_media_AudioSystem_setAudioPortConfig(JNIEnv *env, jobject clazz,
1748 jobject jAudioPortConfig)
1749{
1750 ALOGV("setAudioPortConfig");
1751 if (jAudioPortConfig == NULL) {
1752 return AUDIO_JAVA_BAD_VALUE;
1753 }
1754 if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
1755 return AUDIO_JAVA_BAD_VALUE;
1756 }
Mikhail Naganov304eafc2018-05-23 16:54:12 -07001757 struct audio_port_config nAudioPortConfig = {};
Eric Laurent6368a7d2014-11-19 12:18:32 -08001758 jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig, true);
Eric Laurent3a241992014-05-19 19:33:26 -07001759 if (jStatus != AUDIO_JAVA_SUCCESS) {
1760 return jStatus;
1761 }
1762 status_t status = AudioSystem::setAudioPortConfig(&nAudioPortConfig);
1763 ALOGV("AudioSystem::setAudioPortConfig() returned %d", status);
1764 jStatus = nativeToJavaStatus(status);
1765 return jStatus;
1766}
1767
Hongwei Wangf44a5682018-08-24 10:37:56 -07001768/**
1769 * Returns handle if the audio source is successfully started.
1770 */
1771static jint
1772android_media_AudioSystem_startAudioSource(JNIEnv *env, jobject clazz,
1773 jobject jAudioPortConfig,
1774 jobject jAudioAttributes)
1775{
1776 ALOGV("startAudioSource");
1777 if (jAudioPortConfig == NULL || jAudioAttributes == NULL) {
1778 return AUDIO_JAVA_BAD_VALUE;
1779 }
1780 if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
1781 return AUDIO_JAVA_BAD_VALUE;
1782 }
Hongwei Wangf44a5682018-08-24 10:37:56 -07001783 struct audio_port_config nAudioPortConfig = {};
1784 jint jStatus = convertAudioPortConfigToNativeWithDevicePort(env,
1785 &nAudioPortConfig, jAudioPortConfig, false);
1786 if (jStatus != AUDIO_JAVA_SUCCESS) {
1787 return jStatus;
1788 }
François Gaffieb4691282018-07-09 13:07:32 +02001789 auto paa = JNIAudioAttributeHelper::makeUnique();
1790 jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAudioAttributes, paa.get());
1791 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
Hongwei Wangf44a5682018-08-24 10:37:56 -07001792 return jStatus;
1793 }
1794 audio_port_handle_t handle;
François Gaffieb4691282018-07-09 13:07:32 +02001795 status_t status = AudioSystem::startAudioSource(&nAudioPortConfig, paa.get(), &handle);
Hongwei Wangf44a5682018-08-24 10:37:56 -07001796 ALOGV("AudioSystem::startAudioSource() returned %d handle %d", status, handle);
1797 return handle > 0 ? handle : nativeToJavaStatus(status);
1798}
1799
1800static jint
1801android_media_AudioSystem_stopAudioSource(JNIEnv *env, jobject clazz, jint handle)
1802{
1803 ALOGV("stopAudioSource");
1804 status_t status = AudioSystem::stopAudioSource(
1805 static_cast <audio_port_handle_t>(handle));
1806 ALOGV("AudioSystem::stopAudioSource() returned %d", status);
1807 return nativeToJavaStatus(status);
1808}
1809
Eric Laurent700e7342014-05-02 18:33:15 -07001810static void
1811android_media_AudioSystem_eventHandlerSetup(JNIEnv *env, jobject thiz, jobject weak_this)
1812{
1813 ALOGV("eventHandlerSetup");
1814
1815 sp<JNIAudioPortCallback> callback = new JNIAudioPortCallback(env, thiz, weak_this);
1816
Eric Laurent2615afb2015-03-25 14:51:08 -07001817 if (AudioSystem::addAudioPortCallback(callback) == NO_ERROR) {
1818 setJniCallback(env, thiz, callback);
1819 }
Eric Laurent700e7342014-05-02 18:33:15 -07001820}
1821
1822static void
1823android_media_AudioSystem_eventHandlerFinalize(JNIEnv *env, jobject thiz)
1824{
1825 ALOGV("eventHandlerFinalize");
1826
Eric Laurent2615afb2015-03-25 14:51:08 -07001827 sp<JNIAudioPortCallback> callback = setJniCallback(env, thiz, 0);
Eric Laurent700e7342014-05-02 18:33:15 -07001828
Eric Laurent2615afb2015-03-25 14:51:08 -07001829 if (callback != 0) {
1830 AudioSystem::removeAudioPortCallback(callback);
1831 }
Eric Laurent700e7342014-05-02 18:33:15 -07001832}
1833
Eric Laurentb634e1b2014-08-01 14:44:46 -07001834static jint
1835android_media_AudioSystem_getAudioHwSyncForSession(JNIEnv *env, jobject thiz, jint sessionId)
1836{
Glenn Kasten33b84042016-03-08 12:02:55 -08001837 return (jint) AudioSystem::getAudioHwSyncForSession((audio_session_t) sessionId);
Eric Laurentb634e1b2014-08-01 14:44:46 -07001838}
1839
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07001840static void
1841android_media_AudioSystem_registerDynPolicyCallback(JNIEnv *env, jobject thiz)
1842{
1843 AudioSystem::setDynPolicyCallback(android_media_AudioSystem_dyn_policy_callback);
1844}
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001845
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08001846static void
1847android_media_AudioSystem_registerRecordingCallback(JNIEnv *env, jobject thiz)
1848{
1849 AudioSystem::setRecordConfigCallback(android_media_AudioSystem_recording_callback);
1850}
1851
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001852
1853static jint convertAudioMixToNative(JNIEnv *env,
1854 AudioMix *nAudioMix,
1855 const jobject jAudioMix)
1856{
1857 nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType);
1858 nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags);
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07001859 nAudioMix->mDeviceType = (audio_devices_t)
1860 env->GetIntField(jAudioMix, gAudioMixFields.mDeviceType);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001861
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07001862 jstring jDeviceAddress = (jstring)env->GetObjectField(jAudioMix,
1863 gAudioMixFields.mDeviceAddress);
1864 const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
1865 nAudioMix->mDeviceAddress = String8(nDeviceAddress);
1866 env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
1867 env->DeleteLocalRef(jDeviceAddress);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001868
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07001869 nAudioMix->mCbFlags = env->GetIntField(jAudioMix, gAudioMixFields.mCallbackFlags);
1870
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001871 jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat);
1872 nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat,
1873 gAudioFormatFields.mSampleRate);
1874 nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat,
1875 gAudioFormatFields.mChannelMask));
1876 nAudioMix->mFormat.format = audioFormatToNative(env->GetIntField(jFormat,
1877 gAudioFormatFields.mEncoding));
1878 env->DeleteLocalRef(jFormat);
1879
1880 jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule);
1881 jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria);
Kevin Rocarda3a4bbb2019-03-07 18:29:48 -08001882 nAudioMix->mAllowPrivilegedPlaybackCapture =
1883 env->GetBooleanField(jRule, gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001884 env->DeleteLocalRef(jRule);
1885 jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria,
1886 gArrayListMethods.toArray);
1887 env->DeleteLocalRef(jRuleCriteria);
1888
1889 jint numCriteria = env->GetArrayLength(jCriteria);
1890 if (numCriteria > MAX_CRITERIA_PER_MIX) {
1891 numCriteria = MAX_CRITERIA_PER_MIX;
1892 }
1893
1894 for (jint i = 0; i < numCriteria; i++) {
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001895 AudioMixMatchCriterion nCriterion;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001896
1897 jobject jCriterion = env->GetObjectArrayElement(jCriteria, i);
1898
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001899 nCriterion.mRule = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mRule);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001900
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001901 const uint32_t match_rule = nCriterion.mRule & ~RULE_EXCLUSION_MASK;
1902 switch (match_rule) {
1903 case RULE_MATCH_UID:
1904 nCriterion.mValue.mUid = env->GetIntField(jCriterion,
1905 gAudioMixMatchCriterionFields.mIntProp);
1906 break;
1907 case RULE_MATCH_ATTRIBUTE_USAGE:
1908 case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: {
1909 jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr);
François Gaffieb4691282018-07-09 13:07:32 +02001910
1911 auto paa = JNIAudioAttributeHelper::makeUnique();
1912 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAttributes, paa.get());
1913 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
1914 return jStatus;
1915 }
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001916 if (match_rule == RULE_MATCH_ATTRIBUTE_USAGE) {
François Gaffieb4691282018-07-09 13:07:32 +02001917 nCriterion.mValue.mUsage = paa->usage;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001918 } else {
François Gaffieb4691282018-07-09 13:07:32 +02001919 nCriterion.mValue.mSource = paa->source;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001920 }
1921 env->DeleteLocalRef(jAttributes);
1922 }
1923 break;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001924 }
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001925
1926 nAudioMix->mCriteria.add(nCriterion);
1927 env->DeleteLocalRef(jCriterion);
1928 }
1929
1930 env->DeleteLocalRef(jCriteria);
1931
1932 return (jint)AUDIO_JAVA_SUCCESS;
1933}
1934
1935static jint
1936android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz,
1937 jobject jMixesList, jboolean registration)
1938{
1939 ALOGV("registerPolicyMixes");
1940
1941 if (jMixesList == NULL) {
1942 return (jint)AUDIO_JAVA_BAD_VALUE;
1943 }
1944 if (!env->IsInstanceOf(jMixesList, gArrayListClass)) {
1945 return (jint)AUDIO_JAVA_BAD_VALUE;
1946 }
1947 jobjectArray jMixes = (jobjectArray)env->CallObjectMethod(jMixesList,
1948 gArrayListMethods.toArray);
1949 jint numMixes = env->GetArrayLength(jMixes);
1950 if (numMixes > MAX_MIXES_PER_POLICY) {
1951 numMixes = MAX_MIXES_PER_POLICY;
1952 }
1953
1954 status_t status;
1955 jint jStatus;
1956 jobject jAudioMix = NULL;
1957 Vector <AudioMix> mixes;
1958 for (jint i = 0; i < numMixes; i++) {
1959 jAudioMix = env->GetObjectArrayElement(jMixes, i);
1960 if (!env->IsInstanceOf(jAudioMix, gAudioMixClass)) {
1961 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1962 goto exit;
1963 }
1964 AudioMix mix;
1965 jStatus = convertAudioMixToNative(env, &mix, jAudioMix);
1966 env->DeleteLocalRef(jAudioMix);
1967 jAudioMix = NULL;
1968 if (jStatus != AUDIO_JAVA_SUCCESS) {
1969 goto exit;
1970 }
1971 mixes.add(mix);
1972 }
1973
1974 ALOGV("AudioSystem::registerPolicyMixes numMixes %d registration %d", numMixes, registration);
1975 status = AudioSystem::registerPolicyMixes(mixes, registration);
1976 ALOGV("AudioSystem::registerPolicyMixes() returned %d", status);
1977
1978 jStatus = nativeToJavaStatus(status);
1979 if (jStatus != AUDIO_JAVA_SUCCESS) {
1980 goto exit;
1981 }
1982
1983exit:
1984 if (jAudioMix != NULL) {
1985 env->DeleteLocalRef(jAudioMix);
1986 }
1987 return jStatus;
1988}
1989
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08001990static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz,
1991 jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) {
1992 if (deviceTypes == nullptr || deviceAddresses == nullptr) {
1993 return (jint) AUDIO_JAVA_BAD_VALUE;
1994 }
1995 jsize nb = env->GetArrayLength(deviceTypes);
1996 if (nb == 0 || nb != env->GetArrayLength(deviceAddresses)) {
1997 return (jint) AUDIO_JAVA_BAD_VALUE;
1998 }
1999 // retrieve all device types
2000 std::vector<audio_devices_t> deviceTypesVector;
2001 jint* typesPtr = nullptr;
2002 typesPtr = env->GetIntArrayElements(deviceTypes, 0);
2003 if (typesPtr == nullptr) {
2004 return (jint) AUDIO_JAVA_BAD_VALUE;
2005 }
2006 for (jint i = 0; i < nb; i++) {
2007 deviceTypesVector.push_back((audio_devices_t) typesPtr[i]);
2008 }
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002009
2010 // check each address is a string and add device type/address to list for device affinity
2011 Vector<AudioDeviceTypeAddr> deviceVector;
2012 jclass stringClass = FindClassOrDie(env, "java/lang/String");
2013 for (jint i = 0; i < nb; i++) {
2014 jobject addrJobj = env->GetObjectArrayElement(deviceAddresses, i);
2015 if (!env->IsInstanceOf(addrJobj, stringClass)) {
2016 return (jint) AUDIO_JAVA_BAD_VALUE;
2017 }
2018 String8 address = String8(env->GetStringUTFChars((jstring) addrJobj, NULL));
2019 AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address);
2020 deviceVector.add(dev);
2021 }
Hongwei Wang94d58002019-02-13 16:59:32 -08002022 env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0);
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002023
2024 status_t status = AudioSystem::setUidDeviceAffinities((uid_t) uid, deviceVector);
2025 return (jint) nativeToJavaStatus(status);
2026}
2027
2028static jint android_media_AudioSystem_removeUidDeviceAffinities(JNIEnv *env, jobject clazz,
2029 jint uid) {
2030
2031 //###
2032 status_t status = NO_ERROR;//AudioSystem::removeUidDeviceAffinities();
2033 return (jint) nativeToJavaStatus(status);
2034}
2035
2036
Eric Laurent0867bed2015-05-20 14:49:08 -07002037static jint
2038android_media_AudioSystem_systemReady(JNIEnv *env, jobject thiz)
2039{
2040 return nativeToJavaStatus(AudioSystem::systemReady());
2041}
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002042
Eric Laurenteab40d12017-06-09 12:45:21 -07002043static jfloat
2044android_media_AudioSystem_getStreamVolumeDB(JNIEnv *env, jobject thiz,
2045 jint stream, jint index, jint device)
2046{
2047 return (jfloat)AudioSystem::getStreamVolumeDB((audio_stream_type_t)stream,
2048 (int)index,
2049 (audio_devices_t)device);
2050}
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002051
Jean-Michel Trivi980d38f2018-01-08 15:43:35 -08002052static jboolean
2053android_media_AudioSystem_isOffloadSupported(JNIEnv *env, jobject thiz,
Jean-Michel Trivif3fd84a2019-03-21 16:08:50 -07002054 jint encoding, jint sampleRate, jint channelMask, jint channelIndexMask, jint streamType)
Jean-Michel Trivi980d38f2018-01-08 15:43:35 -08002055{
2056 audio_offload_info_t format = AUDIO_INFO_INITIALIZER;
2057 format.format = (audio_format_t) audioFormatToNative(encoding);
2058 format.sample_rate = (uint32_t) sampleRate;
2059 format.channel_mask = nativeChannelMaskFromJavaChannelMasks(channelMask, channelIndexMask);
Jean-Michel Trivif3fd84a2019-03-21 16:08:50 -07002060 format.stream_type = (audio_stream_type_t) streamType;
Jean-Michel Trivi980d38f2018-01-08 15:43:35 -08002061 format.has_video = false;
2062 format.is_streaming = false;
2063 // offload duration unknown at this point:
2064 // client side code cannot access "audio.offload.min.duration.secs" property to make a query
2065 // agnostic of duration, so using acceptable estimate of 2mn
2066 format.duration_us = 120 * 1000000;
2067 return AudioSystem::isOffloadSupported(format);
2068}
2069
jiabinc0f49442018-01-05 10:23:50 -08002070static jint
2071android_media_AudioSystem_getMicrophones(JNIEnv *env, jobject thiz, jobject jMicrophonesInfo)
2072{
2073 ALOGV("getMicrophones");
2074
2075 if (jMicrophonesInfo == NULL) {
2076 ALOGE("jMicrophonesInfo NULL MicrophoneInfo ArrayList");
2077 return (jint)AUDIO_JAVA_BAD_VALUE;
2078 }
2079 if (!env->IsInstanceOf(jMicrophonesInfo, gArrayListClass)) {
2080 ALOGE("getMicrophones not an arraylist");
2081 return (jint)AUDIO_JAVA_BAD_VALUE;
2082 }
2083
2084 jint jStatus;
2085 std::vector<media::MicrophoneInfo> microphones;
2086 status_t status = AudioSystem::getMicrophones(&microphones);
2087 if (status != NO_ERROR) {
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002088 ALOGE("AudioSystem::getMicrophones error %d", status);
jiabinc0f49442018-01-05 10:23:50 -08002089 jStatus = nativeToJavaStatus(status);
2090 return jStatus;
2091 }
2092 if (microphones.size() == 0) {
2093 jStatus = (jint)AUDIO_JAVA_SUCCESS;
2094 return jStatus;
2095 }
2096 for (size_t i = 0; i < microphones.size(); i++) {
2097 jobject jMicrophoneInfo;
2098 jStatus = convertMicrophoneInfoFromNative(env, &jMicrophoneInfo, &microphones[i]);
2099 if (jStatus != AUDIO_JAVA_SUCCESS) {
2100 return jStatus;
2101 }
2102 env->CallBooleanMethod(jMicrophonesInfo, gArrayListMethods.add, jMicrophoneInfo);
2103 env->DeleteLocalRef(jMicrophoneInfo);
2104 }
2105
2106 return jStatus;
2107}
2108
jiabin39940752018-04-02 18:18:45 -07002109static jint
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002110android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP(
2111 JNIEnv *env, jobject thiz, jobject jEncodingFormatList)
2112{
2113 ALOGV("%s", __FUNCTION__);
2114 jint jStatus = AUDIO_JAVA_SUCCESS;
2115 if (!env->IsInstanceOf(jEncodingFormatList, gArrayListClass)) {
2116 ALOGE("%s: jEncodingFormatList not an ArrayList", __FUNCTION__);
2117 return (jint)AUDIO_JAVA_BAD_VALUE;
2118 }
2119 std::vector<audio_format_t> encodingFormats;
Eric Laurentfffeac82019-01-17 09:03:47 -08002120 status_t status = AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP(
2121 &encodingFormats);
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002122 if (status != NO_ERROR) {
2123 ALOGE("%s: error %d", __FUNCTION__, status);
2124 jStatus = nativeToJavaStatus(status);
2125 return jStatus;
2126 }
2127
2128 for (size_t i = 0; i < encodingFormats.size(); i++) {
2129 ScopedLocalRef<jobject> jEncodingFormat(
2130 env, env->NewObject(gIntegerClass, gIntegerCstor, encodingFormats[i]));
2131 env->CallBooleanMethod(jEncodingFormatList, gArrayListMethods.add,
2132 jEncodingFormat.get());
2133 }
2134 return jStatus;
2135}
2136
2137static jint
jiabin39940752018-04-02 18:18:45 -07002138android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
2139 jobject jSurroundFormats, jboolean reported)
2140{
2141 ALOGV("getSurroundFormats");
2142
2143 if (jSurroundFormats == NULL) {
2144 ALOGE("jSurroundFormats is NULL");
2145 return (jint)AUDIO_JAVA_BAD_VALUE;
2146 }
2147 if (!env->IsInstanceOf(jSurroundFormats, gMapClass)) {
2148 ALOGE("getSurroundFormats not a map");
2149 return (jint)AUDIO_JAVA_BAD_VALUE;
2150 }
2151
2152 jint jStatus;
2153 unsigned int numSurroundFormats = 0;
2154 audio_format_t *surroundFormats = NULL;
2155 bool *surroundFormatsEnabled = NULL;
2156 status_t status = AudioSystem::getSurroundFormats(
2157 &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
2158 if (status != NO_ERROR) {
2159 ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
2160 jStatus = nativeToJavaStatus(status);
2161 goto exit;
2162 }
2163 if (numSurroundFormats == 0) {
2164 jStatus = (jint)AUDIO_JAVA_SUCCESS;
2165 goto exit;
2166 }
2167 surroundFormats = (audio_format_t *)calloc(numSurroundFormats, sizeof(audio_format_t));
2168 surroundFormatsEnabled = (bool *)calloc(numSurroundFormats, sizeof(bool));
2169 status = AudioSystem::getSurroundFormats(
2170 &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
2171 jStatus = nativeToJavaStatus(status);
2172 if (status != NO_ERROR) {
2173 ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
2174 goto exit;
2175 }
2176 for (size_t i = 0; i < numSurroundFormats; i++) {
2177 jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor,
2178 audioFormatFromNative(surroundFormats[i]));
2179 jobject enabled = env->NewObject(gBooleanClass, gBooleanCstor, surroundFormatsEnabled[i]);
2180 env->CallObjectMethod(jSurroundFormats, gMapPut, surroundFormat, enabled);
2181 env->DeleteLocalRef(surroundFormat);
2182 env->DeleteLocalRef(enabled);
2183 }
2184
2185exit:
2186 free(surroundFormats);
2187 free(surroundFormatsEnabled);
2188 return jStatus;
2189}
2190
2191static jint
2192android_media_AudioSystem_setSurroundFormatEnabled(JNIEnv *env, jobject thiz,
2193 jint audioFormat, jboolean enabled)
2194{
2195 status_t status = AudioSystem::setSurroundFormatEnabled(audioFormatToNative(audioFormat),
2196 (bool)enabled);
2197 if (status != NO_ERROR) {
2198 ALOGE_IF(status != NO_ERROR, "AudioSystem::setSurroundFormatEnabled error %d", status);
2199 }
2200 return (jint)nativeToJavaStatus(status);
2201}
2202
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002203static jint android_media_AudioSystem_get_FCC_8(JNIEnv *env, jobject thiz) {
2204 return FCC_8;
2205}
2206
Eric Laurent1c9c1d52018-10-17 10:06:46 -07002207static jint
2208android_media_AudioSystem_setAssistantUid(JNIEnv *env, jobject thiz, jint uid)
2209{
2210 status_t status = AudioSystem::setAssistantUid(uid);
2211 return (jint)nativeToJavaStatus(status);
2212}
2213
2214static jint
2215android_media_AudioSystem_setA11yServicesUids(JNIEnv *env, jobject thiz, jintArray uids) {
2216 std::vector<uid_t> nativeUidsVector;
2217
2218 if (uids != nullptr) {
2219 jsize len = env->GetArrayLength(uids);
2220
2221 if (len > 0) {
2222 int *nativeUids = nullptr;
2223 nativeUids = env->GetIntArrayElements(uids, 0);
2224 if (nativeUids != nullptr) {
2225 for (size_t i = 0; i < len; i++) {
2226 nativeUidsVector.push_back(nativeUids[i]);
2227 }
2228 env->ReleaseIntArrayElements(uids, nativeUids, 0);
2229 }
2230 }
2231 }
2232 status_t status = AudioSystem::setA11yServicesUids(nativeUidsVector);
2233 return (jint)nativeToJavaStatus(status);
2234}
2235
jiabin66f9e722018-11-02 16:20:19 -07002236static jboolean
2237android_media_AudioSystem_isHapticPlaybackSupported(JNIEnv *env, jobject thiz)
2238{
2239 return AudioSystem::isHapticPlaybackSupported();
2240}
2241
Kevin Rocard7919c2a2019-03-21 10:28:01 -07002242static jint
2243android_media_AudioSystem_setAllowedCapturePolicy(JNIEnv *env, jobject thiz, jint uid, jint flags) {
2244 return AudioSystem::setAllowedCapturePolicy(uid, flags);
2245}
2246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002247// ----------------------------------------------------------------------------
2248
Daniel Micay76f6a862015-09-19 17:31:01 -04002249static const JNINativeMethod gMethods[] = {
Eric Laurenta553c252009-07-17 12:17:14 -07002250 {"setParameters", "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
2251 {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002252 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
2253 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
Jean-Michel Trivid6770542012-10-10 12:03:41 -07002254 {"isStreamActive", "(II)Z", (void *)android_media_AudioSystem_isStreamActive},
Jean-Michel Trivi679d5042013-02-04 16:24:09 -08002255 {"isStreamActiveRemotely","(II)Z", (void *)android_media_AudioSystem_isStreamActiveRemotely},
Jean-Michel Trivid6770542012-10-10 12:03:41 -07002256 {"isSourceActive", "(I)Z", (void *)android_media_AudioSystem_isSourceActive},
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -07002257 {"newAudioSessionId", "()I", (void *)android_media_AudioSystem_newAudioSessionId},
Jean-Michel Trivi292a6a42016-12-01 08:32:15 -08002258 {"newAudioPlayerId", "()I", (void *)android_media_AudioSystem_newAudioPlayerId},
Mikhail Naganova00883d2019-04-18 12:36:27 -07002259 {"newAudioRecorderId", "()I", (void *)android_media_AudioSystem_newAudioRecorderId},
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -08002260 {"setDeviceConnectionState", "(IILjava/lang/String;Ljava/lang/String;I)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
Eric Laurenta553c252009-07-17 12:17:14 -07002261 {"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -08002262 {"handleDeviceConfigChange", "(ILjava/lang/String;Ljava/lang/String;I)I", (void *)android_media_AudioSystem_handleDeviceConfigChange},
Eric Laurenta553c252009-07-17 12:17:14 -07002263 {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
Eric Laurenta553c252009-07-17 12:17:14 -07002264 {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
2265 {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
2266 {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume},
Eric Laurent9bc8358d2011-11-18 16:43:31 -08002267 {"setStreamVolumeIndex","(III)I", (void *)android_media_AudioSystem_setStreamVolumeIndex},
2268 {"getStreamVolumeIndex","(II)I", (void *)android_media_AudioSystem_getStreamVolumeIndex},
François Gaffieebb67d02018-09-14 15:05:04 +02002269 {"setVolumeIndexForAttributes","(Landroid/media/AudioAttributes;II)I", (void *)android_media_AudioSystem_setVolumeIndexForAttributes},
2270 {"getVolumeIndexForAttributes","(Landroid/media/AudioAttributes;I)I", (void *)android_media_AudioSystem_getVolumeIndexForAttributes},
2271 {"getMinVolumeIndexForAttributes","(Landroid/media/AudioAttributes;)I", (void *)android_media_AudioSystem_getMinVolumeIndexForAttributes},
2272 {"getMaxVolumeIndexForAttributes","(Landroid/media/AudioAttributes;)I", (void *)android_media_AudioSystem_getMaxVolumeIndexForAttributes},
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -04002273 {"setMasterVolume", "(F)I", (void *)android_media_AudioSystem_setMasterVolume},
2274 {"getMasterVolume", "()F", (void *)android_media_AudioSystem_getMasterVolume},
2275 {"setMasterMute", "(Z)I", (void *)android_media_AudioSystem_setMasterMute},
2276 {"getMasterMute", "()Z", (void *)android_media_AudioSystem_getMasterMute},
Andy Hungf04b84d2015-12-18 17:33:27 -08002277 {"setMasterMono", "(Z)I", (void *)android_media_AudioSystem_setMasterMono},
2278 {"getMasterMono", "()Z", (void *)android_media_AudioSystem_getMasterMono},
Edward Savage-Jones35c292f2017-01-13 09:04:34 +01002279 {"setMasterBalance", "(F)I", (void *)android_media_AudioSystem_setMasterBalance},
2280 {"getMasterBalance", "()F", (void *)android_media_AudioSystem_getMasterBalance},
Glenn Kasten8b4b97a2011-02-04 13:54:26 -08002281 {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream},
Glenn Kastenc6c43652012-09-24 17:32:30 -07002282 {"getPrimaryOutputSamplingRate", "()I", (void *)android_media_AudioSystem_getPrimaryOutputSamplingRate},
2283 {"getPrimaryOutputFrameCount", "()I", (void *)android_media_AudioSystem_getPrimaryOutputFrameCount},
Oliver Woodman61dcdf32013-06-26 12:43:36 +01002284 {"getOutputLatency", "(I)I", (void *)android_media_AudioSystem_getOutputLatency},
Andy Hung79583582018-01-23 13:58:02 -08002285 {"setLowRamDevice", "(ZJ)I", (void *)android_media_AudioSystem_setLowRamDevice},
Eric Laurentdfb881f2013-07-18 14:41:39 -07002286 {"checkAudioFlinger", "()I", (void *)android_media_AudioSystem_checkAudioFlinger},
Eric Laurentb69681c2014-05-19 19:02:51 -07002287 {"listAudioPorts", "(Ljava/util/ArrayList;[I)I",
2288 (void *)android_media_AudioSystem_listAudioPorts},
2289 {"createAudioPatch", "([Landroid/media/AudioPatch;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)I",
2290 (void *)android_media_AudioSystem_createAudioPatch},
2291 {"releaseAudioPatch", "(Landroid/media/AudioPatch;)I",
2292 (void *)android_media_AudioSystem_releaseAudioPatch},
2293 {"listAudioPatches", "(Ljava/util/ArrayList;[I)I",
2294 (void *)android_media_AudioSystem_listAudioPatches},
Eric Laurent3a241992014-05-19 19:33:26 -07002295 {"setAudioPortConfig", "(Landroid/media/AudioPortConfig;)I",
2296 (void *)android_media_AudioSystem_setAudioPortConfig},
Hongwei Wangf44a5682018-08-24 10:37:56 -07002297 {"startAudioSource", "(Landroid/media/AudioPortConfig;Landroid/media/AudioAttributes;)I",
2298 (void *)android_media_AudioSystem_startAudioSource},
2299 {"stopAudioSource", "(I)I", (void *)android_media_AudioSystem_stopAudioSource},
Eric Laurentb634e1b2014-08-01 14:44:46 -07002300 {"getAudioHwSyncForSession", "(I)I",
2301 (void *)android_media_AudioSystem_getAudioHwSyncForSession},
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002302 {"registerPolicyMixes", "(Ljava/util/ArrayList;Z)I",
2303 (void *)android_media_AudioSystem_registerPolicyMixes},
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002304 {"setUidDeviceAffinities", "(I[I[Ljava/lang/String;)I",
2305 (void *)android_media_AudioSystem_setUidDeviceAffinities},
2306 {"removeUidDeviceAffinities", "(I)I",
2307 (void *)android_media_AudioSystem_removeUidDeviceAffinities},
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002308 {"native_register_dynamic_policy_callback", "()V",
2309 (void *)android_media_AudioSystem_registerDynPolicyCallback},
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002310 {"native_register_recording_callback", "()V",
2311 (void *)android_media_AudioSystem_registerRecordingCallback},
Eric Laurent0867bed2015-05-20 14:49:08 -07002312 {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady},
Eric Laurenteab40d12017-06-09 12:45:21 -07002313 {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
Jean-Michel Trivif3fd84a2019-03-21 16:08:50 -07002314 {"native_is_offload_supported", "(IIIII)Z", (void *)android_media_AudioSystem_isOffloadSupported},
jiabinc0f49442018-01-05 10:23:50 -08002315 {"getMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioSystem_getMicrophones},
jiabin39940752018-04-02 18:18:45 -07002316 {"getSurroundFormats", "(Ljava/util/Map;Z)I", (void *)android_media_AudioSystem_getSurroundFormats},
2317 {"setSurroundFormatEnabled", "(IZ)I", (void *)android_media_AudioSystem_setSurroundFormatEnabled},
Eric Laurent1c9c1d52018-10-17 10:06:46 -07002318 {"setAssistantUid", "(I)I", (void *)android_media_AudioSystem_setAssistantUid},
2319 {"setA11yServicesUids", "([I)I", (void *)android_media_AudioSystem_setA11yServicesUids},
jiabin66f9e722018-11-02 16:20:19 -07002320 {"isHapticPlaybackSupported", "()Z", (void *)android_media_AudioSystem_isHapticPlaybackSupported},
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002321 {"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
2322 (void*)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
Kevin Rocard7919c2a2019-03-21 10:28:01 -07002323 {"setAllowedCapturePolicy", "(II)I", (void *)android_media_AudioSystem_setAllowedCapturePolicy},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324};
2325
Daniel Micay76f6a862015-09-19 17:31:01 -04002326static const JNINativeMethod gEventHandlerMethods[] = {
Eric Laurent700e7342014-05-02 18:33:15 -07002327 {"native_setup",
2328 "(Ljava/lang/Object;)V",
2329 (void *)android_media_AudioSystem_eventHandlerSetup},
2330 {"native_finalize",
2331 "()V",
2332 (void *)android_media_AudioSystem_eventHandlerFinalize},
2333};
2334
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002335static const JNINativeMethod gGetFCC8Methods[] = {
2336 {"native_get_FCC_8", "()I", (void *)android_media_AudioSystem_get_FCC_8},
2337};
2338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002339int register_android_media_AudioSystem(JNIEnv *env)
2340{
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002341 // This needs to be done before hooking up methods AudioTrackRoutingProxy (below)
2342 RegisterMethodsOrDie(env, kClassPathName, gGetFCC8Methods, NELEM(gGetFCC8Methods));
2343
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002344 jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
2345 gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
2346 gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
Eric Laurent09378972014-12-10 10:42:08 -08002347 gArrayListMethods.toArray = GetMethodIDOrDie(env, arrayListClass, "toArray", "()[Ljava/lang/Object;");
Eric Laurentb69681c2014-05-19 19:02:51 -07002348
jiabin39940752018-04-02 18:18:45 -07002349 jclass booleanClass = FindClassOrDie(env, "java/lang/Boolean");
2350 gBooleanClass = MakeGlobalRefOrDie(env, booleanClass);
2351 gBooleanCstor = GetMethodIDOrDie(env, booleanClass, "<init>", "(Z)V");
2352
2353 jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
2354 gIntegerClass = MakeGlobalRefOrDie(env, integerClass);
2355 gIntegerCstor = GetMethodIDOrDie(env, integerClass, "<init>", "(I)V");
2356
2357 jclass mapClass = FindClassOrDie(env, "java/util/Map");
2358 gMapClass = MakeGlobalRefOrDie(env, mapClass);
2359 gMapPut = GetMethodIDOrDie(env, mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
2360
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002361 jclass audioHandleClass = FindClassOrDie(env, "android/media/AudioHandle");
2362 gAudioHandleClass = MakeGlobalRefOrDie(env, audioHandleClass);
2363 gAudioHandleCstor = GetMethodIDOrDie(env, audioHandleClass, "<init>", "(I)V");
2364 gAudioHandleFields.mId = GetFieldIDOrDie(env, audioHandleClass, "mId", "I");
Eric Laurentb69681c2014-05-19 19:02:51 -07002365
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002366 jclass audioPortClass = FindClassOrDie(env, "android/media/AudioPort");
2367 gAudioPortClass = MakeGlobalRefOrDie(env, audioPortClass);
2368 gAudioPortCstor = GetMethodIDOrDie(env, audioPortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002369 "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002370 gAudioPortFields.mHandle = GetFieldIDOrDie(env, audioPortClass, "mHandle",
Eric Laurentb69681c2014-05-19 19:02:51 -07002371 "Landroid/media/AudioHandle;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002372 gAudioPortFields.mRole = GetFieldIDOrDie(env, audioPortClass, "mRole", "I");
2373 gAudioPortFields.mGains = GetFieldIDOrDie(env, audioPortClass, "mGains",
Eric Laurentb69681c2014-05-19 19:02:51 -07002374 "[Landroid/media/AudioGain;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002375 gAudioPortFields.mActiveConfig = GetFieldIDOrDie(env, audioPortClass, "mActiveConfig",
2376 "Landroid/media/AudioPortConfig;");
Eric Laurentb69681c2014-05-19 19:02:51 -07002377
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002378 jclass audioPortConfigClass = FindClassOrDie(env, "android/media/AudioPortConfig");
2379 gAudioPortConfigClass = MakeGlobalRefOrDie(env, audioPortConfigClass);
2380 gAudioPortConfigCstor = GetMethodIDOrDie(env, audioPortConfigClass, "<init>",
2381 "(Landroid/media/AudioPort;IIILandroid/media/AudioGainConfig;)V");
2382 gAudioPortConfigFields.mPort = GetFieldIDOrDie(env, audioPortConfigClass, "mPort",
Eric Laurentb69681c2014-05-19 19:02:51 -07002383 "Landroid/media/AudioPort;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002384 gAudioPortConfigFields.mSamplingRate = GetFieldIDOrDie(env, audioPortConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002385 "mSamplingRate", "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002386 gAudioPortConfigFields.mChannelMask = GetFieldIDOrDie(env, audioPortConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002387 "mChannelMask", "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002388 gAudioPortConfigFields.mFormat = GetFieldIDOrDie(env, audioPortConfigClass, "mFormat", "I");
2389 gAudioPortConfigFields.mGain = GetFieldIDOrDie(env, audioPortConfigClass, "mGain",
Eric Laurentb69681c2014-05-19 19:02:51 -07002390 "Landroid/media/AudioGainConfig;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002391 gAudioPortConfigFields.mConfigMask = GetFieldIDOrDie(env, audioPortConfigClass, "mConfigMask",
2392 "I");
Eric Laurentb69681c2014-05-19 19:02:51 -07002393
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002394 jclass audioDevicePortConfigClass = FindClassOrDie(env, "android/media/AudioDevicePortConfig");
2395 gAudioDevicePortConfigClass = MakeGlobalRefOrDie(env, audioDevicePortConfigClass);
2396 gAudioDevicePortConfigCstor = GetMethodIDOrDie(env, audioDevicePortConfigClass, "<init>",
2397 "(Landroid/media/AudioDevicePort;IIILandroid/media/AudioGainConfig;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002398
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002399 jclass audioMixPortConfigClass = FindClassOrDie(env, "android/media/AudioMixPortConfig");
2400 gAudioMixPortConfigClass = MakeGlobalRefOrDie(env, audioMixPortConfigClass);
2401 gAudioMixPortConfigCstor = GetMethodIDOrDie(env, audioMixPortConfigClass, "<init>",
2402 "(Landroid/media/AudioMixPort;IIILandroid/media/AudioGainConfig;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002403
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002404 jclass audioDevicePortClass = FindClassOrDie(env, "android/media/AudioDevicePort");
2405 gAudioDevicePortClass = MakeGlobalRefOrDie(env, audioDevicePortClass);
2406 gAudioDevicePortCstor = GetMethodIDOrDie(env, audioDevicePortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002407 "(Landroid/media/AudioHandle;Ljava/lang/String;[I[I[I[I[Landroid/media/AudioGain;ILjava/lang/String;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002408
Hongwei Wangf44a5682018-08-24 10:37:56 -07002409 // When access AudioPort as AudioDevicePort
2410 gAudioPortFields.mType = GetFieldIDOrDie(env, audioDevicePortClass, "mType", "I");
2411 gAudioPortFields.mAddress = GetFieldIDOrDie(env, audioDevicePortClass, "mAddress",
2412 "Ljava/lang/String;");
2413
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002414 jclass audioMixPortClass = FindClassOrDie(env, "android/media/AudioMixPort");
2415 gAudioMixPortClass = MakeGlobalRefOrDie(env, audioMixPortClass);
2416 gAudioMixPortCstor = GetMethodIDOrDie(env, audioMixPortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002417 "(Landroid/media/AudioHandle;IILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002418
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002419 jclass audioGainClass = FindClassOrDie(env, "android/media/AudioGain");
2420 gAudioGainClass = MakeGlobalRefOrDie(env, audioGainClass);
2421 gAudioGainCstor = GetMethodIDOrDie(env, audioGainClass, "<init>", "(IIIIIIIII)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002422
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002423 jclass audioGainConfigClass = FindClassOrDie(env, "android/media/AudioGainConfig");
2424 gAudioGainConfigClass = MakeGlobalRefOrDie(env, audioGainConfigClass);
2425 gAudioGainConfigCstor = GetMethodIDOrDie(env, audioGainConfigClass, "<init>",
Eric Laurentb69681c2014-05-19 19:02:51 -07002426 "(ILandroid/media/AudioGain;II[II)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002427 gAudioGainConfigFields.mIndex = GetFieldIDOrDie(env, gAudioGainConfigClass, "mIndex", "I");
2428 gAudioGainConfigFields.mMode = GetFieldIDOrDie(env, audioGainConfigClass, "mMode", "I");
2429 gAudioGainConfigFields.mChannelMask = GetFieldIDOrDie(env, audioGainConfigClass, "mChannelMask",
Eric Laurentb69681c2014-05-19 19:02:51 -07002430 "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002431 gAudioGainConfigFields.mValues = GetFieldIDOrDie(env, audioGainConfigClass, "mValues", "[I");
2432 gAudioGainConfigFields.mRampDurationMs = GetFieldIDOrDie(env, audioGainConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002433 "mRampDurationMs", "I");
2434
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002435 jclass audioPatchClass = FindClassOrDie(env, "android/media/AudioPatch");
2436 gAudioPatchClass = MakeGlobalRefOrDie(env, audioPatchClass);
2437 gAudioPatchCstor = GetMethodIDOrDie(env, audioPatchClass, "<init>",
Eric Laurentb69681c2014-05-19 19:02:51 -07002438"(Landroid/media/AudioHandle;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002439 gAudioPatchFields.mHandle = GetFieldIDOrDie(env, audioPatchClass, "mHandle",
Eric Laurentb69681c2014-05-19 19:02:51 -07002440 "Landroid/media/AudioHandle;");
2441
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002442 jclass eventHandlerClass = FindClassOrDie(env, kEventHandlerClassPathName);
Eric Laurent2615afb2015-03-25 14:51:08 -07002443 gAudioPortEventHandlerMethods.postEventFromNative = GetStaticMethodIDOrDie(
2444 env, eventHandlerClass, "postEventFromNative",
2445 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
2446 gEventHandlerFields.mJniCallback = GetFieldIDOrDie(env,
2447 eventHandlerClass, "mJniCallback", "J");
Eric Laurent700e7342014-05-02 18:33:15 -07002448
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002449 gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative =
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002450 GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
2451 "dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V");
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002452 gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative =
2453 GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
Mikhail Naganova00883d2019-04-18 12:36:27 -07002454 "recordingCallbackFromNative", "(IIIIIIZ[I[Landroid/media/audiofx/AudioEffect$Descriptor;[Landroid/media/audiofx/AudioEffect$Descriptor;I)V");
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002455
Eric Laurent09378972014-12-10 10:42:08 -08002456 jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix");
2457 gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass);
2458 gAudioMixFields.mRule = GetFieldIDOrDie(env, audioMixClass, "mRule",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002459 "Landroid/media/audiopolicy/AudioMixingRule;");
Eric Laurent09378972014-12-10 10:42:08 -08002460 gAudioMixFields.mFormat = GetFieldIDOrDie(env, audioMixClass, "mFormat",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002461 "Landroid/media/AudioFormat;");
Eric Laurent09378972014-12-10 10:42:08 -08002462 gAudioMixFields.mRouteFlags = GetFieldIDOrDie(env, audioMixClass, "mRouteFlags", "I");
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07002463 gAudioMixFields.mDeviceType = GetFieldIDOrDie(env, audioMixClass, "mDeviceSystemType", "I");
2464 gAudioMixFields.mDeviceAddress = GetFieldIDOrDie(env, audioMixClass, "mDeviceAddress",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002465 "Ljava/lang/String;");
Eric Laurent09378972014-12-10 10:42:08 -08002466 gAudioMixFields.mMixType = GetFieldIDOrDie(env, audioMixClass, "mMixType", "I");
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002467 gAudioMixFields.mCallbackFlags = GetFieldIDOrDie(env, audioMixClass, "mCallbackFlags", "I");
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002468
Eric Laurent09378972014-12-10 10:42:08 -08002469 jclass audioFormatClass = FindClassOrDie(env, "android/media/AudioFormat");
2470 gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass);
2471 gAudioFormatFields.mEncoding = GetFieldIDOrDie(env, audioFormatClass, "mEncoding", "I");
2472 gAudioFormatFields.mSampleRate = GetFieldIDOrDie(env, audioFormatClass, "mSampleRate", "I");
2473 gAudioFormatFields.mChannelMask = GetFieldIDOrDie(env, audioFormatClass, "mChannelMask", "I");
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002474
Eric Laurent09378972014-12-10 10:42:08 -08002475 jclass audioMixingRuleClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule");
2476 gAudioMixingRuleClass = MakeGlobalRefOrDie(env, audioMixingRuleClass);
2477 gAudioMixingRuleFields.mCriteria = GetFieldIDOrDie(env, audioMixingRuleClass, "mCriteria",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002478 "Ljava/util/ArrayList;");
Kevin Rocarda3a4bbb2019-03-07 18:29:48 -08002479 gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture =
2480 GetFieldIDOrDie(env, audioMixingRuleClass, "mAllowPrivilegedPlaybackCapture", "Z");
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002481
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08002482 jclass audioMixMatchCriterionClass =
2483 FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion");
2484 gAudioMixMatchCriterionClass = MakeGlobalRefOrDie(env,audioMixMatchCriterionClass);
2485 gAudioMixMatchCriterionFields.mAttr = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mAttr",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002486 "Landroid/media/AudioAttributes;");
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08002487 gAudioMixMatchCriterionFields.mIntProp = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mIntProp",
2488 "I");
2489 gAudioMixMatchCriterionFields.mRule = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mRule",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002490 "I");
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002491 // AudioTrackRoutingProxy methods
2492 gClsAudioTrackRoutingProxy =
2493 android::FindClassOrDie(env, "android/media/AudioTrackRoutingProxy");
2494 // make sure this reference doesn't get deleted
2495 gClsAudioTrackRoutingProxy = (jclass)env->NewGlobalRef(gClsAudioTrackRoutingProxy);
2496
2497 gMidAudioTrackRoutingProxy_ctor =
2498 android::GetMethodIDOrDie(env, gClsAudioTrackRoutingProxy, "<init>", "(J)V");
2499 gMidAudioTrackRoutingProxy_release =
2500 android::GetMethodIDOrDie(env, gClsAudioTrackRoutingProxy, "native_release", "()V");
2501
2502 // AudioRecordRoutingProxy
2503 gClsAudioRecordRoutingProxy =
2504 android::FindClassOrDie(env, "android/media/AudioRecordRoutingProxy");
2505 // make sure this reference doesn't get deleted
2506 gClsAudioRecordRoutingProxy = (jclass)env->NewGlobalRef(gClsAudioRecordRoutingProxy);
2507
2508 gMidAudioRecordRoutingProxy_ctor =
2509 android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "<init>", "(J)V");
2510 gMidAudioRecordRoutingProxy_release =
2511 android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "native_release", "()V");
2512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
Glenn Kasten18db49a2012-03-12 16:29:55 -07002514
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002515 RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
2516 return RegisterMethodsOrDie(env, kEventHandlerClassPathName, gEventHandlerMethods,
2517 NELEM(gEventHandlerMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002518}