blob: 6417b283f52009a825c1aca086e9763755224640 [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>
jiabin111725d2019-11-04 14:16:21 -080030#include <media/AudioDeviceTypeAddr.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031#include <media/AudioSystem.h>
Eric Laurent7f5eb9f2014-12-01 19:36:30 -080032#include <media/AudioPolicy.h>
jiabinc0f49442018-01-05 10:23:50 -080033#include <media/MicrophoneInfo.h>
Andy Hung737d9fb2016-08-16 18:38:49 -070034#include <nativehelper/ScopedLocalRef.h>
Dima Zavin34bb4192011-05-11 14:15:23 -070035#include <system/audio.h>
Dima Zavin290029d2011-06-13 18:16:26 -070036#include <system/audio_policy.h>
Eric Laurentc7a0cdf2018-11-30 12:16:52 -080037#include "android_media_AudioEffectDescriptor.h"
Eric Laurentb69681c2014-05-19 19:02:51 -070038#include "android_media_AudioFormat.h"
39#include "android_media_AudioErrors.h"
jiabinc0f49442018-01-05 10:23:50 -080040#include "android_media_MicrophoneInfo.h"
François Gaffieb4691282018-07-09 13:07:32 +020041#include "android_media_AudioAttributes.h"
Dima Zavin24fc2fb2011-04-19 22:30:36 -070042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043// ----------------------------------------------------------------------------
44
45using namespace android;
46
Glenn Kastened0079d2011-04-04 10:50:50 -070047static const char* const kClassPathName = "android/media/AudioSystem";
48
Eric Laurentb69681c2014-05-19 19:02:51 -070049static jclass gArrayListClass;
50static struct {
51 jmethodID add;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -080052 jmethodID toArray;
Eric Laurentb69681c2014-05-19 19:02:51 -070053} gArrayListMethods;
54
jiabin39940752018-04-02 18:18:45 -070055static jclass gBooleanClass;
56static jmethodID gBooleanCstor;
57
58static jclass gIntegerClass;
59static jmethodID gIntegerCstor;
60
61static jclass gMapClass;
62static jmethodID gMapPut;
63
Eric Laurentb69681c2014-05-19 19:02:51 -070064static jclass gAudioHandleClass;
65static jmethodID gAudioHandleCstor;
66static struct {
67 jfieldID mId;
68} gAudioHandleFields;
69
70static jclass gAudioPortClass;
71static jmethodID gAudioPortCstor;
72static struct {
73 jfieldID mHandle;
74 jfieldID mRole;
75 jfieldID mGains;
76 jfieldID mActiveConfig;
Hongwei Wangf44a5682018-08-24 10:37:56 -070077 // Valid only if an AudioDevicePort
78 jfieldID mType;
79 jfieldID mAddress;
Eric Laurentb69681c2014-05-19 19:02:51 -070080 // other fields unused by JNI
81} gAudioPortFields;
82
83static jclass gAudioPortConfigClass;
84static jmethodID gAudioPortConfigCstor;
85static struct {
86 jfieldID mPort;
87 jfieldID mSamplingRate;
88 jfieldID mChannelMask;
89 jfieldID mFormat;
90 jfieldID mGain;
Eric Laurent3a241992014-05-19 19:33:26 -070091 jfieldID mConfigMask;
Eric Laurentb69681c2014-05-19 19:02:51 -070092} gAudioPortConfigFields;
93
94static jclass gAudioDevicePortClass;
95static jmethodID gAudioDevicePortCstor;
96
97static jclass gAudioDevicePortConfigClass;
98static jmethodID gAudioDevicePortConfigCstor;
99
100static jclass gAudioMixPortClass;
101static jmethodID gAudioMixPortCstor;
102
103static jclass gAudioMixPortConfigClass;
104static jmethodID gAudioMixPortConfigCstor;
105
106static jclass gAudioGainClass;
107static jmethodID gAudioGainCstor;
108
109static jclass gAudioGainConfigClass;
110static jmethodID gAudioGainConfigCstor;
111static struct {
112 jfieldID mIndex;
113 jfieldID mMode;
114 jfieldID mChannelMask;
115 jfieldID mValues;
116 jfieldID mRampDurationMs;
117 // other fields unused by JNI
118} gAudioGainConfigFields;
119
120static jclass gAudioPatchClass;
121static jmethodID gAudioPatchCstor;
122static struct {
123 jfieldID mHandle;
124 // other fields unused by JNI
125} gAudioPatchFields;
126
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800127static jclass gAudioMixClass;
128static struct {
129 jfieldID mRule;
130 jfieldID mFormat;
131 jfieldID mRouteFlags;
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -0700132 jfieldID mDeviceType;
133 jfieldID mDeviceAddress;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800134 jfieldID mMixType;
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700135 jfieldID mCallbackFlags;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800136} gAudioMixFields;
137
138static jclass gAudioFormatClass;
139static struct {
140 jfieldID mEncoding;
141 jfieldID mSampleRate;
142 jfieldID mChannelMask;
143 // other fields unused by JNI
144} gAudioFormatFields;
145
146static jclass gAudioMixingRuleClass;
147static struct {
148 jfieldID mCriteria;
Kevin Rocarda3a4bbb2019-03-07 18:29:48 -0800149 jfieldID mAllowPrivilegedPlaybackCapture;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800150 // other fields unused by JNI
151} gAudioMixingRuleFields;
152
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800153static jclass gAudioMixMatchCriterionClass;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800154static struct {
155 jfieldID mAttr;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800156 jfieldID mIntProp;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800157 jfieldID mRule;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800158} gAudioMixMatchCriterionFields;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800159
Eric Laurent700e7342014-05-02 18:33:15 -0700160static const char* const kEventHandlerClassPathName =
161 "android/media/AudioPortEventHandler";
Eric Laurent2615afb2015-03-25 14:51:08 -0700162static struct {
163 jfieldID mJniCallback;
164} gEventHandlerFields;
165static struct {
166 jmethodID postEventFromNative;
167} gAudioPortEventHandlerMethods;
168
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700169static struct {
170 jmethodID postDynPolicyEventFromNative;
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800171 jmethodID postRecordConfigEventFromNative;
172} gAudioPolicyEventHandlerMethods;
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700173
Paul McLeanb3ae6d92018-11-05 15:16:59 -0700174//
175// JNI Initialization for OpenSLES routing
176//
177jmethodID gMidAudioTrackRoutingProxy_ctor;
178jmethodID gMidAudioTrackRoutingProxy_release;
179jmethodID gMidAudioRecordRoutingProxy_ctor;
180jmethodID gMidAudioRecordRoutingProxy_release;
181
182jclass gClsAudioTrackRoutingProxy;
183jclass gClsAudioRecordRoutingProxy;
184
Eric Laurent2615afb2015-03-25 14:51:08 -0700185static Mutex gLock;
Eric Laurentb69681c2014-05-19 19:02:51 -0700186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187enum AudioError {
188 kAudioStatusOk = 0,
189 kAudioStatusError = 1,
190 kAudioStatusMediaServerDied = 100
191};
192
Eric Laurent700e7342014-05-02 18:33:15 -0700193enum {
194 AUDIOPORT_EVENT_PORT_LIST_UPDATED = 1,
195 AUDIOPORT_EVENT_PATCH_LIST_UPDATED = 2,
196 AUDIOPORT_EVENT_SERVICE_DIED = 3,
197};
198
Eric Laurentb69681c2014-05-19 19:02:51 -0700199#define MAX_PORT_GENERATION_SYNC_ATTEMPTS 5
200
Eric Laurent700e7342014-05-02 18:33:15 -0700201// ----------------------------------------------------------------------------
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700202// ref-counted object for audio port callbacks
Eric Laurent700e7342014-05-02 18:33:15 -0700203class JNIAudioPortCallback: public AudioSystem::AudioPortCallback
204{
205public:
206 JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
207 ~JNIAudioPortCallback();
208
209 virtual void onAudioPortListUpdate();
210 virtual void onAudioPatchListUpdate();
211 virtual void onServiceDied();
212
213private:
214 void sendEvent(int event);
215
Eric Laurent2615afb2015-03-25 14:51:08 -0700216 jclass mClass; // Reference to AudioPortEventHandler class
217 jobject mObject; // Weak ref to AudioPortEventHandler Java object to call on
Eric Laurent700e7342014-05-02 18:33:15 -0700218};
219
220JNIAudioPortCallback::JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
221{
222
Eric Laurent2615afb2015-03-25 14:51:08 -0700223 // Hold onto the AudioPortEventHandler class for use in calling the static method
Eric Laurent700e7342014-05-02 18:33:15 -0700224 // that posts events to the application thread.
225 jclass clazz = env->GetObjectClass(thiz);
226 if (clazz == NULL) {
227 ALOGE("Can't find class %s", kEventHandlerClassPathName);
228 return;
229 }
230 mClass = (jclass)env->NewGlobalRef(clazz);
231
Eric Laurent2615afb2015-03-25 14:51:08 -0700232 // We use a weak reference so the AudioPortEventHandler object can be garbage collected.
Eric Laurent700e7342014-05-02 18:33:15 -0700233 // The reference is only used as a proxy for callbacks.
234 mObject = env->NewGlobalRef(weak_thiz);
235}
236
237JNIAudioPortCallback::~JNIAudioPortCallback()
238{
239 // remove global references
240 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent449c5882014-11-12 11:07:48 -0800241 if (env == NULL) {
242 return;
243 }
Eric Laurent700e7342014-05-02 18:33:15 -0700244 env->DeleteGlobalRef(mObject);
245 env->DeleteGlobalRef(mClass);
246}
247
248void JNIAudioPortCallback::sendEvent(int event)
249{
250 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent449c5882014-11-12 11:07:48 -0800251 if (env == NULL) {
252 return;
253 }
Eric Laurent2615afb2015-03-25 14:51:08 -0700254 env->CallStaticVoidMethod(mClass, gAudioPortEventHandlerMethods.postEventFromNative, mObject,
Eric Laurent700e7342014-05-02 18:33:15 -0700255 event, 0, 0, NULL);
256 if (env->ExceptionCheck()) {
257 ALOGW("An exception occurred while notifying an event.");
258 env->ExceptionClear();
259 }
260}
261
262void JNIAudioPortCallback::onAudioPortListUpdate()
263{
264 sendEvent(AUDIOPORT_EVENT_PORT_LIST_UPDATED);
265}
266
267void JNIAudioPortCallback::onAudioPatchListUpdate()
268{
269 sendEvent(AUDIOPORT_EVENT_PATCH_LIST_UPDATED);
270}
271
272void JNIAudioPortCallback::onServiceDied()
273{
274 sendEvent(AUDIOPORT_EVENT_SERVICE_DIED);
275}
276
Eric Laurent2615afb2015-03-25 14:51:08 -0700277static sp<JNIAudioPortCallback> setJniCallback(JNIEnv* env,
278 jobject thiz,
279 const sp<JNIAudioPortCallback>& callback)
280{
281 Mutex::Autolock l(gLock);
282 sp<JNIAudioPortCallback> old =
283 (JNIAudioPortCallback*)env->GetLongField(thiz, gEventHandlerFields.mJniCallback);
284 if (callback.get()) {
285 callback->incStrong((void*)setJniCallback);
286 }
287 if (old != 0) {
288 old->decStrong((void*)setJniCallback);
289 }
290 env->SetLongField(thiz, gEventHandlerFields.mJniCallback, (jlong)callback.get());
291 return old;
292}
293
Mikhail Naganov5caa57d2018-04-02 10:35:45 -0700294#define check_AudioSystem_Command(status) _check_AudioSystem_Command(__func__, (status))
295
296static int _check_AudioSystem_Command(const char* caller, status_t status)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297{
Mikhail Naganov5caa57d2018-04-02 10:35:45 -0700298 ALOGE_IF(status, "Command failed for %s: %d", caller, status);
Eric Laurentdfb881f2013-07-18 14:41:39 -0700299 switch (status) {
300 case DEAD_OBJECT:
301 return kAudioStatusMediaServerDied;
302 case NO_ERROR:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 return kAudioStatusOk;
Eric Laurentdfb881f2013-07-18 14:41:39 -0700304 default:
305 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 }
Eric Laurentdfb881f2013-07-18 14:41:39 -0700307 return kAudioStatusError;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308}
309
Ashok Bhat075e9a12014-01-06 13:45:09 +0000310static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
312{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000313 return (jint) check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314}
315
316static jboolean
317android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
318{
319 bool state = false;
320 AudioSystem::isMicrophoneMuted(&state);
321 return state;
322}
323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324static jboolean
Eric Laurent25101b02011-02-02 09:33:30 -0800325android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326{
327 bool state = false;
Glenn Kastenbc1d77b2012-01-12 16:38:12 -0800328 AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 return state;
330}
331
Jean-Michel Trivid6770542012-10-10 12:03:41 -0700332static jboolean
Jean-Michel Trivi679d5042013-02-04 16:24:09 -0800333android_media_AudioSystem_isStreamActiveRemotely(JNIEnv *env, jobject thiz, jint stream,
334 jint inPastMs)
335{
336 bool state = false;
337 AudioSystem::isStreamActiveRemotely((audio_stream_type_t) stream, &state, inPastMs);
338 return state;
339}
340
341static jboolean
Jean-Michel Trivid6770542012-10-10 12:03:41 -0700342android_media_AudioSystem_isSourceActive(JNIEnv *env, jobject thiz, jint source)
343{
344 bool state = false;
345 AudioSystem::isSourceActive((audio_source_t) source, &state);
346 return state;
347}
348
Ashok Bhat075e9a12014-01-06 13:45:09 +0000349static jint
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -0700350android_media_AudioSystem_newAudioSessionId(JNIEnv *env, jobject thiz)
351{
Glenn Kasten211d9052016-02-26 16:22:40 -0800352 return AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -0700353}
354
355static jint
Jean-Michel Trivi292a6a42016-12-01 08:32:15 -0800356android_media_AudioSystem_newAudioPlayerId(JNIEnv *env, jobject thiz)
357{
Mikhail Naganova00883d2019-04-18 12:36:27 -0700358 int id = AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_CLIENT);
359 return id != AUDIO_UNIQUE_ID_ALLOCATE ? id : PLAYER_PIID_INVALID;
360}
361
362static jint
363android_media_AudioSystem_newAudioRecorderId(JNIEnv *env, jobject thiz)
364{
365 int id = AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_CLIENT);
366 return id != AUDIO_UNIQUE_ID_ALLOCATE ? id : RECORD_RIID_INVALID;
Jean-Michel Trivi292a6a42016-12-01 08:32:15 -0800367}
368
369static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700370android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371{
Eric Laurenta553c252009-07-17 12:17:14 -0700372 const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
373 String8 c_keyValuePairs8;
374 if (keyValuePairs) {
Dan Albert66987492014-11-20 11:41:21 -0800375 c_keyValuePairs8 = String8(
376 reinterpret_cast<const char16_t*>(c_keyValuePairs),
377 env->GetStringLength(keyValuePairs));
Eric Laurenta553c252009-07-17 12:17:14 -0700378 env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
379 }
Glenn Kastenc94752a2013-12-19 12:40:33 -0800380 int status = check_AudioSystem_Command(AudioSystem::setParameters(c_keyValuePairs8));
Ashok Bhat075e9a12014-01-06 13:45:09 +0000381 return (jint) status;
Eric Laurenta553c252009-07-17 12:17:14 -0700382}
383
384static jstring
385android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
386{
387 const jchar* c_keys = env->GetStringCritical(keys, 0);
388 String8 c_keys8;
389 if (keys) {
Dan Albert66987492014-11-20 11:41:21 -0800390 c_keys8 = String8(reinterpret_cast<const char16_t*>(c_keys),
391 env->GetStringLength(keys));
Eric Laurenta553c252009-07-17 12:17:14 -0700392 env->ReleaseStringCritical(keys, c_keys);
393 }
Glenn Kastenc94752a2013-12-19 12:40:33 -0800394 return env->NewStringUTF(AudioSystem::getParameters(c_keys8).string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395}
396
Glenn Kastened0079d2011-04-04 10:50:50 -0700397static void
398android_media_AudioSystem_error_callback(status_t err)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399{
Eric Laurent539719a2013-07-18 14:08:00 -0700400 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent0e7a4d92010-10-15 12:33:16 -0700401 if (env == NULL) {
402 return;
403 }
404
Glenn Kastened0079d2011-04-04 10:50:50 -0700405 jclass clazz = env->FindClass(kClassPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406
Eric Laurentdfb881f2013-07-18 14:41:39 -0700407 env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz,
408 "errorCallbackFromNative","(I)V"),
409 check_AudioSystem_Command(err));
Viorel Sumanb637ccf2014-05-30 16:51:07 +0300410
411 env->DeleteLocalRef(clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412}
413
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700414static void
415android_media_AudioSystem_dyn_policy_callback(int event, String8 regId, int val)
416{
417 JNIEnv *env = AndroidRuntime::getJNIEnv();
418 if (env == NULL) {
419 return;
420 }
421
422 jclass clazz = env->FindClass(kClassPathName);
423 const char* zechars = regId.string();
424 jstring zestring = env->NewStringUTF(zechars);
425
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800426 env->CallStaticVoidMethod(clazz, gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative,
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700427 event, zestring, val);
428
429 env->ReleaseStringUTFChars(zestring, zechars);
430 env->DeleteLocalRef(clazz);
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800431}
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700432
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800433static void
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800434android_media_AudioSystem_recording_callback(int event,
435 const record_client_info_t *clientInfo,
436 const audio_config_base_t *clientConfig,
437 std::vector<effect_descriptor_t> clientEffects,
438 const audio_config_base_t *deviceConfig,
439 std::vector<effect_descriptor_t> effects __unused,
440 audio_patch_handle_t patchHandle,
441 audio_source_t source)
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800442{
443 JNIEnv *env = AndroidRuntime::getJNIEnv();
444 if (env == NULL) {
445 return;
446 }
Jean-Michel Trivi66ffacf2017-02-04 17:25:31 -0800447 if (clientInfo == NULL || clientConfig == NULL || deviceConfig == NULL) {
448 ALOGE("Unexpected null client/device info or configurations in recording callback");
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800449 return;
450 }
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800451
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800452 // create an array for 2*3 integers to store the record configurations (client + device)
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800453 // plus 1 integer for the patch handle
454 const int REC_PARAM_SIZE = 7;
455 jintArray recParamArray = env->NewIntArray(REC_PARAM_SIZE);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800456 if (recParamArray == NULL) {
457 ALOGE("recording callback: Couldn't allocate int array for configuration data");
458 return;
459 }
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800460 jint recParamData[REC_PARAM_SIZE];
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800461 recParamData[0] = (jint) audioFormatFromNative(clientConfig->format);
462 // FIXME this doesn't support index-based masks
463 recParamData[1] = (jint) inChannelMaskFromNative(clientConfig->channel_mask);
464 recParamData[2] = (jint) clientConfig->sample_rate;
465 recParamData[3] = (jint) audioFormatFromNative(deviceConfig->format);
466 // FIXME this doesn't support index-based masks
467 recParamData[4] = (jint) inChannelMaskFromNative(deviceConfig->channel_mask);
468 recParamData[5] = (jint) deviceConfig->sample_rate;
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800469 recParamData[6] = (jint) patchHandle;
470 env->SetIntArrayRegion(recParamArray, 0, REC_PARAM_SIZE, recParamData);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800471
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800472 jobjectArray jClientEffects;
473 convertAudioEffectDescriptorVectorFromNative(env, &jClientEffects, clientEffects);
474
475 jobjectArray jEffects;
476 convertAudioEffectDescriptorVectorFromNative(env, &jEffects, effects);
477
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800478 // callback into java
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800479 jclass clazz = env->FindClass(kClassPathName);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800480
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800481 env->CallStaticVoidMethod(clazz,
482 gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative,
Mikhail Naganova00883d2019-04-18 12:36:27 -0700483 event, (jint) clientInfo->riid, (jint) clientInfo->uid,
484 clientInfo->session, clientInfo->source, clientInfo->port_id,
485 clientInfo->silenced, recParamArray, jClientEffects, jEffects,
486 source);
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800487 env->DeleteLocalRef(clazz);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800488 env->DeleteLocalRef(recParamArray);
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800489 env->DeleteLocalRef(jClientEffects);
490 env->DeleteLocalRef(jEffects);
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700491}
492
Ashok Bhat075e9a12014-01-06 13:45:09 +0000493static jint
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -0800494android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name,
Eric Laurent1d43aec2019-01-16 18:24:08 -0800495 jint codec)
Eric Laurenta553c252009-07-17 12:17:14 -0700496{
497 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Paul McLean10804eb2015-01-28 11:16:35 -0800498 const char *c_name = env->GetStringUTFChars(device_name, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700499 int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
500 static_cast <audio_policy_dev_state_t>(state),
Eric Laurent1d43aec2019-01-16 18:24:08 -0800501 c_address, c_name,
502 static_cast <audio_format_t>(codec)));
Eric Laurenta553c252009-07-17 12:17:14 -0700503 env->ReleaseStringUTFChars(device_address, c_address);
Paul McLean10804eb2015-01-28 11:16:35 -0800504 env->ReleaseStringUTFChars(device_name, c_name);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000505 return (jint) status;
Eric Laurenta553c252009-07-17 12:17:14 -0700506}
507
Ashok Bhat075e9a12014-01-06 13:45:09 +0000508static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700509android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
510{
511 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700512 int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
Eric Laurenta553c252009-07-17 12:17:14 -0700513 c_address));
514 env->ReleaseStringUTFChars(device_address, c_address);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000515 return (jint) state;
Eric Laurenta553c252009-07-17 12:17:14 -0700516}
517
Ashok Bhat075e9a12014-01-06 13:45:09 +0000518static jint
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -0800519android_media_AudioSystem_handleDeviceConfigChange(JNIEnv *env, jobject thiz, jint device, jstring device_address, jstring device_name,
Eric Laurent1d43aec2019-01-16 18:24:08 -0800520 jint codec)
Pavlin Radoslavov44a4ef02016-12-21 12:05:51 -0800521{
522 const char *c_address = env->GetStringUTFChars(device_address, NULL);
523 const char *c_name = env->GetStringUTFChars(device_name, NULL);
524 int status = check_AudioSystem_Command(AudioSystem::handleDeviceConfigChange(static_cast <audio_devices_t>(device),
Eric Laurent1d43aec2019-01-16 18:24:08 -0800525 c_address, c_name, static_cast <audio_format_t>(codec)));
Pavlin Radoslavov44a4ef02016-12-21 12:05:51 -0800526 env->ReleaseStringUTFChars(device_address, c_address);
527 env->ReleaseStringUTFChars(device_name, c_name);
528 return (jint) status;
529}
530
531static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700532android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
533{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000534 return (jint) check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state));
Eric Laurenta553c252009-07-17 12:17:14 -0700535}
536
Ashok Bhat075e9a12014-01-06 13:45:09 +0000537static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700538android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
539{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000540 return (jint) check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700541 static_cast <audio_policy_forced_cfg_t>(config)));
Eric Laurenta553c252009-07-17 12:17:14 -0700542}
543
Ashok Bhat075e9a12014-01-06 13:45:09 +0000544static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700545android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
546{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000547 return static_cast <jint>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
Eric Laurenta553c252009-07-17 12:17:14 -0700548}
549
Ashok Bhat075e9a12014-01-06 13:45:09 +0000550static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700551android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
552{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000553 return (jint) check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
Eric Laurenta553c252009-07-17 12:17:14 -0700554 indexMin,
555 indexMax));
556}
557
Ashok Bhat075e9a12014-01-06 13:45:09 +0000558static jint
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800559android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
560 jobject thiz,
561 jint stream,
562 jint index,
563 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700564{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000565 return (jint) check_AudioSystem_Command(
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800566 AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
567 index,
568 (audio_devices_t)device));
Eric Laurenta553c252009-07-17 12:17:14 -0700569}
570
Ashok Bhat075e9a12014-01-06 13:45:09 +0000571static jint
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800572android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env,
573 jobject thiz,
574 jint stream,
575 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700576{
577 int index;
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800578 if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
579 &index,
580 (audio_devices_t)device)
581 != NO_ERROR) {
Eric Laurenta553c252009-07-17 12:17:14 -0700582 index = -1;
583 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000584 return (jint) index;
Eric Laurenta553c252009-07-17 12:17:14 -0700585}
586
Ashok Bhat075e9a12014-01-06 13:45:09 +0000587static jint
François Gaffieebb67d02018-09-14 15:05:04 +0200588android_media_AudioSystem_setVolumeIndexForAttributes(JNIEnv *env,
589 jobject thiz,
590 jobject jaa,
591 jint index,
592 jint device)
593{
594 // read the AudioAttributes values
595 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
596 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
597 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
598 return jStatus;
599 }
600 return (jint) check_AudioSystem_Command(
601 AudioSystem::setVolumeIndexForAttributes(*(paa.get()), index, (audio_devices_t)device));
602}
603
604static jint
605android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env,
606 jobject thiz,
607 jobject jaa,
608 jint device)
609{
610 // read the AudioAttributes values
611 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
612 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
613 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
614 return jStatus;
615 }
616 int index;
617 if (AudioSystem::getVolumeIndexForAttributes(*(paa.get()), index, (audio_devices_t)device)
618 != NO_ERROR) {
619 index = -1;
620 }
621 return (jint) index;
622}
623
624static jint
625android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env,
626 jobject thiz,
627 jobject jaa)
628{
629 // read the AudioAttributes values
630 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
631 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
632 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
633 return jStatus;
634 }
635 int index;
636 if (AudioSystem::getMinVolumeIndexForAttributes(*(paa.get()), index)
637 != NO_ERROR) {
638 index = -1;
639 }
640 return (jint) index;
641}
642
643static jint
644android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env,
645 jobject thiz,
646 jobject jaa)
647{
648 // read the AudioAttributes values
649 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
650 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
651 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
652 return jStatus;
653 }
654 int index;
655 if (AudioSystem::getMaxVolumeIndexForAttributes(*(paa.get()), index)
656 != NO_ERROR) {
657 index = -1;
658 }
659 return (jint) index;
660}
661
662static jint
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400663android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
664{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000665 return (jint) check_AudioSystem_Command(AudioSystem::setMasterVolume(value));
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400666}
667
668static jfloat
669android_media_AudioSystem_getMasterVolume(JNIEnv *env, jobject thiz)
670{
671 float value;
672 if (AudioSystem::getMasterVolume(&value) != NO_ERROR) {
673 value = -1.0;
674 }
675 return value;
676}
677
Ashok Bhat075e9a12014-01-06 13:45:09 +0000678static jint
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400679android_media_AudioSystem_setMasterMute(JNIEnv *env, jobject thiz, jboolean mute)
680{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000681 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMute(mute));
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400682}
683
Vladimir Markoc1bcdbb2014-10-29 20:34:15 +0000684static jboolean
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400685android_media_AudioSystem_getMasterMute(JNIEnv *env, jobject thiz)
686{
687 bool mute;
688 if (AudioSystem::getMasterMute(&mute) != NO_ERROR) {
689 mute = false;
690 }
691 return mute;
692}
693
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800694static jint
Andy Hungf04b84d2015-12-18 17:33:27 -0800695android_media_AudioSystem_setMasterMono(JNIEnv *env, jobject thiz, jboolean mono)
696{
697 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMono(mono));
698}
699
700static jboolean
701android_media_AudioSystem_getMasterMono(JNIEnv *env, jobject thiz)
702{
703 bool mono;
704 if (AudioSystem::getMasterMono(&mono) != NO_ERROR) {
705 mono = false;
706 }
707 return mono;
708}
709
710static jint
Edward Savage-Jones35c292f2017-01-13 09:04:34 +0100711android_media_AudioSystem_setMasterBalance(JNIEnv *env, jobject thiz, jfloat balance)
712{
713 return (jint) check_AudioSystem_Command(AudioSystem::setMasterBalance(balance));
714}
715
716static jfloat
717android_media_AudioSystem_getMasterBalance(JNIEnv *env, jobject thiz)
718{
719 float balance;
720 const status_t status = AudioSystem::getMasterBalance(&balance);
721 if (status != NO_ERROR) {
722 ALOGW("%s getMasterBalance error %d, returning 0.f, audioserver down?", __func__, status);
723 balance = 0.f;
724 }
725 return balance;
726}
727
728static jint
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800729android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
730{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700731 return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800732}
733
Glenn Kastenc6c43652012-09-24 17:32:30 -0700734static jint
735android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz)
736{
737 return (jint) AudioSystem::getPrimaryOutputSamplingRate();
738}
739
740static jint
741android_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv *env, jobject clazz)
742{
743 return (jint) AudioSystem::getPrimaryOutputFrameCount();
744}
745
Oliver Woodman61dcdf32013-06-26 12:43:36 +0100746static jint
747android_media_AudioSystem_getOutputLatency(JNIEnv *env, jobject clazz, jint stream)
748{
749 uint32_t afLatency;
750 if (AudioSystem::getOutputLatency(&afLatency, static_cast <audio_stream_type_t>(stream))
751 != NO_ERROR) {
752 afLatency = -1;
753 }
754 return (jint) afLatency;
755}
756
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700757static jint
Andy Hung79583582018-01-23 13:58:02 -0800758android_media_AudioSystem_setLowRamDevice(
759 JNIEnv *env, jobject clazz, jboolean isLowRamDevice, jlong totalMemory)
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700760{
Andy Hung79583582018-01-23 13:58:02 -0800761 return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice, (int64_t) totalMemory);
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700762}
763
Ashok Bhat075e9a12014-01-06 13:45:09 +0000764static jint
Eric Laurentdfb881f2013-07-18 14:41:39 -0700765android_media_AudioSystem_checkAudioFlinger(JNIEnv *env, jobject clazz)
766{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000767 return (jint) check_AudioSystem_Command(AudioSystem::checkAudioFlinger());
Eric Laurentdfb881f2013-07-18 14:41:39 -0700768}
769
Eric Laurentb69681c2014-05-19 19:02:51 -0700770
771static bool useInChannelMask(audio_port_type_t type, audio_port_role_t role)
772{
773 return ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) ||
774 ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK));
775}
776
Eric Laurent3a241992014-05-19 19:33:26 -0700777static void convertAudioGainConfigToNative(JNIEnv *env,
778 struct audio_gain_config *nAudioGainConfig,
779 const jobject jAudioGainConfig,
780 bool useInMask)
781{
782 nAudioGainConfig->index = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mIndex);
783 nAudioGainConfig->mode = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mMode);
784 ALOGV("convertAudioGainConfigToNative got gain index %d", nAudioGainConfig->index);
785 jint jMask = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mChannelMask);
786 audio_channel_mask_t nMask;
787 if (useInMask) {
788 nMask = inChannelMaskToNative(jMask);
789 ALOGV("convertAudioGainConfigToNative IN mask java %x native %x", jMask, nMask);
790 } else {
791 nMask = outChannelMaskToNative(jMask);
792 ALOGV("convertAudioGainConfigToNative OUT mask java %x native %x", jMask, nMask);
793 }
794 nAudioGainConfig->channel_mask = nMask;
795 nAudioGainConfig->ramp_duration_ms = env->GetIntField(jAudioGainConfig,
796 gAudioGainConfigFields.mRampDurationMs);
797 jintArray jValues = (jintArray)env->GetObjectField(jAudioGainConfig,
798 gAudioGainConfigFields.mValues);
799 int *nValues = env->GetIntArrayElements(jValues, NULL);
800 size_t size = env->GetArrayLength(jValues);
801 memcpy(nAudioGainConfig->values, nValues, size * sizeof(int));
802 env->DeleteLocalRef(jValues);
803}
804
Eric Laurentb69681c2014-05-19 19:02:51 -0700805static jint convertAudioPortConfigToNative(JNIEnv *env,
806 struct audio_port_config *nAudioPortConfig,
Eric Laurent6368a7d2014-11-19 12:18:32 -0800807 const jobject jAudioPortConfig,
808 bool useConfigMask)
Eric Laurentb69681c2014-05-19 19:02:51 -0700809{
810 jobject jAudioPort = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mPort);
811 jobject jHandle = env->GetObjectField(jAudioPort, gAudioPortFields.mHandle);
812 nAudioPortConfig->id = env->GetIntField(jHandle, gAudioHandleFields.mId);
813 nAudioPortConfig->role = (audio_port_role_t)env->GetIntField(jAudioPort,
814 gAudioPortFields.mRole);
815 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
816 nAudioPortConfig->type = AUDIO_PORT_TYPE_DEVICE;
817 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
818 nAudioPortConfig->type = AUDIO_PORT_TYPE_MIX;
819 } else {
820 env->DeleteLocalRef(jAudioPort);
821 env->DeleteLocalRef(jHandle);
822 return (jint)AUDIO_JAVA_ERROR;
823 }
824 ALOGV("convertAudioPortConfigToNative handle %d role %d type %d",
825 nAudioPortConfig->id, nAudioPortConfig->role, nAudioPortConfig->type);
826
Eric Laurent6368a7d2014-11-19 12:18:32 -0800827 unsigned int configMask = 0;
828
Eric Laurentb69681c2014-05-19 19:02:51 -0700829 nAudioPortConfig->sample_rate = env->GetIntField(jAudioPortConfig,
830 gAudioPortConfigFields.mSamplingRate);
Eric Laurent6368a7d2014-11-19 12:18:32 -0800831 if (nAudioPortConfig->sample_rate != 0) {
832 configMask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
833 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700834
835 bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role);
836 audio_channel_mask_t nMask;
837 jint jMask = env->GetIntField(jAudioPortConfig,
838 gAudioPortConfigFields.mChannelMask);
839 if (useInMask) {
840 nMask = inChannelMaskToNative(jMask);
841 ALOGV("convertAudioPortConfigToNative IN mask java %x native %x", jMask, nMask);
842 } else {
843 nMask = outChannelMaskToNative(jMask);
844 ALOGV("convertAudioPortConfigToNative OUT mask java %x native %x", jMask, nMask);
845 }
846 nAudioPortConfig->channel_mask = nMask;
Eric Laurent6368a7d2014-11-19 12:18:32 -0800847 if (nAudioPortConfig->channel_mask != AUDIO_CHANNEL_NONE) {
848 configMask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
849 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700850
851 jint jFormat = env->GetIntField(jAudioPortConfig, gAudioPortConfigFields.mFormat);
852 audio_format_t nFormat = audioFormatToNative(jFormat);
853 ALOGV("convertAudioPortConfigToNative format %d native %d", jFormat, nFormat);
854 nAudioPortConfig->format = nFormat;
Eric Laurent6368a7d2014-11-19 12:18:32 -0800855 if (nAudioPortConfig->format != AUDIO_FORMAT_DEFAULT &&
856 nAudioPortConfig->format != AUDIO_FORMAT_INVALID) {
857 configMask |= AUDIO_PORT_CONFIG_FORMAT;
858 }
859
Eric Laurentb69681c2014-05-19 19:02:51 -0700860 jobject jGain = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mGain);
861 if (jGain != NULL) {
Eric Laurent3a241992014-05-19 19:33:26 -0700862 convertAudioGainConfigToNative(env, &nAudioPortConfig->gain, jGain, useInMask);
Eric Laurentb69681c2014-05-19 19:02:51 -0700863 env->DeleteLocalRef(jGain);
Eric Laurent6368a7d2014-11-19 12:18:32 -0800864 configMask |= AUDIO_PORT_CONFIG_GAIN;
Eric Laurentb69681c2014-05-19 19:02:51 -0700865 } else {
866 ALOGV("convertAudioPortConfigToNative no gain");
867 nAudioPortConfig->gain.index = -1;
868 }
Eric Laurent6368a7d2014-11-19 12:18:32 -0800869 if (useConfigMask) {
870 nAudioPortConfig->config_mask = env->GetIntField(jAudioPortConfig,
871 gAudioPortConfigFields.mConfigMask);
872 } else {
873 nAudioPortConfig->config_mask = configMask;
874 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700875 env->DeleteLocalRef(jAudioPort);
876 env->DeleteLocalRef(jHandle);
877 return (jint)AUDIO_JAVA_SUCCESS;
878}
879
Hongwei Wangf44a5682018-08-24 10:37:56 -0700880/**
881 * Extends convertAudioPortConfigToNative with extra device port info.
882 * Mix / Session specific info is not fulfilled.
883 */
884static jint convertAudioPortConfigToNativeWithDevicePort(JNIEnv *env,
885 struct audio_port_config *nAudioPortConfig,
886 const jobject jAudioPortConfig,
887 bool useConfigMask)
888{
889 jint jStatus = convertAudioPortConfigToNative(env,
890 nAudioPortConfig,
891 jAudioPortConfig,
892 useConfigMask);
893 if (jStatus != AUDIO_JAVA_SUCCESS) {
894 return jStatus;
895 }
896 // Supports AUDIO_PORT_TYPE_DEVICE only
897 if (nAudioPortConfig->type != AUDIO_PORT_TYPE_DEVICE) {
898 return (jint)AUDIO_JAVA_BAD_VALUE;
899 }
900
901 jobject jAudioDevicePort = env->GetObjectField(jAudioPortConfig,
902 gAudioPortConfigFields.mPort);
903 nAudioPortConfig->ext.device.type = env->GetIntField(jAudioDevicePort,
904 gAudioPortFields.mType);
905 jstring jDeviceAddress = (jstring)env->GetObjectField(jAudioDevicePort,
906 gAudioPortFields.mAddress);
907 const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
908 strncpy(nAudioPortConfig->ext.device.address,
909 nDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN - 1);
910 env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
911 env->DeleteLocalRef(jDeviceAddress);
912 env->DeleteLocalRef(jAudioDevicePort);
913 return jStatus;
914}
915
Eric Laurentb69681c2014-05-19 19:02:51 -0700916static jint convertAudioPortConfigFromNative(JNIEnv *env,
917 jobject jAudioPort,
918 jobject *jAudioPortConfig,
919 const struct audio_port_config *nAudioPortConfig)
920{
921 jint jStatus = AUDIO_JAVA_SUCCESS;
922 jobject jAudioGainConfig = NULL;
923 jobject jAudioGain = NULL;
924 jintArray jGainValues;
925 bool audioportCreated = false;
926
927 ALOGV("convertAudioPortConfigFromNative jAudioPort %p", jAudioPort);
928
929 if (jAudioPort == NULL) {
930 jobject jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
931 nAudioPortConfig->id);
932
933 ALOGV("convertAudioPortConfigFromNative handle %d is a %s", nAudioPortConfig->id,
934 nAudioPortConfig->type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix");
935
936 if (jHandle == NULL) {
937 return (jint)AUDIO_JAVA_ERROR;
938 }
939 // create dummy port and port config objects with just the correct handle
940 // and configuration data. The actual AudioPortConfig objects will be
941 // constructed by java code with correct class type (device, mix etc...)
942 // and reference to AudioPort instance in this client
943 jAudioPort = env->NewObject(gAudioPortClass, gAudioPortCstor,
Paul McLeanf29e5f32015-06-15 10:19:22 -0700944 jHandle, // handle
945 0, // role
946 NULL, // name
947 NULL, // samplingRates
948 NULL, // channelMasks
949 NULL, // channelIndexMasks
950 NULL, // formats
951 NULL); // gains
Eric Laurentb69681c2014-05-19 19:02:51 -0700952 env->DeleteLocalRef(jHandle);
953 if (jAudioPort == NULL) {
954 return (jint)AUDIO_JAVA_ERROR;
955 }
956 ALOGV("convertAudioPortConfigFromNative jAudioPort created for handle %d",
957 nAudioPortConfig->id);
958
959 audioportCreated = true;
960 }
961
962 bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role);
963
964 audio_channel_mask_t nMask;
965 jint jMask;
966
967 int gainIndex = nAudioPortConfig->gain.index;
968 if (gainIndex >= 0) {
969 ALOGV("convertAudioPortConfigFromNative gain found with index %d mode %x",
970 gainIndex, nAudioPortConfig->gain.mode);
971 if (audioportCreated) {
972 ALOGV("convertAudioPortConfigFromNative creating gain");
973 jAudioGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
974 gainIndex,
975 0,
976 0,
977 0,
978 0,
979 0,
980 0,
981 0,
982 0);
983 if (jAudioGain == NULL) {
984 ALOGV("convertAudioPortConfigFromNative creating gain FAILED");
985 jStatus = (jint)AUDIO_JAVA_ERROR;
986 goto exit;
987 }
988 } else {
989 ALOGV("convertAudioPortConfigFromNative reading gain from port");
990 jobjectArray jGains = (jobjectArray)env->GetObjectField(jAudioPort,
991 gAudioPortFields.mGains);
992 if (jGains == NULL) {
993 ALOGV("convertAudioPortConfigFromNative could not get gains from port");
994 jStatus = (jint)AUDIO_JAVA_ERROR;
995 goto exit;
996 }
997 jAudioGain = env->GetObjectArrayElement(jGains, gainIndex);
998 env->DeleteLocalRef(jGains);
999 if (jAudioGain == NULL) {
1000 ALOGV("convertAudioPortConfigFromNative could not get gain at index %d", gainIndex);
1001 jStatus = (jint)AUDIO_JAVA_ERROR;
1002 goto exit;
1003 }
1004 }
Eric Laurent0078c7c2014-06-04 09:49:52 -07001005 int numValues;
1006 if (useInMask) {
1007 numValues = audio_channel_count_from_in_mask(nAudioPortConfig->gain.channel_mask);
1008 } else {
1009 numValues = audio_channel_count_from_out_mask(nAudioPortConfig->gain.channel_mask);
1010 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001011 jGainValues = env->NewIntArray(numValues);
1012 if (jGainValues == NULL) {
1013 ALOGV("convertAudioPortConfigFromNative could not create gain values %d", numValues);
1014 jStatus = (jint)AUDIO_JAVA_ERROR;
1015 goto exit;
1016 }
1017 env->SetIntArrayRegion(jGainValues, 0, numValues,
1018 nAudioPortConfig->gain.values);
1019
1020 nMask = nAudioPortConfig->gain.channel_mask;
1021 if (useInMask) {
1022 jMask = inChannelMaskFromNative(nMask);
1023 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1024 } else {
1025 jMask = outChannelMaskFromNative(nMask);
1026 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1027 }
1028
1029 jAudioGainConfig = env->NewObject(gAudioGainConfigClass,
1030 gAudioGainConfigCstor,
1031 gainIndex,
1032 jAudioGain,
1033 nAudioPortConfig->gain.mode,
1034 jMask,
1035 jGainValues,
1036 nAudioPortConfig->gain.ramp_duration_ms);
1037 env->DeleteLocalRef(jGainValues);
1038 if (jAudioGainConfig == NULL) {
1039 ALOGV("convertAudioPortConfigFromNative could not create gain config");
1040 jStatus = (jint)AUDIO_JAVA_ERROR;
1041 goto exit;
1042 }
1043 }
1044 jclass clazz;
1045 jmethodID methodID;
1046 if (audioportCreated) {
1047 clazz = gAudioPortConfigClass;
1048 methodID = gAudioPortConfigCstor;
1049 ALOGV("convertAudioPortConfigFromNative building a generic port config");
1050 } else {
1051 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
1052 clazz = gAudioDevicePortConfigClass;
1053 methodID = gAudioDevicePortConfigCstor;
1054 ALOGV("convertAudioPortConfigFromNative building a device config");
1055 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
1056 clazz = gAudioMixPortConfigClass;
1057 methodID = gAudioMixPortConfigCstor;
1058 ALOGV("convertAudioPortConfigFromNative building a mix config");
1059 } else {
1060 jStatus = (jint)AUDIO_JAVA_ERROR;
1061 goto exit;
1062 }
1063 }
1064 nMask = nAudioPortConfig->channel_mask;
1065 if (useInMask) {
1066 jMask = inChannelMaskFromNative(nMask);
1067 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1068 } else {
1069 jMask = outChannelMaskFromNative(nMask);
1070 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1071 }
1072
1073 *jAudioPortConfig = env->NewObject(clazz, methodID,
1074 jAudioPort,
1075 nAudioPortConfig->sample_rate,
1076 jMask,
1077 audioFormatFromNative(nAudioPortConfig->format),
1078 jAudioGainConfig);
1079 if (*jAudioPortConfig == NULL) {
1080 ALOGV("convertAudioPortConfigFromNative could not create new port config");
1081 jStatus = (jint)AUDIO_JAVA_ERROR;
1082 } else {
1083 ALOGV("convertAudioPortConfigFromNative OK");
1084 }
1085
1086exit:
1087 if (audioportCreated) {
1088 env->DeleteLocalRef(jAudioPort);
1089 if (jAudioGain != NULL) {
1090 env->DeleteLocalRef(jAudioGain);
1091 }
1092 }
1093 if (jAudioGainConfig != NULL) {
1094 env->DeleteLocalRef(jAudioGainConfig);
1095 }
1096 return jStatus;
1097}
1098
Paul McLean4e5e9e92015-06-17 10:10:11 -07001099static bool hasFormat(int* formats, size_t size, int format) {
1100 for (size_t index = 0; index < size; index++) {
1101 if (formats[index] == format) {
1102 return true; // found
1103 }
1104 }
1105 return false; // not found
1106}
1107
Andy Hung737d9fb2016-08-16 18:38:49 -07001108// TODO: pull out to separate file
1109template <typename T, size_t N>
1110static constexpr size_t array_size(const T (&)[N]) {
1111 return N;
1112}
1113
Eric Laurentb69681c2014-05-19 19:02:51 -07001114static jint convertAudioPortFromNative(JNIEnv *env,
1115 jobject *jAudioPort, const struct audio_port *nAudioPort)
1116{
1117 jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
1118 jintArray jSamplingRates = NULL;
1119 jintArray jChannelMasks = NULL;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001120 jintArray jChannelIndexMasks = NULL;
Paul McLean4e5e9e92015-06-17 10:10:11 -07001121 int* cFormats = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001122 jintArray jFormats = NULL;
1123 jobjectArray jGains = NULL;
1124 jobject jHandle = NULL;
xiaomi/hanli82840c42017-07-19 18:53:03 +08001125 jobject jAudioPortConfig = NULL;
Paul McLean10804eb2015-01-28 11:16:35 -08001126 jstring jDeviceName = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001127 bool useInMask;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001128 size_t numPositionMasks = 0;
1129 size_t numIndexMasks = 0;
Paul McLean2db94372015-06-18 12:47:34 -07001130 size_t numUniqueFormats = 0;
1131
Paul McLean10804eb2015-01-28 11:16:35 -08001132 ALOGV("convertAudioPortFromNative id %d role %d type %d name %s",
1133 nAudioPort->id, nAudioPort->role, nAudioPort->type, nAudioPort->name);
Eric Laurentb69681c2014-05-19 19:02:51 -07001134
Andy Hung737d9fb2016-08-16 18:38:49 -07001135 // Verify audio port array count info.
1136 if (nAudioPort->num_sample_rates > array_size(nAudioPort->sample_rates)
1137 || nAudioPort->num_channel_masks > array_size(nAudioPort->channel_masks)
1138 || nAudioPort->num_formats > array_size(nAudioPort->formats)
1139 || nAudioPort->num_gains > array_size(nAudioPort->gains)) {
1140
1141 std::stringstream ss;
1142 ss << "convertAudioPortFromNative array count out of bounds:"
1143 << " num_sample_rates " << nAudioPort->num_sample_rates
1144 << " num_channel_masks " << nAudioPort->num_channel_masks
1145 << " num_formats " << nAudioPort->num_formats
1146 << " num_gains " << nAudioPort->num_gains
1147 ;
1148 std::string s = ss.str();
1149
1150 // Prefer to log through Java wtf instead of native ALOGE.
1151 ScopedLocalRef<jclass> jLogClass(env, env->FindClass("android/util/Log"));
1152 jmethodID jWtfId = (jLogClass.get() == nullptr)
1153 ? nullptr
1154 : env->GetStaticMethodID(jLogClass.get(), "wtf",
1155 "(Ljava/lang/String;Ljava/lang/String;)I");
1156 if (jWtfId != nullptr) {
1157 ScopedLocalRef<jstring> jMessage(env, env->NewStringUTF(s.c_str()));
1158 ScopedLocalRef<jstring> jTag(env, env->NewStringUTF(LOG_TAG));
1159 (void)env->CallStaticIntMethod(jLogClass.get(), jWtfId, jTag.get(), jMessage.get());
1160 } else {
1161 ALOGE("%s", s.c_str());
1162 }
1163 jStatus = (jint)AUDIO_JAVA_ERROR;
1164 goto exit;
1165 }
1166
Eric Laurentb69681c2014-05-19 19:02:51 -07001167 jSamplingRates = env->NewIntArray(nAudioPort->num_sample_rates);
1168 if (jSamplingRates == NULL) {
1169 jStatus = (jint)AUDIO_JAVA_ERROR;
1170 goto exit;
1171 }
1172 if (nAudioPort->num_sample_rates) {
1173 env->SetIntArrayRegion(jSamplingRates, 0, nAudioPort->num_sample_rates,
1174 (jint *)nAudioPort->sample_rates);
1175 }
1176
Paul McLeanf29e5f32015-06-15 10:19:22 -07001177 // count up how many masks are positional and indexed
1178 for(size_t index = 0; index < nAudioPort->num_channel_masks; index++) {
1179 const audio_channel_mask_t mask = nAudioPort->channel_masks[index];
1180 if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1181 numIndexMasks++;
1182 } else {
1183 numPositionMasks++;
1184 }
1185 }
1186
1187 jChannelMasks = env->NewIntArray(numPositionMasks);
Eric Laurentb69681c2014-05-19 19:02:51 -07001188 if (jChannelMasks == NULL) {
1189 jStatus = (jint)AUDIO_JAVA_ERROR;
1190 goto exit;
1191 }
Paul McLeanf29e5f32015-06-15 10:19:22 -07001192 jChannelIndexMasks = env->NewIntArray(numIndexMasks);
1193 if (jChannelIndexMasks == NULL) {
1194 jStatus = (jint)AUDIO_JAVA_ERROR;
1195 goto exit;
1196 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001197 useInMask = useInChannelMask(nAudioPort->type, nAudioPort->role);
1198
Paul McLeanf29e5f32015-06-15 10:19:22 -07001199 // put the masks in the output arrays
1200 for (size_t maskIndex = 0, posMaskIndex = 0, indexedMaskIndex = 0;
1201 maskIndex < nAudioPort->num_channel_masks; maskIndex++) {
1202 const audio_channel_mask_t mask = nAudioPort->channel_masks[maskIndex];
1203 if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1204 jint jMask = audio_channel_mask_get_bits(mask);
1205 env->SetIntArrayRegion(jChannelIndexMasks, indexedMaskIndex++, 1, &jMask);
Eric Laurentb69681c2014-05-19 19:02:51 -07001206 } else {
Paul McLeanf29e5f32015-06-15 10:19:22 -07001207 jint jMask = useInMask ? inChannelMaskFromNative(mask)
1208 : outChannelMaskFromNative(mask);
1209 env->SetIntArrayRegion(jChannelMasks, posMaskIndex++, 1, &jMask);
Eric Laurentb69681c2014-05-19 19:02:51 -07001210 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001211 }
1212
Paul McLeanf29e5f32015-06-15 10:19:22 -07001213 // formats
Paul McLean2db94372015-06-18 12:47:34 -07001214 if (nAudioPort->num_formats != 0) {
1215 cFormats = new int[nAudioPort->num_formats];
1216 for (size_t index = 0; index < nAudioPort->num_formats; index++) {
1217 int format = audioFormatFromNative(nAudioPort->formats[index]);
1218 if (!hasFormat(cFormats, numUniqueFormats, format)) {
1219 cFormats[numUniqueFormats++] = format;
1220 }
Paul McLean4e5e9e92015-06-17 10:10:11 -07001221 }
1222 }
1223 jFormats = env->NewIntArray(numUniqueFormats);
Eric Laurentb69681c2014-05-19 19:02:51 -07001224 if (jFormats == NULL) {
1225 jStatus = (jint)AUDIO_JAVA_ERROR;
1226 goto exit;
1227 }
Paul McLean2db94372015-06-18 12:47:34 -07001228 if (numUniqueFormats != 0) {
1229 env->SetIntArrayRegion(jFormats, 0, numUniqueFormats, cFormats);
1230 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001231
Paul McLeanf29e5f32015-06-15 10:19:22 -07001232 // gains
Eric Laurentb69681c2014-05-19 19:02:51 -07001233 jGains = env->NewObjectArray(nAudioPort->num_gains,
1234 gAudioGainClass, NULL);
1235 if (jGains == NULL) {
1236 jStatus = (jint)AUDIO_JAVA_ERROR;
1237 goto exit;
1238 }
Paul McLeanf29e5f32015-06-15 10:19:22 -07001239
Eric Laurentb69681c2014-05-19 19:02:51 -07001240 for (size_t j = 0; j < nAudioPort->num_gains; j++) {
1241 audio_channel_mask_t nMask = nAudioPort->gains[j].channel_mask;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001242 jint jMask;
Eric Laurentb69681c2014-05-19 19:02:51 -07001243 if (useInMask) {
1244 jMask = inChannelMaskFromNative(nMask);
1245 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1246 } else {
1247 jMask = outChannelMaskFromNative(nMask);
1248 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1249 }
1250
1251 jobject jGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
1252 j,
1253 nAudioPort->gains[j].mode,
1254 jMask,
1255 nAudioPort->gains[j].min_value,
1256 nAudioPort->gains[j].max_value,
1257 nAudioPort->gains[j].default_value,
1258 nAudioPort->gains[j].step_value,
1259 nAudioPort->gains[j].min_ramp_ms,
1260 nAudioPort->gains[j].max_ramp_ms);
1261 if (jGain == NULL) {
1262 jStatus = (jint)AUDIO_JAVA_ERROR;
1263 goto exit;
1264 }
1265 env->SetObjectArrayElement(jGains, j, jGain);
1266 env->DeleteLocalRef(jGain);
1267 }
1268
1269 jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1270 nAudioPort->id);
1271 if (jHandle == NULL) {
1272 jStatus = (jint)AUDIO_JAVA_ERROR;
1273 goto exit;
1274 }
1275
Paul McLean10804eb2015-01-28 11:16:35 -08001276 jDeviceName = env->NewStringUTF(nAudioPort->name);
1277
Eric Laurentb69681c2014-05-19 19:02:51 -07001278 if (nAudioPort->type == AUDIO_PORT_TYPE_DEVICE) {
1279 ALOGV("convertAudioPortFromNative is a device %08x", nAudioPort->ext.device.type);
1280 jstring jAddress = env->NewStringUTF(nAudioPort->ext.device.address);
1281 *jAudioPort = env->NewObject(gAudioDevicePortClass, gAudioDevicePortCstor,
Paul McLean10804eb2015-01-28 11:16:35 -08001282 jHandle, jDeviceName,
Paul McLeanf29e5f32015-06-15 10:19:22 -07001283 jSamplingRates, jChannelMasks, jChannelIndexMasks,
1284 jFormats, jGains,
Eric Laurentb69681c2014-05-19 19:02:51 -07001285 nAudioPort->ext.device.type, jAddress);
1286 env->DeleteLocalRef(jAddress);
1287 } else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) {
1288 ALOGV("convertAudioPortFromNative is a mix");
1289 *jAudioPort = env->NewObject(gAudioMixPortClass, gAudioMixPortCstor,
Eric Laurent4bcdba82015-05-01 11:37:49 -07001290 jHandle, nAudioPort->ext.mix.handle,
1291 nAudioPort->role, jDeviceName,
Paul McLeanf29e5f32015-06-15 10:19:22 -07001292 jSamplingRates, jChannelMasks, jChannelIndexMasks,
Eric Laurentb69681c2014-05-19 19:02:51 -07001293 jFormats, jGains);
1294 } else {
1295 ALOGE("convertAudioPortFromNative unknown nAudioPort type %d", nAudioPort->type);
1296 jStatus = (jint)AUDIO_JAVA_ERROR;
1297 goto exit;
1298 }
1299 if (*jAudioPort == NULL) {
1300 jStatus = (jint)AUDIO_JAVA_ERROR;
1301 goto exit;
1302 }
1303
Eric Laurentb69681c2014-05-19 19:02:51 -07001304 jStatus = convertAudioPortConfigFromNative(env,
1305 *jAudioPort,
1306 &jAudioPortConfig,
1307 &nAudioPort->active_config);
1308 if (jStatus != AUDIO_JAVA_SUCCESS) {
Andy Hung737d9fb2016-08-16 18:38:49 -07001309 goto exit;
Eric Laurentb69681c2014-05-19 19:02:51 -07001310 }
1311
1312 env->SetObjectField(*jAudioPort, gAudioPortFields.mActiveConfig, jAudioPortConfig);
1313
1314exit:
Paul McLean10804eb2015-01-28 11:16:35 -08001315 if (jDeviceName != NULL) {
1316 env->DeleteLocalRef(jDeviceName);
1317 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001318 if (jSamplingRates != NULL) {
1319 env->DeleteLocalRef(jSamplingRates);
1320 }
1321 if (jChannelMasks != NULL) {
1322 env->DeleteLocalRef(jChannelMasks);
1323 }
Paul McLean4e5e9e92015-06-17 10:10:11 -07001324 if (jChannelIndexMasks != NULL) {
1325 env->DeleteLocalRef(jChannelIndexMasks);
1326 }
1327 if (cFormats != NULL) {
1328 delete[] cFormats;
1329 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001330 if (jFormats != NULL) {
1331 env->DeleteLocalRef(jFormats);
1332 }
1333 if (jGains != NULL) {
1334 env->DeleteLocalRef(jGains);
1335 }
1336 if (jHandle != NULL) {
1337 env->DeleteLocalRef(jHandle);
1338 }
xiaomi/hanli82840c42017-07-19 18:53:03 +08001339 if (jAudioPortConfig != NULL) {
1340 env->DeleteLocalRef(jAudioPortConfig);
1341 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001342
1343 return jStatus;
1344}
1345
Eric Laurentb69681c2014-05-19 19:02:51 -07001346static jint
1347android_media_AudioSystem_listAudioPorts(JNIEnv *env, jobject clazz,
1348 jobject jPorts, jintArray jGeneration)
1349{
1350 ALOGV("listAudioPorts");
1351
1352 if (jPorts == NULL) {
1353 ALOGE("listAudioPorts NULL AudioPort ArrayList");
1354 return (jint)AUDIO_JAVA_BAD_VALUE;
1355 }
1356 if (!env->IsInstanceOf(jPorts, gArrayListClass)) {
1357 ALOGE("listAudioPorts not an arraylist");
1358 return (jint)AUDIO_JAVA_BAD_VALUE;
1359 }
1360
1361 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1362 return (jint)AUDIO_JAVA_BAD_VALUE;
1363 }
1364
1365 status_t status;
1366 unsigned int generation1;
1367 unsigned int generation;
1368 unsigned int numPorts;
1369 jint *nGeneration;
1370 struct audio_port *nPorts = NULL;
1371 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
Eric Laurentb36d1042016-04-14 18:00:38 -07001372 jint jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001373
1374 // get the port count and all the ports until they both return the same generation
1375 do {
1376 if (attempts-- < 0) {
1377 status = TIMED_OUT;
1378 break;
1379 }
1380
1381 numPorts = 0;
1382 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE,
1383 AUDIO_PORT_TYPE_NONE,
1384 &numPorts,
1385 NULL,
1386 &generation1);
Eric Laurentb36d1042016-04-14 18:00:38 -07001387 if (status != NO_ERROR) {
Eric Laurentb69681c2014-05-19 19:02:51 -07001388 ALOGE_IF(status != NO_ERROR, "AudioSystem::listAudioPorts error %d", status);
1389 break;
1390 }
Eric Laurentb36d1042016-04-14 18:00:38 -07001391 if (numPorts == 0) {
1392 jStatus = (jint)AUDIO_JAVA_SUCCESS;
1393 goto exit;
1394 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001395 nPorts = (struct audio_port *)realloc(nPorts, numPorts * sizeof(struct audio_port));
1396
1397 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE,
1398 AUDIO_PORT_TYPE_NONE,
1399 &numPorts,
1400 nPorts,
1401 &generation);
1402 ALOGV("listAudioPorts AudioSystem::listAudioPorts numPorts %d generation %d generation1 %d",
1403 numPorts, generation, generation1);
1404 } while (generation1 != generation && status == NO_ERROR);
1405
Eric Laurentb36d1042016-04-14 18:00:38 -07001406 jStatus = nativeToJavaStatus(status);
Eric Laurentb69681c2014-05-19 19:02:51 -07001407 if (jStatus != AUDIO_JAVA_SUCCESS) {
1408 goto exit;
1409 }
1410
Eric Laurentb69681c2014-05-19 19:02:51 -07001411 for (size_t i = 0; i < numPorts; i++) {
xiaomi/hanli82840c42017-07-19 18:53:03 +08001412 jobject jAudioPort = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001413 jStatus = convertAudioPortFromNative(env, &jAudioPort, &nPorts[i]);
1414 if (jStatus != AUDIO_JAVA_SUCCESS) {
1415 goto exit;
1416 }
1417 env->CallBooleanMethod(jPorts, gArrayListMethods.add, jAudioPort);
xiaomi/hanli82840c42017-07-19 18:53:03 +08001418 if (jAudioPort != NULL) {
1419 env->DeleteLocalRef(jAudioPort);
1420 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001421 }
1422
1423exit:
Eric Laurentb36d1042016-04-14 18:00:38 -07001424 nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1425 if (nGeneration == NULL) {
1426 jStatus = (jint)AUDIO_JAVA_ERROR;
1427 } else {
1428 nGeneration[0] = generation1;
1429 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1430 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001431 free(nPorts);
1432 return jStatus;
1433}
1434
1435static int
1436android_media_AudioSystem_createAudioPatch(JNIEnv *env, jobject clazz,
1437 jobjectArray jPatches, jobjectArray jSources, jobjectArray jSinks)
1438{
1439 status_t status;
1440 jint jStatus;
1441
1442 ALOGV("createAudioPatch");
1443 if (jPatches == NULL || jSources == NULL || jSinks == NULL) {
1444 return (jint)AUDIO_JAVA_BAD_VALUE;
1445 }
1446
1447 if (env->GetArrayLength(jPatches) != 1) {
1448 return (jint)AUDIO_JAVA_BAD_VALUE;
1449 }
1450 jint numSources = env->GetArrayLength(jSources);
1451 if (numSources == 0 || numSources > AUDIO_PATCH_PORTS_MAX) {
1452 return (jint)AUDIO_JAVA_BAD_VALUE;
1453 }
1454
1455 jint numSinks = env->GetArrayLength(jSinks);
1456 if (numSinks == 0 || numSinks > AUDIO_PATCH_PORTS_MAX) {
1457 return (jint)AUDIO_JAVA_BAD_VALUE;
1458 }
1459
1460 audio_patch_handle_t handle = (audio_patch_handle_t)0;
1461 jobject jPatch = env->GetObjectArrayElement(jPatches, 0);
1462 jobject jPatchHandle = NULL;
1463 if (jPatch != NULL) {
1464 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1465 return (jint)AUDIO_JAVA_BAD_VALUE;
1466 }
1467 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1468 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1469 }
1470
Mikhail Naganov304eafc2018-05-23 16:54:12 -07001471 struct audio_patch nPatch = { .id = handle };
Eric Laurentb69681c2014-05-19 19:02:51 -07001472
Eric Laurentb69681c2014-05-19 19:02:51 -07001473 jobject jSource = NULL;
1474 jobject jSink = NULL;
1475
1476 for (jint i = 0; i < numSources; i++) {
1477 jSource = env->GetObjectArrayElement(jSources, i);
1478 if (!env->IsInstanceOf(jSource, gAudioPortConfigClass)) {
1479 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1480 goto exit;
1481 }
Eric Laurent6368a7d2014-11-19 12:18:32 -08001482 jStatus = convertAudioPortConfigToNative(env, &nPatch.sources[i], jSource, false);
Eric Laurentb69681c2014-05-19 19:02:51 -07001483 env->DeleteLocalRef(jSource);
1484 jSource = NULL;
1485 if (jStatus != AUDIO_JAVA_SUCCESS) {
1486 goto exit;
1487 }
1488 nPatch.num_sources++;
1489 }
1490
1491 for (jint i = 0; i < numSinks; i++) {
1492 jSink = env->GetObjectArrayElement(jSinks, i);
1493 if (!env->IsInstanceOf(jSink, gAudioPortConfigClass)) {
1494 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1495 goto exit;
1496 }
Eric Laurent6368a7d2014-11-19 12:18:32 -08001497 jStatus = convertAudioPortConfigToNative(env, &nPatch.sinks[i], jSink, false);
Eric Laurentb69681c2014-05-19 19:02:51 -07001498 env->DeleteLocalRef(jSink);
1499 jSink = NULL;
1500 if (jStatus != AUDIO_JAVA_SUCCESS) {
1501 goto exit;
1502 }
1503 nPatch.num_sinks++;
1504 }
1505
1506 ALOGV("AudioSystem::createAudioPatch");
1507 status = AudioSystem::createAudioPatch(&nPatch, &handle);
1508 ALOGV("AudioSystem::createAudioPatch() returned %d hande %d", status, handle);
1509
1510 jStatus = nativeToJavaStatus(status);
1511 if (jStatus != AUDIO_JAVA_SUCCESS) {
1512 goto exit;
1513 }
1514
1515 if (jPatchHandle == NULL) {
1516 jPatchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1517 handle);
1518 if (jPatchHandle == NULL) {
1519 jStatus = (jint)AUDIO_JAVA_ERROR;
1520 goto exit;
1521 }
1522 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor, jPatchHandle, jSources, jSinks);
1523 if (jPatch == NULL) {
1524 jStatus = (jint)AUDIO_JAVA_ERROR;
1525 goto exit;
1526 }
1527 env->SetObjectArrayElement(jPatches, 0, jPatch);
1528 } else {
1529 env->SetIntField(jPatchHandle, gAudioHandleFields.mId, handle);
1530 }
1531
1532exit:
1533 if (jPatchHandle != NULL) {
1534 env->DeleteLocalRef(jPatchHandle);
1535 }
1536 if (jPatch != NULL) {
1537 env->DeleteLocalRef(jPatch);
1538 }
1539 if (jSource != NULL) {
1540 env->DeleteLocalRef(jSource);
1541 }
1542 if (jSink != NULL) {
1543 env->DeleteLocalRef(jSink);
1544 }
1545 return jStatus;
1546}
1547
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001548static jint
Eric Laurentb69681c2014-05-19 19:02:51 -07001549android_media_AudioSystem_releaseAudioPatch(JNIEnv *env, jobject clazz,
1550 jobject jPatch)
1551{
1552 ALOGV("releaseAudioPatch");
1553 if (jPatch == NULL) {
1554 return (jint)AUDIO_JAVA_BAD_VALUE;
1555 }
1556
1557 audio_patch_handle_t handle = (audio_patch_handle_t)0;
1558 jobject jPatchHandle = NULL;
1559 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1560 return (jint)AUDIO_JAVA_BAD_VALUE;
1561 }
1562 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1563 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1564 env->DeleteLocalRef(jPatchHandle);
1565
1566 ALOGV("AudioSystem::releaseAudioPatch");
1567 status_t status = AudioSystem::releaseAudioPatch(handle);
1568 ALOGV("AudioSystem::releaseAudioPatch() returned %d", status);
1569 jint jStatus = nativeToJavaStatus(status);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001570 return jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001571}
1572
1573static jint
1574android_media_AudioSystem_listAudioPatches(JNIEnv *env, jobject clazz,
1575 jobject jPatches, jintArray jGeneration)
1576{
1577 ALOGV("listAudioPatches");
1578 if (jPatches == NULL) {
1579 ALOGE("listAudioPatches NULL AudioPatch ArrayList");
1580 return (jint)AUDIO_JAVA_BAD_VALUE;
1581 }
1582 if (!env->IsInstanceOf(jPatches, gArrayListClass)) {
1583 ALOGE("listAudioPatches not an arraylist");
1584 return (jint)AUDIO_JAVA_BAD_VALUE;
1585 }
1586
1587 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1588 return (jint)AUDIO_JAVA_BAD_VALUE;
1589 }
1590
1591 status_t status;
1592 unsigned int generation1;
1593 unsigned int generation;
1594 unsigned int numPatches;
1595 jint *nGeneration;
1596 struct audio_patch *nPatches = NULL;
1597 jobjectArray jSources = NULL;
1598 jobject jSource = NULL;
1599 jobjectArray jSinks = NULL;
1600 jobject jSink = NULL;
1601 jobject jPatch = NULL;
1602 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
Eric Laurentb36d1042016-04-14 18:00:38 -07001603 jint jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001604
1605 // get the patch count and all the patches until they both return the same generation
1606 do {
1607 if (attempts-- < 0) {
1608 status = TIMED_OUT;
1609 break;
1610 }
1611
1612 numPatches = 0;
1613 status = AudioSystem::listAudioPatches(&numPatches,
1614 NULL,
1615 &generation1);
Eric Laurentb36d1042016-04-14 18:00:38 -07001616 if (status != NO_ERROR) {
Eric Laurentb69681c2014-05-19 19:02:51 -07001617 ALOGE_IF(status != NO_ERROR, "listAudioPatches AudioSystem::listAudioPatches error %d",
1618 status);
1619 break;
1620 }
Eric Laurentb36d1042016-04-14 18:00:38 -07001621 if (numPatches == 0) {
1622 jStatus = (jint)AUDIO_JAVA_SUCCESS;
1623 goto exit;
1624 }
1625
Eric Laurentb69681c2014-05-19 19:02:51 -07001626 nPatches = (struct audio_patch *)realloc(nPatches, numPatches * sizeof(struct audio_patch));
1627
1628 status = AudioSystem::listAudioPatches(&numPatches,
1629 nPatches,
1630 &generation);
1631 ALOGV("listAudioPatches AudioSystem::listAudioPatches numPatches %d generation %d generation1 %d",
1632 numPatches, generation, generation1);
1633
1634 } while (generation1 != generation && status == NO_ERROR);
1635
Eric Laurentb36d1042016-04-14 18:00:38 -07001636 jStatus = nativeToJavaStatus(status);
Eric Laurentb69681c2014-05-19 19:02:51 -07001637 if (jStatus != AUDIO_JAVA_SUCCESS) {
1638 goto exit;
1639 }
1640
Eric Laurentb69681c2014-05-19 19:02:51 -07001641 for (size_t i = 0; i < numPatches; i++) {
1642 jobject patchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1643 nPatches[i].id);
1644 if (patchHandle == NULL) {
1645 jStatus = AUDIO_JAVA_ERROR;
1646 goto exit;
1647 }
Dan Albert46d84442014-11-18 16:07:51 -08001648 ALOGV("listAudioPatches patch %zu num_sources %d num_sinks %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001649 i, nPatches[i].num_sources, nPatches[i].num_sinks);
1650
1651 env->SetIntField(patchHandle, gAudioHandleFields.mId, nPatches[i].id);
1652
1653 // load sources
1654 jSources = env->NewObjectArray(nPatches[i].num_sources,
1655 gAudioPortConfigClass, NULL);
1656 if (jSources == NULL) {
1657 jStatus = AUDIO_JAVA_ERROR;
1658 goto exit;
1659 }
1660
1661 for (size_t j = 0; j < nPatches[i].num_sources; j++) {
1662 jStatus = convertAudioPortConfigFromNative(env,
1663 NULL,
1664 &jSource,
1665 &nPatches[i].sources[j]);
1666 if (jStatus != AUDIO_JAVA_SUCCESS) {
1667 goto exit;
1668 }
1669 env->SetObjectArrayElement(jSources, j, jSource);
1670 env->DeleteLocalRef(jSource);
1671 jSource = NULL;
Dan Albert46d84442014-11-18 16:07:51 -08001672 ALOGV("listAudioPatches patch %zu source %zu is a %s handle %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001673 i, j,
1674 nPatches[i].sources[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1675 nPatches[i].sources[j].id);
1676 }
1677 // load sinks
1678 jSinks = env->NewObjectArray(nPatches[i].num_sinks,
1679 gAudioPortConfigClass, NULL);
1680 if (jSinks == NULL) {
1681 jStatus = AUDIO_JAVA_ERROR;
1682 goto exit;
1683 }
1684
1685 for (size_t j = 0; j < nPatches[i].num_sinks; j++) {
1686 jStatus = convertAudioPortConfigFromNative(env,
1687 NULL,
1688 &jSink,
1689 &nPatches[i].sinks[j]);
1690
1691 if (jStatus != AUDIO_JAVA_SUCCESS) {
1692 goto exit;
1693 }
1694 env->SetObjectArrayElement(jSinks, j, jSink);
1695 env->DeleteLocalRef(jSink);
1696 jSink = NULL;
Dan Albert46d84442014-11-18 16:07:51 -08001697 ALOGV("listAudioPatches patch %zu sink %zu is a %s handle %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001698 i, j,
1699 nPatches[i].sinks[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1700 nPatches[i].sinks[j].id);
1701 }
1702
1703 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor,
1704 patchHandle, jSources, jSinks);
1705 env->DeleteLocalRef(jSources);
1706 jSources = NULL;
1707 env->DeleteLocalRef(jSinks);
1708 jSinks = NULL;
1709 if (jPatch == NULL) {
1710 jStatus = AUDIO_JAVA_ERROR;
1711 goto exit;
1712 }
1713 env->CallBooleanMethod(jPatches, gArrayListMethods.add, jPatch);
1714 env->DeleteLocalRef(jPatch);
1715 jPatch = NULL;
1716 }
1717
1718exit:
Eric Laurentb36d1042016-04-14 18:00:38 -07001719
1720 nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1721 if (nGeneration == NULL) {
1722 jStatus = AUDIO_JAVA_ERROR;
1723 } else {
1724 nGeneration[0] = generation1;
1725 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1726 }
1727
Eric Laurentb69681c2014-05-19 19:02:51 -07001728 if (jSources != NULL) {
1729 env->DeleteLocalRef(jSources);
1730 }
1731 if (jSource != NULL) {
1732 env->DeleteLocalRef(jSource);
1733 }
1734 if (jSinks != NULL) {
1735 env->DeleteLocalRef(jSinks);
1736 }
1737 if (jSink != NULL) {
1738 env->DeleteLocalRef(jSink);
1739 }
1740 if (jPatch != NULL) {
1741 env->DeleteLocalRef(jPatch);
1742 }
1743 free(nPatches);
1744 return jStatus;
1745}
1746
Eric Laurent3a241992014-05-19 19:33:26 -07001747static jint
1748android_media_AudioSystem_setAudioPortConfig(JNIEnv *env, jobject clazz,
1749 jobject jAudioPortConfig)
1750{
1751 ALOGV("setAudioPortConfig");
1752 if (jAudioPortConfig == NULL) {
1753 return AUDIO_JAVA_BAD_VALUE;
1754 }
1755 if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
1756 return AUDIO_JAVA_BAD_VALUE;
1757 }
Mikhail Naganov304eafc2018-05-23 16:54:12 -07001758 struct audio_port_config nAudioPortConfig = {};
Eric Laurent6368a7d2014-11-19 12:18:32 -08001759 jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig, true);
Eric Laurent3a241992014-05-19 19:33:26 -07001760 if (jStatus != AUDIO_JAVA_SUCCESS) {
1761 return jStatus;
1762 }
1763 status_t status = AudioSystem::setAudioPortConfig(&nAudioPortConfig);
1764 ALOGV("AudioSystem::setAudioPortConfig() returned %d", status);
1765 jStatus = nativeToJavaStatus(status);
1766 return jStatus;
1767}
1768
Hongwei Wangf44a5682018-08-24 10:37:56 -07001769/**
1770 * Returns handle if the audio source is successfully started.
1771 */
1772static jint
1773android_media_AudioSystem_startAudioSource(JNIEnv *env, jobject clazz,
1774 jobject jAudioPortConfig,
1775 jobject jAudioAttributes)
1776{
1777 ALOGV("startAudioSource");
1778 if (jAudioPortConfig == NULL || jAudioAttributes == NULL) {
1779 return AUDIO_JAVA_BAD_VALUE;
1780 }
1781 if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
1782 return AUDIO_JAVA_BAD_VALUE;
1783 }
Hongwei Wangf44a5682018-08-24 10:37:56 -07001784 struct audio_port_config nAudioPortConfig = {};
1785 jint jStatus = convertAudioPortConfigToNativeWithDevicePort(env,
1786 &nAudioPortConfig, jAudioPortConfig, false);
1787 if (jStatus != AUDIO_JAVA_SUCCESS) {
1788 return jStatus;
1789 }
François Gaffieb4691282018-07-09 13:07:32 +02001790 auto paa = JNIAudioAttributeHelper::makeUnique();
1791 jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAudioAttributes, paa.get());
1792 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
Hongwei Wangf44a5682018-08-24 10:37:56 -07001793 return jStatus;
1794 }
1795 audio_port_handle_t handle;
François Gaffieb4691282018-07-09 13:07:32 +02001796 status_t status = AudioSystem::startAudioSource(&nAudioPortConfig, paa.get(), &handle);
Hongwei Wangf44a5682018-08-24 10:37:56 -07001797 ALOGV("AudioSystem::startAudioSource() returned %d handle %d", status, handle);
1798 return handle > 0 ? handle : nativeToJavaStatus(status);
1799}
1800
1801static jint
1802android_media_AudioSystem_stopAudioSource(JNIEnv *env, jobject clazz, jint handle)
1803{
1804 ALOGV("stopAudioSource");
1805 status_t status = AudioSystem::stopAudioSource(
1806 static_cast <audio_port_handle_t>(handle));
1807 ALOGV("AudioSystem::stopAudioSource() returned %d", status);
1808 return nativeToJavaStatus(status);
1809}
1810
Eric Laurent700e7342014-05-02 18:33:15 -07001811static void
1812android_media_AudioSystem_eventHandlerSetup(JNIEnv *env, jobject thiz, jobject weak_this)
1813{
1814 ALOGV("eventHandlerSetup");
1815
1816 sp<JNIAudioPortCallback> callback = new JNIAudioPortCallback(env, thiz, weak_this);
1817
Eric Laurent2615afb2015-03-25 14:51:08 -07001818 if (AudioSystem::addAudioPortCallback(callback) == NO_ERROR) {
1819 setJniCallback(env, thiz, callback);
1820 }
Eric Laurent700e7342014-05-02 18:33:15 -07001821}
1822
1823static void
1824android_media_AudioSystem_eventHandlerFinalize(JNIEnv *env, jobject thiz)
1825{
1826 ALOGV("eventHandlerFinalize");
1827
Eric Laurent2615afb2015-03-25 14:51:08 -07001828 sp<JNIAudioPortCallback> callback = setJniCallback(env, thiz, 0);
Eric Laurent700e7342014-05-02 18:33:15 -07001829
Eric Laurent2615afb2015-03-25 14:51:08 -07001830 if (callback != 0) {
1831 AudioSystem::removeAudioPortCallback(callback);
1832 }
Eric Laurent700e7342014-05-02 18:33:15 -07001833}
1834
Eric Laurentb634e1b2014-08-01 14:44:46 -07001835static jint
1836android_media_AudioSystem_getAudioHwSyncForSession(JNIEnv *env, jobject thiz, jint sessionId)
1837{
Glenn Kasten33b84042016-03-08 12:02:55 -08001838 return (jint) AudioSystem::getAudioHwSyncForSession((audio_session_t) sessionId);
Eric Laurentb634e1b2014-08-01 14:44:46 -07001839}
1840
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07001841static void
1842android_media_AudioSystem_registerDynPolicyCallback(JNIEnv *env, jobject thiz)
1843{
1844 AudioSystem::setDynPolicyCallback(android_media_AudioSystem_dyn_policy_callback);
1845}
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001846
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08001847static void
1848android_media_AudioSystem_registerRecordingCallback(JNIEnv *env, jobject thiz)
1849{
1850 AudioSystem::setRecordConfigCallback(android_media_AudioSystem_recording_callback);
1851}
1852
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001853
1854static jint convertAudioMixToNative(JNIEnv *env,
1855 AudioMix *nAudioMix,
1856 const jobject jAudioMix)
1857{
1858 nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType);
1859 nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags);
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07001860 nAudioMix->mDeviceType = (audio_devices_t)
1861 env->GetIntField(jAudioMix, gAudioMixFields.mDeviceType);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001862
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07001863 jstring jDeviceAddress = (jstring)env->GetObjectField(jAudioMix,
1864 gAudioMixFields.mDeviceAddress);
1865 const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
1866 nAudioMix->mDeviceAddress = String8(nDeviceAddress);
1867 env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
1868 env->DeleteLocalRef(jDeviceAddress);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001869
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07001870 nAudioMix->mCbFlags = env->GetIntField(jAudioMix, gAudioMixFields.mCallbackFlags);
1871
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001872 jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat);
1873 nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat,
1874 gAudioFormatFields.mSampleRate);
1875 nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat,
1876 gAudioFormatFields.mChannelMask));
1877 nAudioMix->mFormat.format = audioFormatToNative(env->GetIntField(jFormat,
1878 gAudioFormatFields.mEncoding));
1879 env->DeleteLocalRef(jFormat);
1880
1881 jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule);
1882 jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria);
Kevin Rocarda3a4bbb2019-03-07 18:29:48 -08001883 nAudioMix->mAllowPrivilegedPlaybackCapture =
1884 env->GetBooleanField(jRule, gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001885 env->DeleteLocalRef(jRule);
1886 jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria,
1887 gArrayListMethods.toArray);
1888 env->DeleteLocalRef(jRuleCriteria);
1889
1890 jint numCriteria = env->GetArrayLength(jCriteria);
1891 if (numCriteria > MAX_CRITERIA_PER_MIX) {
1892 numCriteria = MAX_CRITERIA_PER_MIX;
1893 }
1894
1895 for (jint i = 0; i < numCriteria; i++) {
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001896 AudioMixMatchCriterion nCriterion;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001897
1898 jobject jCriterion = env->GetObjectArrayElement(jCriteria, i);
1899
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001900 nCriterion.mRule = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mRule);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001901
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001902 const uint32_t match_rule = nCriterion.mRule & ~RULE_EXCLUSION_MASK;
1903 switch (match_rule) {
1904 case RULE_MATCH_UID:
1905 nCriterion.mValue.mUid = env->GetIntField(jCriterion,
1906 gAudioMixMatchCriterionFields.mIntProp);
1907 break;
1908 case RULE_MATCH_ATTRIBUTE_USAGE:
1909 case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: {
1910 jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr);
François Gaffieb4691282018-07-09 13:07:32 +02001911
1912 auto paa = JNIAudioAttributeHelper::makeUnique();
1913 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAttributes, paa.get());
1914 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
1915 return jStatus;
1916 }
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001917 if (match_rule == RULE_MATCH_ATTRIBUTE_USAGE) {
François Gaffieb4691282018-07-09 13:07:32 +02001918 nCriterion.mValue.mUsage = paa->usage;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001919 } else {
François Gaffieb4691282018-07-09 13:07:32 +02001920 nCriterion.mValue.mSource = paa->source;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001921 }
1922 env->DeleteLocalRef(jAttributes);
1923 }
1924 break;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001925 }
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001926
1927 nAudioMix->mCriteria.add(nCriterion);
1928 env->DeleteLocalRef(jCriterion);
1929 }
1930
1931 env->DeleteLocalRef(jCriteria);
1932
1933 return (jint)AUDIO_JAVA_SUCCESS;
1934}
1935
1936static jint
1937android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz,
1938 jobject jMixesList, jboolean registration)
1939{
1940 ALOGV("registerPolicyMixes");
1941
1942 if (jMixesList == NULL) {
1943 return (jint)AUDIO_JAVA_BAD_VALUE;
1944 }
1945 if (!env->IsInstanceOf(jMixesList, gArrayListClass)) {
1946 return (jint)AUDIO_JAVA_BAD_VALUE;
1947 }
1948 jobjectArray jMixes = (jobjectArray)env->CallObjectMethod(jMixesList,
1949 gArrayListMethods.toArray);
1950 jint numMixes = env->GetArrayLength(jMixes);
1951 if (numMixes > MAX_MIXES_PER_POLICY) {
1952 numMixes = MAX_MIXES_PER_POLICY;
1953 }
1954
1955 status_t status;
1956 jint jStatus;
1957 jobject jAudioMix = NULL;
1958 Vector <AudioMix> mixes;
1959 for (jint i = 0; i < numMixes; i++) {
1960 jAudioMix = env->GetObjectArrayElement(jMixes, i);
1961 if (!env->IsInstanceOf(jAudioMix, gAudioMixClass)) {
1962 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1963 goto exit;
1964 }
1965 AudioMix mix;
1966 jStatus = convertAudioMixToNative(env, &mix, jAudioMix);
1967 env->DeleteLocalRef(jAudioMix);
1968 jAudioMix = NULL;
1969 if (jStatus != AUDIO_JAVA_SUCCESS) {
1970 goto exit;
1971 }
1972 mixes.add(mix);
1973 }
1974
1975 ALOGV("AudioSystem::registerPolicyMixes numMixes %d registration %d", numMixes, registration);
1976 status = AudioSystem::registerPolicyMixes(mixes, registration);
1977 ALOGV("AudioSystem::registerPolicyMixes() returned %d", status);
1978
1979 jStatus = nativeToJavaStatus(status);
1980 if (jStatus != AUDIO_JAVA_SUCCESS) {
1981 goto exit;
1982 }
1983
1984exit:
1985 if (jAudioMix != NULL) {
1986 env->DeleteLocalRef(jAudioMix);
1987 }
1988 return jStatus;
1989}
1990
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08001991static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz,
1992 jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) {
1993 if (deviceTypes == nullptr || deviceAddresses == nullptr) {
1994 return (jint) AUDIO_JAVA_BAD_VALUE;
1995 }
1996 jsize nb = env->GetArrayLength(deviceTypes);
1997 if (nb == 0 || nb != env->GetArrayLength(deviceAddresses)) {
1998 return (jint) AUDIO_JAVA_BAD_VALUE;
1999 }
2000 // retrieve all device types
2001 std::vector<audio_devices_t> deviceTypesVector;
2002 jint* typesPtr = nullptr;
2003 typesPtr = env->GetIntArrayElements(deviceTypes, 0);
2004 if (typesPtr == nullptr) {
2005 return (jint) AUDIO_JAVA_BAD_VALUE;
2006 }
2007 for (jint i = 0; i < nb; i++) {
2008 deviceTypesVector.push_back((audio_devices_t) typesPtr[i]);
2009 }
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002010
2011 // check each address is a string and add device type/address to list for device affinity
2012 Vector<AudioDeviceTypeAddr> deviceVector;
2013 jclass stringClass = FindClassOrDie(env, "java/lang/String");
2014 for (jint i = 0; i < nb; i++) {
2015 jobject addrJobj = env->GetObjectArrayElement(deviceAddresses, i);
2016 if (!env->IsInstanceOf(addrJobj, stringClass)) {
2017 return (jint) AUDIO_JAVA_BAD_VALUE;
2018 }
jiabin111725d2019-11-04 14:16:21 -08002019 const char* address = env->GetStringUTFChars((jstring) addrJobj, NULL);
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002020 AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address);
2021 deviceVector.add(dev);
jiabin111725d2019-11-04 14:16:21 -08002022 env->ReleaseStringUTFChars((jstring) addrJobj, address);
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002023 }
Hongwei Wang94d58002019-02-13 16:59:32 -08002024 env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0);
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002025
2026 status_t status = AudioSystem::setUidDeviceAffinities((uid_t) uid, deviceVector);
2027 return (jint) nativeToJavaStatus(status);
2028}
2029
2030static jint android_media_AudioSystem_removeUidDeviceAffinities(JNIEnv *env, jobject clazz,
2031 jint uid) {
Oscar Azucena3d6341f2019-04-26 23:45:28 -07002032 status_t status = AudioSystem::removeUidDeviceAffinities((uid_t) uid);
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002033 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
Eric Laurent6acdc092019-06-11 14:29:42 -07002247static jint
2248android_media_AudioSystem_setRttEnabled(JNIEnv *env, jobject thiz, jboolean enabled)
2249{
2250 return (jint) check_AudioSystem_Command(AudioSystem::setRttEnabled(enabled));
2251}
2252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002253// ----------------------------------------------------------------------------
2254
Daniel Micay76f6a862015-09-19 17:31:01 -04002255static const JNINativeMethod gMethods[] = {
Eric Laurenta553c252009-07-17 12:17:14 -07002256 {"setParameters", "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
2257 {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
2259 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
Jean-Michel Trivid6770542012-10-10 12:03:41 -07002260 {"isStreamActive", "(II)Z", (void *)android_media_AudioSystem_isStreamActive},
Jean-Michel Trivi679d5042013-02-04 16:24:09 -08002261 {"isStreamActiveRemotely","(II)Z", (void *)android_media_AudioSystem_isStreamActiveRemotely},
Jean-Michel Trivid6770542012-10-10 12:03:41 -07002262 {"isSourceActive", "(I)Z", (void *)android_media_AudioSystem_isSourceActive},
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -07002263 {"newAudioSessionId", "()I", (void *)android_media_AudioSystem_newAudioSessionId},
Jean-Michel Trivi292a6a42016-12-01 08:32:15 -08002264 {"newAudioPlayerId", "()I", (void *)android_media_AudioSystem_newAudioPlayerId},
Mikhail Naganova00883d2019-04-18 12:36:27 -07002265 {"newAudioRecorderId", "()I", (void *)android_media_AudioSystem_newAudioRecorderId},
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -08002266 {"setDeviceConnectionState", "(IILjava/lang/String;Ljava/lang/String;I)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
Eric Laurenta553c252009-07-17 12:17:14 -07002267 {"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -08002268 {"handleDeviceConfigChange", "(ILjava/lang/String;Ljava/lang/String;I)I", (void *)android_media_AudioSystem_handleDeviceConfigChange},
Eric Laurenta553c252009-07-17 12:17:14 -07002269 {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
Eric Laurenta553c252009-07-17 12:17:14 -07002270 {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
2271 {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
2272 {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume},
Eric Laurent9bc8358d2011-11-18 16:43:31 -08002273 {"setStreamVolumeIndex","(III)I", (void *)android_media_AudioSystem_setStreamVolumeIndex},
2274 {"getStreamVolumeIndex","(II)I", (void *)android_media_AudioSystem_getStreamVolumeIndex},
François Gaffieebb67d02018-09-14 15:05:04 +02002275 {"setVolumeIndexForAttributes","(Landroid/media/AudioAttributes;II)I", (void *)android_media_AudioSystem_setVolumeIndexForAttributes},
2276 {"getVolumeIndexForAttributes","(Landroid/media/AudioAttributes;I)I", (void *)android_media_AudioSystem_getVolumeIndexForAttributes},
2277 {"getMinVolumeIndexForAttributes","(Landroid/media/AudioAttributes;)I", (void *)android_media_AudioSystem_getMinVolumeIndexForAttributes},
2278 {"getMaxVolumeIndexForAttributes","(Landroid/media/AudioAttributes;)I", (void *)android_media_AudioSystem_getMaxVolumeIndexForAttributes},
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -04002279 {"setMasterVolume", "(F)I", (void *)android_media_AudioSystem_setMasterVolume},
2280 {"getMasterVolume", "()F", (void *)android_media_AudioSystem_getMasterVolume},
2281 {"setMasterMute", "(Z)I", (void *)android_media_AudioSystem_setMasterMute},
2282 {"getMasterMute", "()Z", (void *)android_media_AudioSystem_getMasterMute},
Andy Hungf04b84d2015-12-18 17:33:27 -08002283 {"setMasterMono", "(Z)I", (void *)android_media_AudioSystem_setMasterMono},
2284 {"getMasterMono", "()Z", (void *)android_media_AudioSystem_getMasterMono},
Edward Savage-Jones35c292f2017-01-13 09:04:34 +01002285 {"setMasterBalance", "(F)I", (void *)android_media_AudioSystem_setMasterBalance},
2286 {"getMasterBalance", "()F", (void *)android_media_AudioSystem_getMasterBalance},
Glenn Kasten8b4b97a2011-02-04 13:54:26 -08002287 {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream},
Glenn Kastenc6c43652012-09-24 17:32:30 -07002288 {"getPrimaryOutputSamplingRate", "()I", (void *)android_media_AudioSystem_getPrimaryOutputSamplingRate},
2289 {"getPrimaryOutputFrameCount", "()I", (void *)android_media_AudioSystem_getPrimaryOutputFrameCount},
Oliver Woodman61dcdf32013-06-26 12:43:36 +01002290 {"getOutputLatency", "(I)I", (void *)android_media_AudioSystem_getOutputLatency},
Andy Hung79583582018-01-23 13:58:02 -08002291 {"setLowRamDevice", "(ZJ)I", (void *)android_media_AudioSystem_setLowRamDevice},
Eric Laurentdfb881f2013-07-18 14:41:39 -07002292 {"checkAudioFlinger", "()I", (void *)android_media_AudioSystem_checkAudioFlinger},
Eric Laurentb69681c2014-05-19 19:02:51 -07002293 {"listAudioPorts", "(Ljava/util/ArrayList;[I)I",
2294 (void *)android_media_AudioSystem_listAudioPorts},
2295 {"createAudioPatch", "([Landroid/media/AudioPatch;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)I",
2296 (void *)android_media_AudioSystem_createAudioPatch},
2297 {"releaseAudioPatch", "(Landroid/media/AudioPatch;)I",
2298 (void *)android_media_AudioSystem_releaseAudioPatch},
2299 {"listAudioPatches", "(Ljava/util/ArrayList;[I)I",
2300 (void *)android_media_AudioSystem_listAudioPatches},
Eric Laurent3a241992014-05-19 19:33:26 -07002301 {"setAudioPortConfig", "(Landroid/media/AudioPortConfig;)I",
2302 (void *)android_media_AudioSystem_setAudioPortConfig},
Hongwei Wangf44a5682018-08-24 10:37:56 -07002303 {"startAudioSource", "(Landroid/media/AudioPortConfig;Landroid/media/AudioAttributes;)I",
2304 (void *)android_media_AudioSystem_startAudioSource},
2305 {"stopAudioSource", "(I)I", (void *)android_media_AudioSystem_stopAudioSource},
Eric Laurentb634e1b2014-08-01 14:44:46 -07002306 {"getAudioHwSyncForSession", "(I)I",
2307 (void *)android_media_AudioSystem_getAudioHwSyncForSession},
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002308 {"registerPolicyMixes", "(Ljava/util/ArrayList;Z)I",
2309 (void *)android_media_AudioSystem_registerPolicyMixes},
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002310 {"setUidDeviceAffinities", "(I[I[Ljava/lang/String;)I",
2311 (void *)android_media_AudioSystem_setUidDeviceAffinities},
2312 {"removeUidDeviceAffinities", "(I)I",
2313 (void *)android_media_AudioSystem_removeUidDeviceAffinities},
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002314 {"native_register_dynamic_policy_callback", "()V",
2315 (void *)android_media_AudioSystem_registerDynPolicyCallback},
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002316 {"native_register_recording_callback", "()V",
2317 (void *)android_media_AudioSystem_registerRecordingCallback},
Eric Laurent0867bed2015-05-20 14:49:08 -07002318 {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady},
Eric Laurenteab40d12017-06-09 12:45:21 -07002319 {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
Jean-Michel Trivif3fd84a2019-03-21 16:08:50 -07002320 {"native_is_offload_supported", "(IIIII)Z", (void *)android_media_AudioSystem_isOffloadSupported},
jiabinc0f49442018-01-05 10:23:50 -08002321 {"getMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioSystem_getMicrophones},
jiabin39940752018-04-02 18:18:45 -07002322 {"getSurroundFormats", "(Ljava/util/Map;Z)I", (void *)android_media_AudioSystem_getSurroundFormats},
2323 {"setSurroundFormatEnabled", "(IZ)I", (void *)android_media_AudioSystem_setSurroundFormatEnabled},
Eric Laurent1c9c1d52018-10-17 10:06:46 -07002324 {"setAssistantUid", "(I)I", (void *)android_media_AudioSystem_setAssistantUid},
2325 {"setA11yServicesUids", "([I)I", (void *)android_media_AudioSystem_setA11yServicesUids},
jiabin66f9e722018-11-02 16:20:19 -07002326 {"isHapticPlaybackSupported", "()Z", (void *)android_media_AudioSystem_isHapticPlaybackSupported},
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002327 {"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
2328 (void*)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
Kevin Rocard7919c2a2019-03-21 10:28:01 -07002329 {"setAllowedCapturePolicy", "(II)I", (void *)android_media_AudioSystem_setAllowedCapturePolicy},
Eric Laurent6acdc092019-06-11 14:29:42 -07002330 {"setRttEnabled", "(Z)I", (void *)android_media_AudioSystem_setRttEnabled},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002331};
2332
Daniel Micay76f6a862015-09-19 17:31:01 -04002333static const JNINativeMethod gEventHandlerMethods[] = {
Eric Laurent700e7342014-05-02 18:33:15 -07002334 {"native_setup",
2335 "(Ljava/lang/Object;)V",
2336 (void *)android_media_AudioSystem_eventHandlerSetup},
2337 {"native_finalize",
2338 "()V",
2339 (void *)android_media_AudioSystem_eventHandlerFinalize},
2340};
2341
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002342static const JNINativeMethod gGetFCC8Methods[] = {
2343 {"native_get_FCC_8", "()I", (void *)android_media_AudioSystem_get_FCC_8},
2344};
2345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346int register_android_media_AudioSystem(JNIEnv *env)
2347{
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002348 // This needs to be done before hooking up methods AudioTrackRoutingProxy (below)
2349 RegisterMethodsOrDie(env, kClassPathName, gGetFCC8Methods, NELEM(gGetFCC8Methods));
2350
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002351 jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
2352 gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
2353 gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
Eric Laurent09378972014-12-10 10:42:08 -08002354 gArrayListMethods.toArray = GetMethodIDOrDie(env, arrayListClass, "toArray", "()[Ljava/lang/Object;");
Eric Laurentb69681c2014-05-19 19:02:51 -07002355
jiabin39940752018-04-02 18:18:45 -07002356 jclass booleanClass = FindClassOrDie(env, "java/lang/Boolean");
2357 gBooleanClass = MakeGlobalRefOrDie(env, booleanClass);
2358 gBooleanCstor = GetMethodIDOrDie(env, booleanClass, "<init>", "(Z)V");
2359
2360 jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
2361 gIntegerClass = MakeGlobalRefOrDie(env, integerClass);
2362 gIntegerCstor = GetMethodIDOrDie(env, integerClass, "<init>", "(I)V");
2363
2364 jclass mapClass = FindClassOrDie(env, "java/util/Map");
2365 gMapClass = MakeGlobalRefOrDie(env, mapClass);
2366 gMapPut = GetMethodIDOrDie(env, mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
2367
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002368 jclass audioHandleClass = FindClassOrDie(env, "android/media/AudioHandle");
2369 gAudioHandleClass = MakeGlobalRefOrDie(env, audioHandleClass);
2370 gAudioHandleCstor = GetMethodIDOrDie(env, audioHandleClass, "<init>", "(I)V");
2371 gAudioHandleFields.mId = GetFieldIDOrDie(env, audioHandleClass, "mId", "I");
Eric Laurentb69681c2014-05-19 19:02:51 -07002372
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002373 jclass audioPortClass = FindClassOrDie(env, "android/media/AudioPort");
2374 gAudioPortClass = MakeGlobalRefOrDie(env, audioPortClass);
2375 gAudioPortCstor = GetMethodIDOrDie(env, audioPortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002376 "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002377 gAudioPortFields.mHandle = GetFieldIDOrDie(env, audioPortClass, "mHandle",
Eric Laurentb69681c2014-05-19 19:02:51 -07002378 "Landroid/media/AudioHandle;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002379 gAudioPortFields.mRole = GetFieldIDOrDie(env, audioPortClass, "mRole", "I");
2380 gAudioPortFields.mGains = GetFieldIDOrDie(env, audioPortClass, "mGains",
Eric Laurentb69681c2014-05-19 19:02:51 -07002381 "[Landroid/media/AudioGain;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002382 gAudioPortFields.mActiveConfig = GetFieldIDOrDie(env, audioPortClass, "mActiveConfig",
2383 "Landroid/media/AudioPortConfig;");
Eric Laurentb69681c2014-05-19 19:02:51 -07002384
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002385 jclass audioPortConfigClass = FindClassOrDie(env, "android/media/AudioPortConfig");
2386 gAudioPortConfigClass = MakeGlobalRefOrDie(env, audioPortConfigClass);
2387 gAudioPortConfigCstor = GetMethodIDOrDie(env, audioPortConfigClass, "<init>",
2388 "(Landroid/media/AudioPort;IIILandroid/media/AudioGainConfig;)V");
2389 gAudioPortConfigFields.mPort = GetFieldIDOrDie(env, audioPortConfigClass, "mPort",
Eric Laurentb69681c2014-05-19 19:02:51 -07002390 "Landroid/media/AudioPort;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002391 gAudioPortConfigFields.mSamplingRate = GetFieldIDOrDie(env, audioPortConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002392 "mSamplingRate", "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002393 gAudioPortConfigFields.mChannelMask = GetFieldIDOrDie(env, audioPortConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002394 "mChannelMask", "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002395 gAudioPortConfigFields.mFormat = GetFieldIDOrDie(env, audioPortConfigClass, "mFormat", "I");
2396 gAudioPortConfigFields.mGain = GetFieldIDOrDie(env, audioPortConfigClass, "mGain",
Eric Laurentb69681c2014-05-19 19:02:51 -07002397 "Landroid/media/AudioGainConfig;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002398 gAudioPortConfigFields.mConfigMask = GetFieldIDOrDie(env, audioPortConfigClass, "mConfigMask",
2399 "I");
Eric Laurentb69681c2014-05-19 19:02:51 -07002400
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002401 jclass audioDevicePortConfigClass = FindClassOrDie(env, "android/media/AudioDevicePortConfig");
2402 gAudioDevicePortConfigClass = MakeGlobalRefOrDie(env, audioDevicePortConfigClass);
2403 gAudioDevicePortConfigCstor = GetMethodIDOrDie(env, audioDevicePortConfigClass, "<init>",
2404 "(Landroid/media/AudioDevicePort;IIILandroid/media/AudioGainConfig;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002405
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002406 jclass audioMixPortConfigClass = FindClassOrDie(env, "android/media/AudioMixPortConfig");
2407 gAudioMixPortConfigClass = MakeGlobalRefOrDie(env, audioMixPortConfigClass);
2408 gAudioMixPortConfigCstor = GetMethodIDOrDie(env, audioMixPortConfigClass, "<init>",
2409 "(Landroid/media/AudioMixPort;IIILandroid/media/AudioGainConfig;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002410
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002411 jclass audioDevicePortClass = FindClassOrDie(env, "android/media/AudioDevicePort");
2412 gAudioDevicePortClass = MakeGlobalRefOrDie(env, audioDevicePortClass);
2413 gAudioDevicePortCstor = GetMethodIDOrDie(env, audioDevicePortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002414 "(Landroid/media/AudioHandle;Ljava/lang/String;[I[I[I[I[Landroid/media/AudioGain;ILjava/lang/String;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002415
Hongwei Wangf44a5682018-08-24 10:37:56 -07002416 // When access AudioPort as AudioDevicePort
2417 gAudioPortFields.mType = GetFieldIDOrDie(env, audioDevicePortClass, "mType", "I");
2418 gAudioPortFields.mAddress = GetFieldIDOrDie(env, audioDevicePortClass, "mAddress",
2419 "Ljava/lang/String;");
2420
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002421 jclass audioMixPortClass = FindClassOrDie(env, "android/media/AudioMixPort");
2422 gAudioMixPortClass = MakeGlobalRefOrDie(env, audioMixPortClass);
2423 gAudioMixPortCstor = GetMethodIDOrDie(env, audioMixPortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002424 "(Landroid/media/AudioHandle;IILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002425
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002426 jclass audioGainClass = FindClassOrDie(env, "android/media/AudioGain");
2427 gAudioGainClass = MakeGlobalRefOrDie(env, audioGainClass);
2428 gAudioGainCstor = GetMethodIDOrDie(env, audioGainClass, "<init>", "(IIIIIIIII)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002429
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002430 jclass audioGainConfigClass = FindClassOrDie(env, "android/media/AudioGainConfig");
2431 gAudioGainConfigClass = MakeGlobalRefOrDie(env, audioGainConfigClass);
2432 gAudioGainConfigCstor = GetMethodIDOrDie(env, audioGainConfigClass, "<init>",
Eric Laurentb69681c2014-05-19 19:02:51 -07002433 "(ILandroid/media/AudioGain;II[II)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002434 gAudioGainConfigFields.mIndex = GetFieldIDOrDie(env, gAudioGainConfigClass, "mIndex", "I");
2435 gAudioGainConfigFields.mMode = GetFieldIDOrDie(env, audioGainConfigClass, "mMode", "I");
2436 gAudioGainConfigFields.mChannelMask = GetFieldIDOrDie(env, audioGainConfigClass, "mChannelMask",
Eric Laurentb69681c2014-05-19 19:02:51 -07002437 "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002438 gAudioGainConfigFields.mValues = GetFieldIDOrDie(env, audioGainConfigClass, "mValues", "[I");
2439 gAudioGainConfigFields.mRampDurationMs = GetFieldIDOrDie(env, audioGainConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002440 "mRampDurationMs", "I");
2441
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002442 jclass audioPatchClass = FindClassOrDie(env, "android/media/AudioPatch");
2443 gAudioPatchClass = MakeGlobalRefOrDie(env, audioPatchClass);
2444 gAudioPatchCstor = GetMethodIDOrDie(env, audioPatchClass, "<init>",
Eric Laurentb69681c2014-05-19 19:02:51 -07002445"(Landroid/media/AudioHandle;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002446 gAudioPatchFields.mHandle = GetFieldIDOrDie(env, audioPatchClass, "mHandle",
Eric Laurentb69681c2014-05-19 19:02:51 -07002447 "Landroid/media/AudioHandle;");
2448
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002449 jclass eventHandlerClass = FindClassOrDie(env, kEventHandlerClassPathName);
Eric Laurent2615afb2015-03-25 14:51:08 -07002450 gAudioPortEventHandlerMethods.postEventFromNative = GetStaticMethodIDOrDie(
2451 env, eventHandlerClass, "postEventFromNative",
2452 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
2453 gEventHandlerFields.mJniCallback = GetFieldIDOrDie(env,
2454 eventHandlerClass, "mJniCallback", "J");
Eric Laurent700e7342014-05-02 18:33:15 -07002455
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002456 gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative =
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002457 GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
2458 "dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V");
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002459 gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative =
2460 GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
Mikhail Naganova00883d2019-04-18 12:36:27 -07002461 "recordingCallbackFromNative", "(IIIIIIZ[I[Landroid/media/audiofx/AudioEffect$Descriptor;[Landroid/media/audiofx/AudioEffect$Descriptor;I)V");
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002462
Eric Laurent09378972014-12-10 10:42:08 -08002463 jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix");
2464 gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass);
2465 gAudioMixFields.mRule = GetFieldIDOrDie(env, audioMixClass, "mRule",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002466 "Landroid/media/audiopolicy/AudioMixingRule;");
Eric Laurent09378972014-12-10 10:42:08 -08002467 gAudioMixFields.mFormat = GetFieldIDOrDie(env, audioMixClass, "mFormat",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002468 "Landroid/media/AudioFormat;");
Eric Laurent09378972014-12-10 10:42:08 -08002469 gAudioMixFields.mRouteFlags = GetFieldIDOrDie(env, audioMixClass, "mRouteFlags", "I");
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07002470 gAudioMixFields.mDeviceType = GetFieldIDOrDie(env, audioMixClass, "mDeviceSystemType", "I");
2471 gAudioMixFields.mDeviceAddress = GetFieldIDOrDie(env, audioMixClass, "mDeviceAddress",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002472 "Ljava/lang/String;");
Eric Laurent09378972014-12-10 10:42:08 -08002473 gAudioMixFields.mMixType = GetFieldIDOrDie(env, audioMixClass, "mMixType", "I");
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002474 gAudioMixFields.mCallbackFlags = GetFieldIDOrDie(env, audioMixClass, "mCallbackFlags", "I");
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002475
Eric Laurent09378972014-12-10 10:42:08 -08002476 jclass audioFormatClass = FindClassOrDie(env, "android/media/AudioFormat");
2477 gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass);
2478 gAudioFormatFields.mEncoding = GetFieldIDOrDie(env, audioFormatClass, "mEncoding", "I");
2479 gAudioFormatFields.mSampleRate = GetFieldIDOrDie(env, audioFormatClass, "mSampleRate", "I");
2480 gAudioFormatFields.mChannelMask = GetFieldIDOrDie(env, audioFormatClass, "mChannelMask", "I");
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002481
Eric Laurent09378972014-12-10 10:42:08 -08002482 jclass audioMixingRuleClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule");
2483 gAudioMixingRuleClass = MakeGlobalRefOrDie(env, audioMixingRuleClass);
2484 gAudioMixingRuleFields.mCriteria = GetFieldIDOrDie(env, audioMixingRuleClass, "mCriteria",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002485 "Ljava/util/ArrayList;");
Kevin Rocarda3a4bbb2019-03-07 18:29:48 -08002486 gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture =
2487 GetFieldIDOrDie(env, audioMixingRuleClass, "mAllowPrivilegedPlaybackCapture", "Z");
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002488
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08002489 jclass audioMixMatchCriterionClass =
2490 FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion");
2491 gAudioMixMatchCriterionClass = MakeGlobalRefOrDie(env,audioMixMatchCriterionClass);
2492 gAudioMixMatchCriterionFields.mAttr = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mAttr",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002493 "Landroid/media/AudioAttributes;");
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08002494 gAudioMixMatchCriterionFields.mIntProp = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mIntProp",
2495 "I");
2496 gAudioMixMatchCriterionFields.mRule = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mRule",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002497 "I");
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002498 // AudioTrackRoutingProxy methods
2499 gClsAudioTrackRoutingProxy =
2500 android::FindClassOrDie(env, "android/media/AudioTrackRoutingProxy");
2501 // make sure this reference doesn't get deleted
2502 gClsAudioTrackRoutingProxy = (jclass)env->NewGlobalRef(gClsAudioTrackRoutingProxy);
2503
2504 gMidAudioTrackRoutingProxy_ctor =
2505 android::GetMethodIDOrDie(env, gClsAudioTrackRoutingProxy, "<init>", "(J)V");
2506 gMidAudioTrackRoutingProxy_release =
2507 android::GetMethodIDOrDie(env, gClsAudioTrackRoutingProxy, "native_release", "()V");
2508
2509 // AudioRecordRoutingProxy
2510 gClsAudioRecordRoutingProxy =
2511 android::FindClassOrDie(env, "android/media/AudioRecordRoutingProxy");
2512 // make sure this reference doesn't get deleted
2513 gClsAudioRecordRoutingProxy = (jclass)env->NewGlobalRef(gClsAudioRecordRoutingProxy);
2514
2515 gMidAudioRecordRoutingProxy_ctor =
2516 android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "<init>", "(J)V");
2517 gMidAudioRecordRoutingProxy_release =
2518 android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "native_release", "()V");
2519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002520 AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
Glenn Kasten18db49a2012-03-12 16:29:55 -07002521
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002522 RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
2523 return RegisterMethodsOrDie(env, kEventHandlerClassPathName, gEventHandlerMethods,
2524 NELEM(gEventHandlerMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002525}