blob: 1a90ebfee999edd433c37fd0120ab44d3098df1e [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
29#include <media/AudioSystem.h>
Eric Laurent7f5eb9f2014-12-01 19:36:30 -080030#include <media/AudioPolicy.h>
jiabinc0f49442018-01-05 10:23:50 -080031#include <media/MicrophoneInfo.h>
Andy Hung737d9fb2016-08-16 18:38:49 -070032#include <nativehelper/ScopedLocalRef.h>
Dima Zavin34bb4192011-05-11 14:15:23 -070033#include <system/audio.h>
Dima Zavin290029d2011-06-13 18:16:26 -070034#include <system/audio_policy.h>
Eric Laurentc7a0cdf2018-11-30 12:16:52 -080035#include "android_media_AudioEffectDescriptor.h"
Eric Laurentb69681c2014-05-19 19:02:51 -070036#include "android_media_AudioFormat.h"
37#include "android_media_AudioErrors.h"
jiabinc0f49442018-01-05 10:23:50 -080038#include "android_media_MicrophoneInfo.h"
François Gaffieb4691282018-07-09 13:07:32 +020039#include "android_media_AudioAttributes.h"
Dima Zavin24fc2fb2011-04-19 22:30:36 -070040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041// ----------------------------------------------------------------------------
42
43using namespace android;
44
Glenn Kastened0079d2011-04-04 10:50:50 -070045static const char* const kClassPathName = "android/media/AudioSystem";
46
Eric Laurentb69681c2014-05-19 19:02:51 -070047static jclass gArrayListClass;
48static struct {
49 jmethodID add;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -080050 jmethodID toArray;
Eric Laurentb69681c2014-05-19 19:02:51 -070051} gArrayListMethods;
52
jiabin39940752018-04-02 18:18:45 -070053static jclass gBooleanClass;
54static jmethodID gBooleanCstor;
55
56static jclass gIntegerClass;
57static jmethodID gIntegerCstor;
58
59static jclass gMapClass;
60static jmethodID gMapPut;
61
Eric Laurentb69681c2014-05-19 19:02:51 -070062static jclass gAudioHandleClass;
63static jmethodID gAudioHandleCstor;
64static struct {
65 jfieldID mId;
66} gAudioHandleFields;
67
68static jclass gAudioPortClass;
69static jmethodID gAudioPortCstor;
70static struct {
71 jfieldID mHandle;
72 jfieldID mRole;
73 jfieldID mGains;
74 jfieldID mActiveConfig;
Hongwei Wangf44a5682018-08-24 10:37:56 -070075 // Valid only if an AudioDevicePort
76 jfieldID mType;
77 jfieldID mAddress;
Eric Laurentb69681c2014-05-19 19:02:51 -070078 // other fields unused by JNI
79} gAudioPortFields;
80
81static jclass gAudioPortConfigClass;
82static jmethodID gAudioPortConfigCstor;
83static struct {
84 jfieldID mPort;
85 jfieldID mSamplingRate;
86 jfieldID mChannelMask;
87 jfieldID mFormat;
88 jfieldID mGain;
Eric Laurent3a241992014-05-19 19:33:26 -070089 jfieldID mConfigMask;
Eric Laurentb69681c2014-05-19 19:02:51 -070090} gAudioPortConfigFields;
91
92static jclass gAudioDevicePortClass;
93static jmethodID gAudioDevicePortCstor;
94
95static jclass gAudioDevicePortConfigClass;
96static jmethodID gAudioDevicePortConfigCstor;
97
98static jclass gAudioMixPortClass;
99static jmethodID gAudioMixPortCstor;
100
101static jclass gAudioMixPortConfigClass;
102static jmethodID gAudioMixPortConfigCstor;
103
104static jclass gAudioGainClass;
105static jmethodID gAudioGainCstor;
106
107static jclass gAudioGainConfigClass;
108static jmethodID gAudioGainConfigCstor;
109static struct {
110 jfieldID mIndex;
111 jfieldID mMode;
112 jfieldID mChannelMask;
113 jfieldID mValues;
114 jfieldID mRampDurationMs;
115 // other fields unused by JNI
116} gAudioGainConfigFields;
117
118static jclass gAudioPatchClass;
119static jmethodID gAudioPatchCstor;
120static struct {
121 jfieldID mHandle;
122 // other fields unused by JNI
123} gAudioPatchFields;
124
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800125static jclass gAudioMixClass;
126static struct {
127 jfieldID mRule;
128 jfieldID mFormat;
129 jfieldID mRouteFlags;
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -0700130 jfieldID mDeviceType;
131 jfieldID mDeviceAddress;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800132 jfieldID mMixType;
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700133 jfieldID mCallbackFlags;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800134} gAudioMixFields;
135
136static jclass gAudioFormatClass;
137static struct {
138 jfieldID mEncoding;
139 jfieldID mSampleRate;
140 jfieldID mChannelMask;
141 // other fields unused by JNI
142} gAudioFormatFields;
143
144static jclass gAudioMixingRuleClass;
145static struct {
146 jfieldID mCriteria;
147 // other fields unused by JNI
148} gAudioMixingRuleFields;
149
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800150static jclass gAudioMixMatchCriterionClass;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800151static struct {
152 jfieldID mAttr;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800153 jfieldID mIntProp;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800154 jfieldID mRule;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800155} gAudioMixMatchCriterionFields;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800156
Eric Laurent700e7342014-05-02 18:33:15 -0700157static const char* const kEventHandlerClassPathName =
158 "android/media/AudioPortEventHandler";
Eric Laurent2615afb2015-03-25 14:51:08 -0700159static struct {
160 jfieldID mJniCallback;
161} gEventHandlerFields;
162static struct {
163 jmethodID postEventFromNative;
164} gAudioPortEventHandlerMethods;
165
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700166static struct {
167 jmethodID postDynPolicyEventFromNative;
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800168 jmethodID postRecordConfigEventFromNative;
169} gAudioPolicyEventHandlerMethods;
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700170
Paul McLeanb3ae6d92018-11-05 15:16:59 -0700171//
172// JNI Initialization for OpenSLES routing
173//
174jmethodID gMidAudioTrackRoutingProxy_ctor;
175jmethodID gMidAudioTrackRoutingProxy_release;
176jmethodID gMidAudioRecordRoutingProxy_ctor;
177jmethodID gMidAudioRecordRoutingProxy_release;
178
179jclass gClsAudioTrackRoutingProxy;
180jclass gClsAudioRecordRoutingProxy;
181
Eric Laurent2615afb2015-03-25 14:51:08 -0700182static Mutex gLock;
Eric Laurentb69681c2014-05-19 19:02:51 -0700183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184enum AudioError {
185 kAudioStatusOk = 0,
186 kAudioStatusError = 1,
187 kAudioStatusMediaServerDied = 100
188};
189
Eric Laurent700e7342014-05-02 18:33:15 -0700190enum {
191 AUDIOPORT_EVENT_PORT_LIST_UPDATED = 1,
192 AUDIOPORT_EVENT_PATCH_LIST_UPDATED = 2,
193 AUDIOPORT_EVENT_SERVICE_DIED = 3,
194};
195
Eric Laurentb69681c2014-05-19 19:02:51 -0700196#define MAX_PORT_GENERATION_SYNC_ATTEMPTS 5
197
Eric Laurent700e7342014-05-02 18:33:15 -0700198// ----------------------------------------------------------------------------
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700199// ref-counted object for audio port callbacks
Eric Laurent700e7342014-05-02 18:33:15 -0700200class JNIAudioPortCallback: public AudioSystem::AudioPortCallback
201{
202public:
203 JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
204 ~JNIAudioPortCallback();
205
206 virtual void onAudioPortListUpdate();
207 virtual void onAudioPatchListUpdate();
208 virtual void onServiceDied();
209
210private:
211 void sendEvent(int event);
212
Eric Laurent2615afb2015-03-25 14:51:08 -0700213 jclass mClass; // Reference to AudioPortEventHandler class
214 jobject mObject; // Weak ref to AudioPortEventHandler Java object to call on
Eric Laurent700e7342014-05-02 18:33:15 -0700215};
216
217JNIAudioPortCallback::JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
218{
219
Eric Laurent2615afb2015-03-25 14:51:08 -0700220 // Hold onto the AudioPortEventHandler class for use in calling the static method
Eric Laurent700e7342014-05-02 18:33:15 -0700221 // that posts events to the application thread.
222 jclass clazz = env->GetObjectClass(thiz);
223 if (clazz == NULL) {
224 ALOGE("Can't find class %s", kEventHandlerClassPathName);
225 return;
226 }
227 mClass = (jclass)env->NewGlobalRef(clazz);
228
Eric Laurent2615afb2015-03-25 14:51:08 -0700229 // We use a weak reference so the AudioPortEventHandler object can be garbage collected.
Eric Laurent700e7342014-05-02 18:33:15 -0700230 // The reference is only used as a proxy for callbacks.
231 mObject = env->NewGlobalRef(weak_thiz);
232}
233
234JNIAudioPortCallback::~JNIAudioPortCallback()
235{
236 // remove global references
237 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent449c5882014-11-12 11:07:48 -0800238 if (env == NULL) {
239 return;
240 }
Eric Laurent700e7342014-05-02 18:33:15 -0700241 env->DeleteGlobalRef(mObject);
242 env->DeleteGlobalRef(mClass);
243}
244
245void JNIAudioPortCallback::sendEvent(int event)
246{
247 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent449c5882014-11-12 11:07:48 -0800248 if (env == NULL) {
249 return;
250 }
Eric Laurent2615afb2015-03-25 14:51:08 -0700251 env->CallStaticVoidMethod(mClass, gAudioPortEventHandlerMethods.postEventFromNative, mObject,
Eric Laurent700e7342014-05-02 18:33:15 -0700252 event, 0, 0, NULL);
253 if (env->ExceptionCheck()) {
254 ALOGW("An exception occurred while notifying an event.");
255 env->ExceptionClear();
256 }
257}
258
259void JNIAudioPortCallback::onAudioPortListUpdate()
260{
261 sendEvent(AUDIOPORT_EVENT_PORT_LIST_UPDATED);
262}
263
264void JNIAudioPortCallback::onAudioPatchListUpdate()
265{
266 sendEvent(AUDIOPORT_EVENT_PATCH_LIST_UPDATED);
267}
268
269void JNIAudioPortCallback::onServiceDied()
270{
271 sendEvent(AUDIOPORT_EVENT_SERVICE_DIED);
272}
273
Eric Laurent2615afb2015-03-25 14:51:08 -0700274static sp<JNIAudioPortCallback> setJniCallback(JNIEnv* env,
275 jobject thiz,
276 const sp<JNIAudioPortCallback>& callback)
277{
278 Mutex::Autolock l(gLock);
279 sp<JNIAudioPortCallback> old =
280 (JNIAudioPortCallback*)env->GetLongField(thiz, gEventHandlerFields.mJniCallback);
281 if (callback.get()) {
282 callback->incStrong((void*)setJniCallback);
283 }
284 if (old != 0) {
285 old->decStrong((void*)setJniCallback);
286 }
287 env->SetLongField(thiz, gEventHandlerFields.mJniCallback, (jlong)callback.get());
288 return old;
289}
290
Mikhail Naganov5caa57d2018-04-02 10:35:45 -0700291#define check_AudioSystem_Command(status) _check_AudioSystem_Command(__func__, (status))
292
293static int _check_AudioSystem_Command(const char* caller, status_t status)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294{
Mikhail Naganov5caa57d2018-04-02 10:35:45 -0700295 ALOGE_IF(status, "Command failed for %s: %d", caller, status);
Eric Laurentdfb881f2013-07-18 14:41:39 -0700296 switch (status) {
297 case DEAD_OBJECT:
298 return kAudioStatusMediaServerDied;
299 case NO_ERROR:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 return kAudioStatusOk;
Eric Laurentdfb881f2013-07-18 14:41:39 -0700301 default:
302 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 }
Eric Laurentdfb881f2013-07-18 14:41:39 -0700304 return kAudioStatusError;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305}
306
Ashok Bhat075e9a12014-01-06 13:45:09 +0000307static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
309{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000310 return (jint) check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311}
312
313static jboolean
314android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
315{
316 bool state = false;
317 AudioSystem::isMicrophoneMuted(&state);
318 return state;
319}
320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321static jboolean
Eric Laurent25101b02011-02-02 09:33:30 -0800322android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323{
324 bool state = false;
Glenn Kastenbc1d77b2012-01-12 16:38:12 -0800325 AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 return state;
327}
328
Jean-Michel Trivid6770542012-10-10 12:03:41 -0700329static jboolean
Jean-Michel Trivi679d5042013-02-04 16:24:09 -0800330android_media_AudioSystem_isStreamActiveRemotely(JNIEnv *env, jobject thiz, jint stream,
331 jint inPastMs)
332{
333 bool state = false;
334 AudioSystem::isStreamActiveRemotely((audio_stream_type_t) stream, &state, inPastMs);
335 return state;
336}
337
338static jboolean
Jean-Michel Trivid6770542012-10-10 12:03:41 -0700339android_media_AudioSystem_isSourceActive(JNIEnv *env, jobject thiz, jint source)
340{
341 bool state = false;
342 AudioSystem::isSourceActive((audio_source_t) source, &state);
343 return state;
344}
345
Ashok Bhat075e9a12014-01-06 13:45:09 +0000346static jint
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -0700347android_media_AudioSystem_newAudioSessionId(JNIEnv *env, jobject thiz)
348{
Glenn Kasten211d9052016-02-26 16:22:40 -0800349 return AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -0700350}
351
352static jint
Jean-Michel Trivi292a6a42016-12-01 08:32:15 -0800353android_media_AudioSystem_newAudioPlayerId(JNIEnv *env, jobject thiz)
354{
355 return AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_PLAYER);
356}
357
358static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700359android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360{
Eric Laurenta553c252009-07-17 12:17:14 -0700361 const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
362 String8 c_keyValuePairs8;
363 if (keyValuePairs) {
Dan Albert66987492014-11-20 11:41:21 -0800364 c_keyValuePairs8 = String8(
365 reinterpret_cast<const char16_t*>(c_keyValuePairs),
366 env->GetStringLength(keyValuePairs));
Eric Laurenta553c252009-07-17 12:17:14 -0700367 env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
368 }
Glenn Kastenc94752a2013-12-19 12:40:33 -0800369 int status = check_AudioSystem_Command(AudioSystem::setParameters(c_keyValuePairs8));
Ashok Bhat075e9a12014-01-06 13:45:09 +0000370 return (jint) status;
Eric Laurenta553c252009-07-17 12:17:14 -0700371}
372
373static jstring
374android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
375{
376 const jchar* c_keys = env->GetStringCritical(keys, 0);
377 String8 c_keys8;
378 if (keys) {
Dan Albert66987492014-11-20 11:41:21 -0800379 c_keys8 = String8(reinterpret_cast<const char16_t*>(c_keys),
380 env->GetStringLength(keys));
Eric Laurenta553c252009-07-17 12:17:14 -0700381 env->ReleaseStringCritical(keys, c_keys);
382 }
Glenn Kastenc94752a2013-12-19 12:40:33 -0800383 return env->NewStringUTF(AudioSystem::getParameters(c_keys8).string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384}
385
Glenn Kastened0079d2011-04-04 10:50:50 -0700386static void
387android_media_AudioSystem_error_callback(status_t err)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388{
Eric Laurent539719a2013-07-18 14:08:00 -0700389 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent0e7a4d92010-10-15 12:33:16 -0700390 if (env == NULL) {
391 return;
392 }
393
Glenn Kastened0079d2011-04-04 10:50:50 -0700394 jclass clazz = env->FindClass(kClassPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395
Eric Laurentdfb881f2013-07-18 14:41:39 -0700396 env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz,
397 "errorCallbackFromNative","(I)V"),
398 check_AudioSystem_Command(err));
Viorel Sumanb637ccf2014-05-30 16:51:07 +0300399
400 env->DeleteLocalRef(clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401}
402
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700403static void
404android_media_AudioSystem_dyn_policy_callback(int event, String8 regId, int val)
405{
406 JNIEnv *env = AndroidRuntime::getJNIEnv();
407 if (env == NULL) {
408 return;
409 }
410
411 jclass clazz = env->FindClass(kClassPathName);
412 const char* zechars = regId.string();
413 jstring zestring = env->NewStringUTF(zechars);
414
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800415 env->CallStaticVoidMethod(clazz, gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative,
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700416 event, zestring, val);
417
418 env->ReleaseStringUTFChars(zestring, zechars);
419 env->DeleteLocalRef(clazz);
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800420}
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700421
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800422static void
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800423android_media_AudioSystem_recording_callback(int event,
424 const record_client_info_t *clientInfo,
425 const audio_config_base_t *clientConfig,
426 std::vector<effect_descriptor_t> clientEffects,
427 const audio_config_base_t *deviceConfig,
428 std::vector<effect_descriptor_t> effects __unused,
429 audio_patch_handle_t patchHandle,
430 audio_source_t source)
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800431{
432 JNIEnv *env = AndroidRuntime::getJNIEnv();
433 if (env == NULL) {
434 return;
435 }
Jean-Michel Trivi66ffacf2017-02-04 17:25:31 -0800436 if (clientInfo == NULL || clientConfig == NULL || deviceConfig == NULL) {
437 ALOGE("Unexpected null client/device info or configurations in recording callback");
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800438 return;
439 }
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800440
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800441 // create an array for 2*3 integers to store the record configurations (client + device)
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800442 // plus 1 integer for the patch handle
443 const int REC_PARAM_SIZE = 7;
444 jintArray recParamArray = env->NewIntArray(REC_PARAM_SIZE);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800445 if (recParamArray == NULL) {
446 ALOGE("recording callback: Couldn't allocate int array for configuration data");
447 return;
448 }
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800449 jint recParamData[REC_PARAM_SIZE];
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800450 recParamData[0] = (jint) audioFormatFromNative(clientConfig->format);
451 // FIXME this doesn't support index-based masks
452 recParamData[1] = (jint) inChannelMaskFromNative(clientConfig->channel_mask);
453 recParamData[2] = (jint) clientConfig->sample_rate;
454 recParamData[3] = (jint) audioFormatFromNative(deviceConfig->format);
455 // FIXME this doesn't support index-based masks
456 recParamData[4] = (jint) inChannelMaskFromNative(deviceConfig->channel_mask);
457 recParamData[5] = (jint) deviceConfig->sample_rate;
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800458 recParamData[6] = (jint) patchHandle;
459 env->SetIntArrayRegion(recParamArray, 0, REC_PARAM_SIZE, recParamData);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800460
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800461 jobjectArray jClientEffects;
462 convertAudioEffectDescriptorVectorFromNative(env, &jClientEffects, clientEffects);
463
464 jobjectArray jEffects;
465 convertAudioEffectDescriptorVectorFromNative(env, &jEffects, effects);
466
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800467 // callback into java
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800468 jclass clazz = env->FindClass(kClassPathName);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800469
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800470 env->CallStaticVoidMethod(clazz,
471 gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative,
472 event, (jint) clientInfo->uid, clientInfo->session,
473 clientInfo->source, clientInfo->port_id, clientInfo->silenced,
474 recParamArray, jClientEffects, jEffects, source);
475 env->DeleteLocalRef(clazz);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800476 env->DeleteLocalRef(recParamArray);
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800477 env->DeleteLocalRef(jClientEffects);
478 env->DeleteLocalRef(jEffects);
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700479}
480
Ashok Bhat075e9a12014-01-06 13:45:09 +0000481static jint
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -0800482android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name,
Eric Laurent1d43aec2019-01-16 18:24:08 -0800483 jint codec)
Eric Laurenta553c252009-07-17 12:17:14 -0700484{
485 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Paul McLean10804eb2015-01-28 11:16:35 -0800486 const char *c_name = env->GetStringUTFChars(device_name, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700487 int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
488 static_cast <audio_policy_dev_state_t>(state),
Eric Laurent1d43aec2019-01-16 18:24:08 -0800489 c_address, c_name,
490 static_cast <audio_format_t>(codec)));
Eric Laurenta553c252009-07-17 12:17:14 -0700491 env->ReleaseStringUTFChars(device_address, c_address);
Paul McLean10804eb2015-01-28 11:16:35 -0800492 env->ReleaseStringUTFChars(device_name, c_name);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000493 return (jint) status;
Eric Laurenta553c252009-07-17 12:17:14 -0700494}
495
Ashok Bhat075e9a12014-01-06 13:45:09 +0000496static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700497android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
498{
499 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700500 int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
Eric Laurenta553c252009-07-17 12:17:14 -0700501 c_address));
502 env->ReleaseStringUTFChars(device_address, c_address);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000503 return (jint) state;
Eric Laurenta553c252009-07-17 12:17:14 -0700504}
505
Ashok Bhat075e9a12014-01-06 13:45:09 +0000506static jint
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -0800507android_media_AudioSystem_handleDeviceConfigChange(JNIEnv *env, jobject thiz, jint device, jstring device_address, jstring device_name,
Eric Laurent1d43aec2019-01-16 18:24:08 -0800508 jint codec)
Pavlin Radoslavov44a4ef02016-12-21 12:05:51 -0800509{
510 const char *c_address = env->GetStringUTFChars(device_address, NULL);
511 const char *c_name = env->GetStringUTFChars(device_name, NULL);
512 int status = check_AudioSystem_Command(AudioSystem::handleDeviceConfigChange(static_cast <audio_devices_t>(device),
Eric Laurent1d43aec2019-01-16 18:24:08 -0800513 c_address, c_name, static_cast <audio_format_t>(codec)));
Pavlin Radoslavov44a4ef02016-12-21 12:05:51 -0800514 env->ReleaseStringUTFChars(device_address, c_address);
515 env->ReleaseStringUTFChars(device_name, c_name);
516 return (jint) status;
517}
518
519static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700520android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
521{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000522 return (jint) check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state));
Eric Laurenta553c252009-07-17 12:17:14 -0700523}
524
Ashok Bhat075e9a12014-01-06 13:45:09 +0000525static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700526android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
527{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000528 return (jint) check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700529 static_cast <audio_policy_forced_cfg_t>(config)));
Eric Laurenta553c252009-07-17 12:17:14 -0700530}
531
Ashok Bhat075e9a12014-01-06 13:45:09 +0000532static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700533android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
534{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000535 return static_cast <jint>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
Eric Laurenta553c252009-07-17 12:17:14 -0700536}
537
Ashok Bhat075e9a12014-01-06 13:45:09 +0000538static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700539android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
540{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000541 return (jint) check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
Eric Laurenta553c252009-07-17 12:17:14 -0700542 indexMin,
543 indexMax));
544}
545
Ashok Bhat075e9a12014-01-06 13:45:09 +0000546static jint
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800547android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
548 jobject thiz,
549 jint stream,
550 jint index,
551 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700552{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000553 return (jint) check_AudioSystem_Command(
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800554 AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
555 index,
556 (audio_devices_t)device));
Eric Laurenta553c252009-07-17 12:17:14 -0700557}
558
Ashok Bhat075e9a12014-01-06 13:45:09 +0000559static jint
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800560android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env,
561 jobject thiz,
562 jint stream,
563 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700564{
565 int index;
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800566 if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
567 &index,
568 (audio_devices_t)device)
569 != NO_ERROR) {
Eric Laurenta553c252009-07-17 12:17:14 -0700570 index = -1;
571 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000572 return (jint) index;
Eric Laurenta553c252009-07-17 12:17:14 -0700573}
574
Ashok Bhat075e9a12014-01-06 13:45:09 +0000575static jint
François Gaffieebb67d02018-09-14 15:05:04 +0200576android_media_AudioSystem_setVolumeIndexForAttributes(JNIEnv *env,
577 jobject thiz,
578 jobject jaa,
579 jint index,
580 jint device)
581{
582 // read the AudioAttributes values
583 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
584 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
585 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
586 return jStatus;
587 }
588 return (jint) check_AudioSystem_Command(
589 AudioSystem::setVolumeIndexForAttributes(*(paa.get()), index, (audio_devices_t)device));
590}
591
592static jint
593android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env,
594 jobject thiz,
595 jobject jaa,
596 jint device)
597{
598 // read the AudioAttributes values
599 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
600 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
601 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
602 return jStatus;
603 }
604 int index;
605 if (AudioSystem::getVolumeIndexForAttributes(*(paa.get()), index, (audio_devices_t)device)
606 != NO_ERROR) {
607 index = -1;
608 }
609 return (jint) index;
610}
611
612static jint
613android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env,
614 jobject thiz,
615 jobject jaa)
616{
617 // read the AudioAttributes values
618 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
619 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
620 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
621 return jStatus;
622 }
623 int index;
624 if (AudioSystem::getMinVolumeIndexForAttributes(*(paa.get()), index)
625 != NO_ERROR) {
626 index = -1;
627 }
628 return (jint) index;
629}
630
631static jint
632android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env,
633 jobject thiz,
634 jobject jaa)
635{
636 // read the AudioAttributes values
637 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
638 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
639 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
640 return jStatus;
641 }
642 int index;
643 if (AudioSystem::getMaxVolumeIndexForAttributes(*(paa.get()), index)
644 != NO_ERROR) {
645 index = -1;
646 }
647 return (jint) index;
648}
649
650static jint
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400651android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
652{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000653 return (jint) check_AudioSystem_Command(AudioSystem::setMasterVolume(value));
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400654}
655
656static jfloat
657android_media_AudioSystem_getMasterVolume(JNIEnv *env, jobject thiz)
658{
659 float value;
660 if (AudioSystem::getMasterVolume(&value) != NO_ERROR) {
661 value = -1.0;
662 }
663 return value;
664}
665
Ashok Bhat075e9a12014-01-06 13:45:09 +0000666static jint
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400667android_media_AudioSystem_setMasterMute(JNIEnv *env, jobject thiz, jboolean mute)
668{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000669 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMute(mute));
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400670}
671
Vladimir Markoc1bcdbb2014-10-29 20:34:15 +0000672static jboolean
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400673android_media_AudioSystem_getMasterMute(JNIEnv *env, jobject thiz)
674{
675 bool mute;
676 if (AudioSystem::getMasterMute(&mute) != NO_ERROR) {
677 mute = false;
678 }
679 return mute;
680}
681
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800682static jint
Andy Hungf04b84d2015-12-18 17:33:27 -0800683android_media_AudioSystem_setMasterMono(JNIEnv *env, jobject thiz, jboolean mono)
684{
685 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMono(mono));
686}
687
688static jboolean
689android_media_AudioSystem_getMasterMono(JNIEnv *env, jobject thiz)
690{
691 bool mono;
692 if (AudioSystem::getMasterMono(&mono) != NO_ERROR) {
693 mono = false;
694 }
695 return mono;
696}
697
698static jint
Edward Savage-Jones35c292f2017-01-13 09:04:34 +0100699android_media_AudioSystem_setMasterBalance(JNIEnv *env, jobject thiz, jfloat balance)
700{
701 return (jint) check_AudioSystem_Command(AudioSystem::setMasterBalance(balance));
702}
703
704static jfloat
705android_media_AudioSystem_getMasterBalance(JNIEnv *env, jobject thiz)
706{
707 float balance;
708 const status_t status = AudioSystem::getMasterBalance(&balance);
709 if (status != NO_ERROR) {
710 ALOGW("%s getMasterBalance error %d, returning 0.f, audioserver down?", __func__, status);
711 balance = 0.f;
712 }
713 return balance;
714}
715
716static jint
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800717android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
718{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700719 return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800720}
721
Glenn Kastenc6c43652012-09-24 17:32:30 -0700722static jint
723android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz)
724{
725 return (jint) AudioSystem::getPrimaryOutputSamplingRate();
726}
727
728static jint
729android_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv *env, jobject clazz)
730{
731 return (jint) AudioSystem::getPrimaryOutputFrameCount();
732}
733
Oliver Woodman61dcdf32013-06-26 12:43:36 +0100734static jint
735android_media_AudioSystem_getOutputLatency(JNIEnv *env, jobject clazz, jint stream)
736{
737 uint32_t afLatency;
738 if (AudioSystem::getOutputLatency(&afLatency, static_cast <audio_stream_type_t>(stream))
739 != NO_ERROR) {
740 afLatency = -1;
741 }
742 return (jint) afLatency;
743}
744
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700745static jint
Andy Hung79583582018-01-23 13:58:02 -0800746android_media_AudioSystem_setLowRamDevice(
747 JNIEnv *env, jobject clazz, jboolean isLowRamDevice, jlong totalMemory)
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700748{
Andy Hung79583582018-01-23 13:58:02 -0800749 return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice, (int64_t) totalMemory);
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700750}
751
Ashok Bhat075e9a12014-01-06 13:45:09 +0000752static jint
Eric Laurentdfb881f2013-07-18 14:41:39 -0700753android_media_AudioSystem_checkAudioFlinger(JNIEnv *env, jobject clazz)
754{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000755 return (jint) check_AudioSystem_Command(AudioSystem::checkAudioFlinger());
Eric Laurentdfb881f2013-07-18 14:41:39 -0700756}
757
Eric Laurentb69681c2014-05-19 19:02:51 -0700758
759static bool useInChannelMask(audio_port_type_t type, audio_port_role_t role)
760{
761 return ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) ||
762 ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK));
763}
764
Eric Laurent3a241992014-05-19 19:33:26 -0700765static void convertAudioGainConfigToNative(JNIEnv *env,
766 struct audio_gain_config *nAudioGainConfig,
767 const jobject jAudioGainConfig,
768 bool useInMask)
769{
770 nAudioGainConfig->index = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mIndex);
771 nAudioGainConfig->mode = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mMode);
772 ALOGV("convertAudioGainConfigToNative got gain index %d", nAudioGainConfig->index);
773 jint jMask = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mChannelMask);
774 audio_channel_mask_t nMask;
775 if (useInMask) {
776 nMask = inChannelMaskToNative(jMask);
777 ALOGV("convertAudioGainConfigToNative IN mask java %x native %x", jMask, nMask);
778 } else {
779 nMask = outChannelMaskToNative(jMask);
780 ALOGV("convertAudioGainConfigToNative OUT mask java %x native %x", jMask, nMask);
781 }
782 nAudioGainConfig->channel_mask = nMask;
783 nAudioGainConfig->ramp_duration_ms = env->GetIntField(jAudioGainConfig,
784 gAudioGainConfigFields.mRampDurationMs);
785 jintArray jValues = (jintArray)env->GetObjectField(jAudioGainConfig,
786 gAudioGainConfigFields.mValues);
787 int *nValues = env->GetIntArrayElements(jValues, NULL);
788 size_t size = env->GetArrayLength(jValues);
789 memcpy(nAudioGainConfig->values, nValues, size * sizeof(int));
790 env->DeleteLocalRef(jValues);
791}
792
Eric Laurentb69681c2014-05-19 19:02:51 -0700793static jint convertAudioPortConfigToNative(JNIEnv *env,
794 struct audio_port_config *nAudioPortConfig,
Eric Laurent6368a7d2014-11-19 12:18:32 -0800795 const jobject jAudioPortConfig,
796 bool useConfigMask)
Eric Laurentb69681c2014-05-19 19:02:51 -0700797{
798 jobject jAudioPort = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mPort);
799 jobject jHandle = env->GetObjectField(jAudioPort, gAudioPortFields.mHandle);
800 nAudioPortConfig->id = env->GetIntField(jHandle, gAudioHandleFields.mId);
801 nAudioPortConfig->role = (audio_port_role_t)env->GetIntField(jAudioPort,
802 gAudioPortFields.mRole);
803 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
804 nAudioPortConfig->type = AUDIO_PORT_TYPE_DEVICE;
805 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
806 nAudioPortConfig->type = AUDIO_PORT_TYPE_MIX;
807 } else {
808 env->DeleteLocalRef(jAudioPort);
809 env->DeleteLocalRef(jHandle);
810 return (jint)AUDIO_JAVA_ERROR;
811 }
812 ALOGV("convertAudioPortConfigToNative handle %d role %d type %d",
813 nAudioPortConfig->id, nAudioPortConfig->role, nAudioPortConfig->type);
814
Eric Laurent6368a7d2014-11-19 12:18:32 -0800815 unsigned int configMask = 0;
816
Eric Laurentb69681c2014-05-19 19:02:51 -0700817 nAudioPortConfig->sample_rate = env->GetIntField(jAudioPortConfig,
818 gAudioPortConfigFields.mSamplingRate);
Eric Laurent6368a7d2014-11-19 12:18:32 -0800819 if (nAudioPortConfig->sample_rate != 0) {
820 configMask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
821 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700822
823 bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role);
824 audio_channel_mask_t nMask;
825 jint jMask = env->GetIntField(jAudioPortConfig,
826 gAudioPortConfigFields.mChannelMask);
827 if (useInMask) {
828 nMask = inChannelMaskToNative(jMask);
829 ALOGV("convertAudioPortConfigToNative IN mask java %x native %x", jMask, nMask);
830 } else {
831 nMask = outChannelMaskToNative(jMask);
832 ALOGV("convertAudioPortConfigToNative OUT mask java %x native %x", jMask, nMask);
833 }
834 nAudioPortConfig->channel_mask = nMask;
Eric Laurent6368a7d2014-11-19 12:18:32 -0800835 if (nAudioPortConfig->channel_mask != AUDIO_CHANNEL_NONE) {
836 configMask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
837 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700838
839 jint jFormat = env->GetIntField(jAudioPortConfig, gAudioPortConfigFields.mFormat);
840 audio_format_t nFormat = audioFormatToNative(jFormat);
841 ALOGV("convertAudioPortConfigToNative format %d native %d", jFormat, nFormat);
842 nAudioPortConfig->format = nFormat;
Eric Laurent6368a7d2014-11-19 12:18:32 -0800843 if (nAudioPortConfig->format != AUDIO_FORMAT_DEFAULT &&
844 nAudioPortConfig->format != AUDIO_FORMAT_INVALID) {
845 configMask |= AUDIO_PORT_CONFIG_FORMAT;
846 }
847
Eric Laurentb69681c2014-05-19 19:02:51 -0700848 jobject jGain = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mGain);
849 if (jGain != NULL) {
Eric Laurent3a241992014-05-19 19:33:26 -0700850 convertAudioGainConfigToNative(env, &nAudioPortConfig->gain, jGain, useInMask);
Eric Laurentb69681c2014-05-19 19:02:51 -0700851 env->DeleteLocalRef(jGain);
Eric Laurent6368a7d2014-11-19 12:18:32 -0800852 configMask |= AUDIO_PORT_CONFIG_GAIN;
Eric Laurentb69681c2014-05-19 19:02:51 -0700853 } else {
854 ALOGV("convertAudioPortConfigToNative no gain");
855 nAudioPortConfig->gain.index = -1;
856 }
Eric Laurent6368a7d2014-11-19 12:18:32 -0800857 if (useConfigMask) {
858 nAudioPortConfig->config_mask = env->GetIntField(jAudioPortConfig,
859 gAudioPortConfigFields.mConfigMask);
860 } else {
861 nAudioPortConfig->config_mask = configMask;
862 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700863 env->DeleteLocalRef(jAudioPort);
864 env->DeleteLocalRef(jHandle);
865 return (jint)AUDIO_JAVA_SUCCESS;
866}
867
Hongwei Wangf44a5682018-08-24 10:37:56 -0700868/**
869 * Extends convertAudioPortConfigToNative with extra device port info.
870 * Mix / Session specific info is not fulfilled.
871 */
872static jint convertAudioPortConfigToNativeWithDevicePort(JNIEnv *env,
873 struct audio_port_config *nAudioPortConfig,
874 const jobject jAudioPortConfig,
875 bool useConfigMask)
876{
877 jint jStatus = convertAudioPortConfigToNative(env,
878 nAudioPortConfig,
879 jAudioPortConfig,
880 useConfigMask);
881 if (jStatus != AUDIO_JAVA_SUCCESS) {
882 return jStatus;
883 }
884 // Supports AUDIO_PORT_TYPE_DEVICE only
885 if (nAudioPortConfig->type != AUDIO_PORT_TYPE_DEVICE) {
886 return (jint)AUDIO_JAVA_BAD_VALUE;
887 }
888
889 jobject jAudioDevicePort = env->GetObjectField(jAudioPortConfig,
890 gAudioPortConfigFields.mPort);
891 nAudioPortConfig->ext.device.type = env->GetIntField(jAudioDevicePort,
892 gAudioPortFields.mType);
893 jstring jDeviceAddress = (jstring)env->GetObjectField(jAudioDevicePort,
894 gAudioPortFields.mAddress);
895 const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
896 strncpy(nAudioPortConfig->ext.device.address,
897 nDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN - 1);
898 env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
899 env->DeleteLocalRef(jDeviceAddress);
900 env->DeleteLocalRef(jAudioDevicePort);
901 return jStatus;
902}
903
Eric Laurentb69681c2014-05-19 19:02:51 -0700904static jint convertAudioPortConfigFromNative(JNIEnv *env,
905 jobject jAudioPort,
906 jobject *jAudioPortConfig,
907 const struct audio_port_config *nAudioPortConfig)
908{
909 jint jStatus = AUDIO_JAVA_SUCCESS;
910 jobject jAudioGainConfig = NULL;
911 jobject jAudioGain = NULL;
912 jintArray jGainValues;
913 bool audioportCreated = false;
914
915 ALOGV("convertAudioPortConfigFromNative jAudioPort %p", jAudioPort);
916
917 if (jAudioPort == NULL) {
918 jobject jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
919 nAudioPortConfig->id);
920
921 ALOGV("convertAudioPortConfigFromNative handle %d is a %s", nAudioPortConfig->id,
922 nAudioPortConfig->type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix");
923
924 if (jHandle == NULL) {
925 return (jint)AUDIO_JAVA_ERROR;
926 }
927 // create dummy port and port config objects with just the correct handle
928 // and configuration data. The actual AudioPortConfig objects will be
929 // constructed by java code with correct class type (device, mix etc...)
930 // and reference to AudioPort instance in this client
931 jAudioPort = env->NewObject(gAudioPortClass, gAudioPortCstor,
Paul McLeanf29e5f32015-06-15 10:19:22 -0700932 jHandle, // handle
933 0, // role
934 NULL, // name
935 NULL, // samplingRates
936 NULL, // channelMasks
937 NULL, // channelIndexMasks
938 NULL, // formats
939 NULL); // gains
Eric Laurentb69681c2014-05-19 19:02:51 -0700940 env->DeleteLocalRef(jHandle);
941 if (jAudioPort == NULL) {
942 return (jint)AUDIO_JAVA_ERROR;
943 }
944 ALOGV("convertAudioPortConfigFromNative jAudioPort created for handle %d",
945 nAudioPortConfig->id);
946
947 audioportCreated = true;
948 }
949
950 bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role);
951
952 audio_channel_mask_t nMask;
953 jint jMask;
954
955 int gainIndex = nAudioPortConfig->gain.index;
956 if (gainIndex >= 0) {
957 ALOGV("convertAudioPortConfigFromNative gain found with index %d mode %x",
958 gainIndex, nAudioPortConfig->gain.mode);
959 if (audioportCreated) {
960 ALOGV("convertAudioPortConfigFromNative creating gain");
961 jAudioGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
962 gainIndex,
963 0,
964 0,
965 0,
966 0,
967 0,
968 0,
969 0,
970 0);
971 if (jAudioGain == NULL) {
972 ALOGV("convertAudioPortConfigFromNative creating gain FAILED");
973 jStatus = (jint)AUDIO_JAVA_ERROR;
974 goto exit;
975 }
976 } else {
977 ALOGV("convertAudioPortConfigFromNative reading gain from port");
978 jobjectArray jGains = (jobjectArray)env->GetObjectField(jAudioPort,
979 gAudioPortFields.mGains);
980 if (jGains == NULL) {
981 ALOGV("convertAudioPortConfigFromNative could not get gains from port");
982 jStatus = (jint)AUDIO_JAVA_ERROR;
983 goto exit;
984 }
985 jAudioGain = env->GetObjectArrayElement(jGains, gainIndex);
986 env->DeleteLocalRef(jGains);
987 if (jAudioGain == NULL) {
988 ALOGV("convertAudioPortConfigFromNative could not get gain at index %d", gainIndex);
989 jStatus = (jint)AUDIO_JAVA_ERROR;
990 goto exit;
991 }
992 }
Eric Laurent0078c7c2014-06-04 09:49:52 -0700993 int numValues;
994 if (useInMask) {
995 numValues = audio_channel_count_from_in_mask(nAudioPortConfig->gain.channel_mask);
996 } else {
997 numValues = audio_channel_count_from_out_mask(nAudioPortConfig->gain.channel_mask);
998 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700999 jGainValues = env->NewIntArray(numValues);
1000 if (jGainValues == NULL) {
1001 ALOGV("convertAudioPortConfigFromNative could not create gain values %d", numValues);
1002 jStatus = (jint)AUDIO_JAVA_ERROR;
1003 goto exit;
1004 }
1005 env->SetIntArrayRegion(jGainValues, 0, numValues,
1006 nAudioPortConfig->gain.values);
1007
1008 nMask = nAudioPortConfig->gain.channel_mask;
1009 if (useInMask) {
1010 jMask = inChannelMaskFromNative(nMask);
1011 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1012 } else {
1013 jMask = outChannelMaskFromNative(nMask);
1014 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1015 }
1016
1017 jAudioGainConfig = env->NewObject(gAudioGainConfigClass,
1018 gAudioGainConfigCstor,
1019 gainIndex,
1020 jAudioGain,
1021 nAudioPortConfig->gain.mode,
1022 jMask,
1023 jGainValues,
1024 nAudioPortConfig->gain.ramp_duration_ms);
1025 env->DeleteLocalRef(jGainValues);
1026 if (jAudioGainConfig == NULL) {
1027 ALOGV("convertAudioPortConfigFromNative could not create gain config");
1028 jStatus = (jint)AUDIO_JAVA_ERROR;
1029 goto exit;
1030 }
1031 }
1032 jclass clazz;
1033 jmethodID methodID;
1034 if (audioportCreated) {
1035 clazz = gAudioPortConfigClass;
1036 methodID = gAudioPortConfigCstor;
1037 ALOGV("convertAudioPortConfigFromNative building a generic port config");
1038 } else {
1039 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
1040 clazz = gAudioDevicePortConfigClass;
1041 methodID = gAudioDevicePortConfigCstor;
1042 ALOGV("convertAudioPortConfigFromNative building a device config");
1043 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
1044 clazz = gAudioMixPortConfigClass;
1045 methodID = gAudioMixPortConfigCstor;
1046 ALOGV("convertAudioPortConfigFromNative building a mix config");
1047 } else {
1048 jStatus = (jint)AUDIO_JAVA_ERROR;
1049 goto exit;
1050 }
1051 }
1052 nMask = nAudioPortConfig->channel_mask;
1053 if (useInMask) {
1054 jMask = inChannelMaskFromNative(nMask);
1055 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1056 } else {
1057 jMask = outChannelMaskFromNative(nMask);
1058 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1059 }
1060
1061 *jAudioPortConfig = env->NewObject(clazz, methodID,
1062 jAudioPort,
1063 nAudioPortConfig->sample_rate,
1064 jMask,
1065 audioFormatFromNative(nAudioPortConfig->format),
1066 jAudioGainConfig);
1067 if (*jAudioPortConfig == NULL) {
1068 ALOGV("convertAudioPortConfigFromNative could not create new port config");
1069 jStatus = (jint)AUDIO_JAVA_ERROR;
1070 } else {
1071 ALOGV("convertAudioPortConfigFromNative OK");
1072 }
1073
1074exit:
1075 if (audioportCreated) {
1076 env->DeleteLocalRef(jAudioPort);
1077 if (jAudioGain != NULL) {
1078 env->DeleteLocalRef(jAudioGain);
1079 }
1080 }
1081 if (jAudioGainConfig != NULL) {
1082 env->DeleteLocalRef(jAudioGainConfig);
1083 }
1084 return jStatus;
1085}
1086
Paul McLean4e5e9e92015-06-17 10:10:11 -07001087static bool hasFormat(int* formats, size_t size, int format) {
1088 for (size_t index = 0; index < size; index++) {
1089 if (formats[index] == format) {
1090 return true; // found
1091 }
1092 }
1093 return false; // not found
1094}
1095
Andy Hung737d9fb2016-08-16 18:38:49 -07001096// TODO: pull out to separate file
1097template <typename T, size_t N>
1098static constexpr size_t array_size(const T (&)[N]) {
1099 return N;
1100}
1101
Eric Laurentb69681c2014-05-19 19:02:51 -07001102static jint convertAudioPortFromNative(JNIEnv *env,
1103 jobject *jAudioPort, const struct audio_port *nAudioPort)
1104{
1105 jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
1106 jintArray jSamplingRates = NULL;
1107 jintArray jChannelMasks = NULL;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001108 jintArray jChannelIndexMasks = NULL;
Paul McLean4e5e9e92015-06-17 10:10:11 -07001109 int* cFormats = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001110 jintArray jFormats = NULL;
1111 jobjectArray jGains = NULL;
1112 jobject jHandle = NULL;
xiaomi/hanli82840c42017-07-19 18:53:03 +08001113 jobject jAudioPortConfig = NULL;
Paul McLean10804eb2015-01-28 11:16:35 -08001114 jstring jDeviceName = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001115 bool useInMask;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001116 size_t numPositionMasks = 0;
1117 size_t numIndexMasks = 0;
Paul McLean2db94372015-06-18 12:47:34 -07001118 size_t numUniqueFormats = 0;
1119
Paul McLean10804eb2015-01-28 11:16:35 -08001120 ALOGV("convertAudioPortFromNative id %d role %d type %d name %s",
1121 nAudioPort->id, nAudioPort->role, nAudioPort->type, nAudioPort->name);
Eric Laurentb69681c2014-05-19 19:02:51 -07001122
Andy Hung737d9fb2016-08-16 18:38:49 -07001123 // Verify audio port array count info.
1124 if (nAudioPort->num_sample_rates > array_size(nAudioPort->sample_rates)
1125 || nAudioPort->num_channel_masks > array_size(nAudioPort->channel_masks)
1126 || nAudioPort->num_formats > array_size(nAudioPort->formats)
1127 || nAudioPort->num_gains > array_size(nAudioPort->gains)) {
1128
1129 std::stringstream ss;
1130 ss << "convertAudioPortFromNative array count out of bounds:"
1131 << " num_sample_rates " << nAudioPort->num_sample_rates
1132 << " num_channel_masks " << nAudioPort->num_channel_masks
1133 << " num_formats " << nAudioPort->num_formats
1134 << " num_gains " << nAudioPort->num_gains
1135 ;
1136 std::string s = ss.str();
1137
1138 // Prefer to log through Java wtf instead of native ALOGE.
1139 ScopedLocalRef<jclass> jLogClass(env, env->FindClass("android/util/Log"));
1140 jmethodID jWtfId = (jLogClass.get() == nullptr)
1141 ? nullptr
1142 : env->GetStaticMethodID(jLogClass.get(), "wtf",
1143 "(Ljava/lang/String;Ljava/lang/String;)I");
1144 if (jWtfId != nullptr) {
1145 ScopedLocalRef<jstring> jMessage(env, env->NewStringUTF(s.c_str()));
1146 ScopedLocalRef<jstring> jTag(env, env->NewStringUTF(LOG_TAG));
1147 (void)env->CallStaticIntMethod(jLogClass.get(), jWtfId, jTag.get(), jMessage.get());
1148 } else {
1149 ALOGE("%s", s.c_str());
1150 }
1151 jStatus = (jint)AUDIO_JAVA_ERROR;
1152 goto exit;
1153 }
1154
Eric Laurentb69681c2014-05-19 19:02:51 -07001155 jSamplingRates = env->NewIntArray(nAudioPort->num_sample_rates);
1156 if (jSamplingRates == NULL) {
1157 jStatus = (jint)AUDIO_JAVA_ERROR;
1158 goto exit;
1159 }
1160 if (nAudioPort->num_sample_rates) {
1161 env->SetIntArrayRegion(jSamplingRates, 0, nAudioPort->num_sample_rates,
1162 (jint *)nAudioPort->sample_rates);
1163 }
1164
Paul McLeanf29e5f32015-06-15 10:19:22 -07001165 // count up how many masks are positional and indexed
1166 for(size_t index = 0; index < nAudioPort->num_channel_masks; index++) {
1167 const audio_channel_mask_t mask = nAudioPort->channel_masks[index];
1168 if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1169 numIndexMasks++;
1170 } else {
1171 numPositionMasks++;
1172 }
1173 }
1174
1175 jChannelMasks = env->NewIntArray(numPositionMasks);
Eric Laurentb69681c2014-05-19 19:02:51 -07001176 if (jChannelMasks == NULL) {
1177 jStatus = (jint)AUDIO_JAVA_ERROR;
1178 goto exit;
1179 }
Paul McLeanf29e5f32015-06-15 10:19:22 -07001180 jChannelIndexMasks = env->NewIntArray(numIndexMasks);
1181 if (jChannelIndexMasks == NULL) {
1182 jStatus = (jint)AUDIO_JAVA_ERROR;
1183 goto exit;
1184 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001185 useInMask = useInChannelMask(nAudioPort->type, nAudioPort->role);
1186
Paul McLeanf29e5f32015-06-15 10:19:22 -07001187 // put the masks in the output arrays
1188 for (size_t maskIndex = 0, posMaskIndex = 0, indexedMaskIndex = 0;
1189 maskIndex < nAudioPort->num_channel_masks; maskIndex++) {
1190 const audio_channel_mask_t mask = nAudioPort->channel_masks[maskIndex];
1191 if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1192 jint jMask = audio_channel_mask_get_bits(mask);
1193 env->SetIntArrayRegion(jChannelIndexMasks, indexedMaskIndex++, 1, &jMask);
Eric Laurentb69681c2014-05-19 19:02:51 -07001194 } else {
Paul McLeanf29e5f32015-06-15 10:19:22 -07001195 jint jMask = useInMask ? inChannelMaskFromNative(mask)
1196 : outChannelMaskFromNative(mask);
1197 env->SetIntArrayRegion(jChannelMasks, posMaskIndex++, 1, &jMask);
Eric Laurentb69681c2014-05-19 19:02:51 -07001198 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001199 }
1200
Paul McLeanf29e5f32015-06-15 10:19:22 -07001201 // formats
Paul McLean2db94372015-06-18 12:47:34 -07001202 if (nAudioPort->num_formats != 0) {
1203 cFormats = new int[nAudioPort->num_formats];
1204 for (size_t index = 0; index < nAudioPort->num_formats; index++) {
1205 int format = audioFormatFromNative(nAudioPort->formats[index]);
1206 if (!hasFormat(cFormats, numUniqueFormats, format)) {
1207 cFormats[numUniqueFormats++] = format;
1208 }
Paul McLean4e5e9e92015-06-17 10:10:11 -07001209 }
1210 }
1211 jFormats = env->NewIntArray(numUniqueFormats);
Eric Laurentb69681c2014-05-19 19:02:51 -07001212 if (jFormats == NULL) {
1213 jStatus = (jint)AUDIO_JAVA_ERROR;
1214 goto exit;
1215 }
Paul McLean2db94372015-06-18 12:47:34 -07001216 if (numUniqueFormats != 0) {
1217 env->SetIntArrayRegion(jFormats, 0, numUniqueFormats, cFormats);
1218 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001219
Paul McLeanf29e5f32015-06-15 10:19:22 -07001220 // gains
Eric Laurentb69681c2014-05-19 19:02:51 -07001221 jGains = env->NewObjectArray(nAudioPort->num_gains,
1222 gAudioGainClass, NULL);
1223 if (jGains == NULL) {
1224 jStatus = (jint)AUDIO_JAVA_ERROR;
1225 goto exit;
1226 }
Paul McLeanf29e5f32015-06-15 10:19:22 -07001227
Eric Laurentb69681c2014-05-19 19:02:51 -07001228 for (size_t j = 0; j < nAudioPort->num_gains; j++) {
1229 audio_channel_mask_t nMask = nAudioPort->gains[j].channel_mask;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001230 jint jMask;
Eric Laurentb69681c2014-05-19 19:02:51 -07001231 if (useInMask) {
1232 jMask = inChannelMaskFromNative(nMask);
1233 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1234 } else {
1235 jMask = outChannelMaskFromNative(nMask);
1236 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1237 }
1238
1239 jobject jGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
1240 j,
1241 nAudioPort->gains[j].mode,
1242 jMask,
1243 nAudioPort->gains[j].min_value,
1244 nAudioPort->gains[j].max_value,
1245 nAudioPort->gains[j].default_value,
1246 nAudioPort->gains[j].step_value,
1247 nAudioPort->gains[j].min_ramp_ms,
1248 nAudioPort->gains[j].max_ramp_ms);
1249 if (jGain == NULL) {
1250 jStatus = (jint)AUDIO_JAVA_ERROR;
1251 goto exit;
1252 }
1253 env->SetObjectArrayElement(jGains, j, jGain);
1254 env->DeleteLocalRef(jGain);
1255 }
1256
1257 jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1258 nAudioPort->id);
1259 if (jHandle == NULL) {
1260 jStatus = (jint)AUDIO_JAVA_ERROR;
1261 goto exit;
1262 }
1263
Paul McLean10804eb2015-01-28 11:16:35 -08001264 jDeviceName = env->NewStringUTF(nAudioPort->name);
1265
Eric Laurentb69681c2014-05-19 19:02:51 -07001266 if (nAudioPort->type == AUDIO_PORT_TYPE_DEVICE) {
1267 ALOGV("convertAudioPortFromNative is a device %08x", nAudioPort->ext.device.type);
1268 jstring jAddress = env->NewStringUTF(nAudioPort->ext.device.address);
1269 *jAudioPort = env->NewObject(gAudioDevicePortClass, gAudioDevicePortCstor,
Paul McLean10804eb2015-01-28 11:16:35 -08001270 jHandle, jDeviceName,
Paul McLeanf29e5f32015-06-15 10:19:22 -07001271 jSamplingRates, jChannelMasks, jChannelIndexMasks,
1272 jFormats, jGains,
Eric Laurentb69681c2014-05-19 19:02:51 -07001273 nAudioPort->ext.device.type, jAddress);
1274 env->DeleteLocalRef(jAddress);
1275 } else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) {
1276 ALOGV("convertAudioPortFromNative is a mix");
1277 *jAudioPort = env->NewObject(gAudioMixPortClass, gAudioMixPortCstor,
Eric Laurent4bcdba82015-05-01 11:37:49 -07001278 jHandle, nAudioPort->ext.mix.handle,
1279 nAudioPort->role, jDeviceName,
Paul McLeanf29e5f32015-06-15 10:19:22 -07001280 jSamplingRates, jChannelMasks, jChannelIndexMasks,
Eric Laurentb69681c2014-05-19 19:02:51 -07001281 jFormats, jGains);
1282 } else {
1283 ALOGE("convertAudioPortFromNative unknown nAudioPort type %d", nAudioPort->type);
1284 jStatus = (jint)AUDIO_JAVA_ERROR;
1285 goto exit;
1286 }
1287 if (*jAudioPort == NULL) {
1288 jStatus = (jint)AUDIO_JAVA_ERROR;
1289 goto exit;
1290 }
1291
Eric Laurentb69681c2014-05-19 19:02:51 -07001292 jStatus = convertAudioPortConfigFromNative(env,
1293 *jAudioPort,
1294 &jAudioPortConfig,
1295 &nAudioPort->active_config);
1296 if (jStatus != AUDIO_JAVA_SUCCESS) {
Andy Hung737d9fb2016-08-16 18:38:49 -07001297 goto exit;
Eric Laurentb69681c2014-05-19 19:02:51 -07001298 }
1299
1300 env->SetObjectField(*jAudioPort, gAudioPortFields.mActiveConfig, jAudioPortConfig);
1301
1302exit:
Paul McLean10804eb2015-01-28 11:16:35 -08001303 if (jDeviceName != NULL) {
1304 env->DeleteLocalRef(jDeviceName);
1305 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001306 if (jSamplingRates != NULL) {
1307 env->DeleteLocalRef(jSamplingRates);
1308 }
1309 if (jChannelMasks != NULL) {
1310 env->DeleteLocalRef(jChannelMasks);
1311 }
Paul McLean4e5e9e92015-06-17 10:10:11 -07001312 if (jChannelIndexMasks != NULL) {
1313 env->DeleteLocalRef(jChannelIndexMasks);
1314 }
1315 if (cFormats != NULL) {
1316 delete[] cFormats;
1317 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001318 if (jFormats != NULL) {
1319 env->DeleteLocalRef(jFormats);
1320 }
1321 if (jGains != NULL) {
1322 env->DeleteLocalRef(jGains);
1323 }
1324 if (jHandle != NULL) {
1325 env->DeleteLocalRef(jHandle);
1326 }
xiaomi/hanli82840c42017-07-19 18:53:03 +08001327 if (jAudioPortConfig != NULL) {
1328 env->DeleteLocalRef(jAudioPortConfig);
1329 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001330
1331 return jStatus;
1332}
1333
Eric Laurentb69681c2014-05-19 19:02:51 -07001334static jint
1335android_media_AudioSystem_listAudioPorts(JNIEnv *env, jobject clazz,
1336 jobject jPorts, jintArray jGeneration)
1337{
1338 ALOGV("listAudioPorts");
1339
1340 if (jPorts == NULL) {
1341 ALOGE("listAudioPorts NULL AudioPort ArrayList");
1342 return (jint)AUDIO_JAVA_BAD_VALUE;
1343 }
1344 if (!env->IsInstanceOf(jPorts, gArrayListClass)) {
1345 ALOGE("listAudioPorts not an arraylist");
1346 return (jint)AUDIO_JAVA_BAD_VALUE;
1347 }
1348
1349 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1350 return (jint)AUDIO_JAVA_BAD_VALUE;
1351 }
1352
1353 status_t status;
1354 unsigned int generation1;
1355 unsigned int generation;
1356 unsigned int numPorts;
1357 jint *nGeneration;
1358 struct audio_port *nPorts = NULL;
1359 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
Eric Laurentb36d1042016-04-14 18:00:38 -07001360 jint jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001361
1362 // get the port count and all the ports until they both return the same generation
1363 do {
1364 if (attempts-- < 0) {
1365 status = TIMED_OUT;
1366 break;
1367 }
1368
1369 numPorts = 0;
1370 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE,
1371 AUDIO_PORT_TYPE_NONE,
1372 &numPorts,
1373 NULL,
1374 &generation1);
Eric Laurentb36d1042016-04-14 18:00:38 -07001375 if (status != NO_ERROR) {
Eric Laurentb69681c2014-05-19 19:02:51 -07001376 ALOGE_IF(status != NO_ERROR, "AudioSystem::listAudioPorts error %d", status);
1377 break;
1378 }
Eric Laurentb36d1042016-04-14 18:00:38 -07001379 if (numPorts == 0) {
1380 jStatus = (jint)AUDIO_JAVA_SUCCESS;
1381 goto exit;
1382 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001383 nPorts = (struct audio_port *)realloc(nPorts, numPorts * sizeof(struct audio_port));
1384
1385 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE,
1386 AUDIO_PORT_TYPE_NONE,
1387 &numPorts,
1388 nPorts,
1389 &generation);
1390 ALOGV("listAudioPorts AudioSystem::listAudioPorts numPorts %d generation %d generation1 %d",
1391 numPorts, generation, generation1);
1392 } while (generation1 != generation && status == NO_ERROR);
1393
Eric Laurentb36d1042016-04-14 18:00:38 -07001394 jStatus = nativeToJavaStatus(status);
Eric Laurentb69681c2014-05-19 19:02:51 -07001395 if (jStatus != AUDIO_JAVA_SUCCESS) {
1396 goto exit;
1397 }
1398
Eric Laurentb69681c2014-05-19 19:02:51 -07001399 for (size_t i = 0; i < numPorts; i++) {
xiaomi/hanli82840c42017-07-19 18:53:03 +08001400 jobject jAudioPort = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001401 jStatus = convertAudioPortFromNative(env, &jAudioPort, &nPorts[i]);
1402 if (jStatus != AUDIO_JAVA_SUCCESS) {
1403 goto exit;
1404 }
1405 env->CallBooleanMethod(jPorts, gArrayListMethods.add, jAudioPort);
xiaomi/hanli82840c42017-07-19 18:53:03 +08001406 if (jAudioPort != NULL) {
1407 env->DeleteLocalRef(jAudioPort);
1408 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001409 }
1410
1411exit:
Eric Laurentb36d1042016-04-14 18:00:38 -07001412 nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1413 if (nGeneration == NULL) {
1414 jStatus = (jint)AUDIO_JAVA_ERROR;
1415 } else {
1416 nGeneration[0] = generation1;
1417 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1418 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001419 free(nPorts);
1420 return jStatus;
1421}
1422
1423static int
1424android_media_AudioSystem_createAudioPatch(JNIEnv *env, jobject clazz,
1425 jobjectArray jPatches, jobjectArray jSources, jobjectArray jSinks)
1426{
1427 status_t status;
1428 jint jStatus;
1429
1430 ALOGV("createAudioPatch");
1431 if (jPatches == NULL || jSources == NULL || jSinks == NULL) {
1432 return (jint)AUDIO_JAVA_BAD_VALUE;
1433 }
1434
1435 if (env->GetArrayLength(jPatches) != 1) {
1436 return (jint)AUDIO_JAVA_BAD_VALUE;
1437 }
1438 jint numSources = env->GetArrayLength(jSources);
1439 if (numSources == 0 || numSources > AUDIO_PATCH_PORTS_MAX) {
1440 return (jint)AUDIO_JAVA_BAD_VALUE;
1441 }
1442
1443 jint numSinks = env->GetArrayLength(jSinks);
1444 if (numSinks == 0 || numSinks > AUDIO_PATCH_PORTS_MAX) {
1445 return (jint)AUDIO_JAVA_BAD_VALUE;
1446 }
1447
1448 audio_patch_handle_t handle = (audio_patch_handle_t)0;
1449 jobject jPatch = env->GetObjectArrayElement(jPatches, 0);
1450 jobject jPatchHandle = NULL;
1451 if (jPatch != NULL) {
1452 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1453 return (jint)AUDIO_JAVA_BAD_VALUE;
1454 }
1455 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1456 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1457 }
1458
Mikhail Naganov304eafc2018-05-23 16:54:12 -07001459 struct audio_patch nPatch = { .id = handle };
Eric Laurentb69681c2014-05-19 19:02:51 -07001460
Eric Laurentb69681c2014-05-19 19:02:51 -07001461 jobject jSource = NULL;
1462 jobject jSink = NULL;
1463
1464 for (jint i = 0; i < numSources; i++) {
1465 jSource = env->GetObjectArrayElement(jSources, i);
1466 if (!env->IsInstanceOf(jSource, gAudioPortConfigClass)) {
1467 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1468 goto exit;
1469 }
Eric Laurent6368a7d2014-11-19 12:18:32 -08001470 jStatus = convertAudioPortConfigToNative(env, &nPatch.sources[i], jSource, false);
Eric Laurentb69681c2014-05-19 19:02:51 -07001471 env->DeleteLocalRef(jSource);
1472 jSource = NULL;
1473 if (jStatus != AUDIO_JAVA_SUCCESS) {
1474 goto exit;
1475 }
1476 nPatch.num_sources++;
1477 }
1478
1479 for (jint i = 0; i < numSinks; i++) {
1480 jSink = env->GetObjectArrayElement(jSinks, i);
1481 if (!env->IsInstanceOf(jSink, gAudioPortConfigClass)) {
1482 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1483 goto exit;
1484 }
Eric Laurent6368a7d2014-11-19 12:18:32 -08001485 jStatus = convertAudioPortConfigToNative(env, &nPatch.sinks[i], jSink, false);
Eric Laurentb69681c2014-05-19 19:02:51 -07001486 env->DeleteLocalRef(jSink);
1487 jSink = NULL;
1488 if (jStatus != AUDIO_JAVA_SUCCESS) {
1489 goto exit;
1490 }
1491 nPatch.num_sinks++;
1492 }
1493
1494 ALOGV("AudioSystem::createAudioPatch");
1495 status = AudioSystem::createAudioPatch(&nPatch, &handle);
1496 ALOGV("AudioSystem::createAudioPatch() returned %d hande %d", status, handle);
1497
1498 jStatus = nativeToJavaStatus(status);
1499 if (jStatus != AUDIO_JAVA_SUCCESS) {
1500 goto exit;
1501 }
1502
1503 if (jPatchHandle == NULL) {
1504 jPatchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1505 handle);
1506 if (jPatchHandle == NULL) {
1507 jStatus = (jint)AUDIO_JAVA_ERROR;
1508 goto exit;
1509 }
1510 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor, jPatchHandle, jSources, jSinks);
1511 if (jPatch == NULL) {
1512 jStatus = (jint)AUDIO_JAVA_ERROR;
1513 goto exit;
1514 }
1515 env->SetObjectArrayElement(jPatches, 0, jPatch);
1516 } else {
1517 env->SetIntField(jPatchHandle, gAudioHandleFields.mId, handle);
1518 }
1519
1520exit:
1521 if (jPatchHandle != NULL) {
1522 env->DeleteLocalRef(jPatchHandle);
1523 }
1524 if (jPatch != NULL) {
1525 env->DeleteLocalRef(jPatch);
1526 }
1527 if (jSource != NULL) {
1528 env->DeleteLocalRef(jSource);
1529 }
1530 if (jSink != NULL) {
1531 env->DeleteLocalRef(jSink);
1532 }
1533 return jStatus;
1534}
1535
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001536static jint
Eric Laurentb69681c2014-05-19 19:02:51 -07001537android_media_AudioSystem_releaseAudioPatch(JNIEnv *env, jobject clazz,
1538 jobject jPatch)
1539{
1540 ALOGV("releaseAudioPatch");
1541 if (jPatch == NULL) {
1542 return (jint)AUDIO_JAVA_BAD_VALUE;
1543 }
1544
1545 audio_patch_handle_t handle = (audio_patch_handle_t)0;
1546 jobject jPatchHandle = NULL;
1547 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1548 return (jint)AUDIO_JAVA_BAD_VALUE;
1549 }
1550 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1551 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1552 env->DeleteLocalRef(jPatchHandle);
1553
1554 ALOGV("AudioSystem::releaseAudioPatch");
1555 status_t status = AudioSystem::releaseAudioPatch(handle);
1556 ALOGV("AudioSystem::releaseAudioPatch() returned %d", status);
1557 jint jStatus = nativeToJavaStatus(status);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001558 return jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001559}
1560
1561static jint
1562android_media_AudioSystem_listAudioPatches(JNIEnv *env, jobject clazz,
1563 jobject jPatches, jintArray jGeneration)
1564{
1565 ALOGV("listAudioPatches");
1566 if (jPatches == NULL) {
1567 ALOGE("listAudioPatches NULL AudioPatch ArrayList");
1568 return (jint)AUDIO_JAVA_BAD_VALUE;
1569 }
1570 if (!env->IsInstanceOf(jPatches, gArrayListClass)) {
1571 ALOGE("listAudioPatches not an arraylist");
1572 return (jint)AUDIO_JAVA_BAD_VALUE;
1573 }
1574
1575 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1576 return (jint)AUDIO_JAVA_BAD_VALUE;
1577 }
1578
1579 status_t status;
1580 unsigned int generation1;
1581 unsigned int generation;
1582 unsigned int numPatches;
1583 jint *nGeneration;
1584 struct audio_patch *nPatches = NULL;
1585 jobjectArray jSources = NULL;
1586 jobject jSource = NULL;
1587 jobjectArray jSinks = NULL;
1588 jobject jSink = NULL;
1589 jobject jPatch = NULL;
1590 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
Eric Laurentb36d1042016-04-14 18:00:38 -07001591 jint jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001592
1593 // get the patch count and all the patches until they both return the same generation
1594 do {
1595 if (attempts-- < 0) {
1596 status = TIMED_OUT;
1597 break;
1598 }
1599
1600 numPatches = 0;
1601 status = AudioSystem::listAudioPatches(&numPatches,
1602 NULL,
1603 &generation1);
Eric Laurentb36d1042016-04-14 18:00:38 -07001604 if (status != NO_ERROR) {
Eric Laurentb69681c2014-05-19 19:02:51 -07001605 ALOGE_IF(status != NO_ERROR, "listAudioPatches AudioSystem::listAudioPatches error %d",
1606 status);
1607 break;
1608 }
Eric Laurentb36d1042016-04-14 18:00:38 -07001609 if (numPatches == 0) {
1610 jStatus = (jint)AUDIO_JAVA_SUCCESS;
1611 goto exit;
1612 }
1613
Eric Laurentb69681c2014-05-19 19:02:51 -07001614 nPatches = (struct audio_patch *)realloc(nPatches, numPatches * sizeof(struct audio_patch));
1615
1616 status = AudioSystem::listAudioPatches(&numPatches,
1617 nPatches,
1618 &generation);
1619 ALOGV("listAudioPatches AudioSystem::listAudioPatches numPatches %d generation %d generation1 %d",
1620 numPatches, generation, generation1);
1621
1622 } while (generation1 != generation && status == NO_ERROR);
1623
Eric Laurentb36d1042016-04-14 18:00:38 -07001624 jStatus = nativeToJavaStatus(status);
Eric Laurentb69681c2014-05-19 19:02:51 -07001625 if (jStatus != AUDIO_JAVA_SUCCESS) {
1626 goto exit;
1627 }
1628
Eric Laurentb69681c2014-05-19 19:02:51 -07001629 for (size_t i = 0; i < numPatches; i++) {
1630 jobject patchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1631 nPatches[i].id);
1632 if (patchHandle == NULL) {
1633 jStatus = AUDIO_JAVA_ERROR;
1634 goto exit;
1635 }
Dan Albert46d84442014-11-18 16:07:51 -08001636 ALOGV("listAudioPatches patch %zu num_sources %d num_sinks %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001637 i, nPatches[i].num_sources, nPatches[i].num_sinks);
1638
1639 env->SetIntField(patchHandle, gAudioHandleFields.mId, nPatches[i].id);
1640
1641 // load sources
1642 jSources = env->NewObjectArray(nPatches[i].num_sources,
1643 gAudioPortConfigClass, NULL);
1644 if (jSources == NULL) {
1645 jStatus = AUDIO_JAVA_ERROR;
1646 goto exit;
1647 }
1648
1649 for (size_t j = 0; j < nPatches[i].num_sources; j++) {
1650 jStatus = convertAudioPortConfigFromNative(env,
1651 NULL,
1652 &jSource,
1653 &nPatches[i].sources[j]);
1654 if (jStatus != AUDIO_JAVA_SUCCESS) {
1655 goto exit;
1656 }
1657 env->SetObjectArrayElement(jSources, j, jSource);
1658 env->DeleteLocalRef(jSource);
1659 jSource = NULL;
Dan Albert46d84442014-11-18 16:07:51 -08001660 ALOGV("listAudioPatches patch %zu source %zu is a %s handle %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001661 i, j,
1662 nPatches[i].sources[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1663 nPatches[i].sources[j].id);
1664 }
1665 // load sinks
1666 jSinks = env->NewObjectArray(nPatches[i].num_sinks,
1667 gAudioPortConfigClass, NULL);
1668 if (jSinks == NULL) {
1669 jStatus = AUDIO_JAVA_ERROR;
1670 goto exit;
1671 }
1672
1673 for (size_t j = 0; j < nPatches[i].num_sinks; j++) {
1674 jStatus = convertAudioPortConfigFromNative(env,
1675 NULL,
1676 &jSink,
1677 &nPatches[i].sinks[j]);
1678
1679 if (jStatus != AUDIO_JAVA_SUCCESS) {
1680 goto exit;
1681 }
1682 env->SetObjectArrayElement(jSinks, j, jSink);
1683 env->DeleteLocalRef(jSink);
1684 jSink = NULL;
Dan Albert46d84442014-11-18 16:07:51 -08001685 ALOGV("listAudioPatches patch %zu sink %zu is a %s handle %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001686 i, j,
1687 nPatches[i].sinks[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1688 nPatches[i].sinks[j].id);
1689 }
1690
1691 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor,
1692 patchHandle, jSources, jSinks);
1693 env->DeleteLocalRef(jSources);
1694 jSources = NULL;
1695 env->DeleteLocalRef(jSinks);
1696 jSinks = NULL;
1697 if (jPatch == NULL) {
1698 jStatus = AUDIO_JAVA_ERROR;
1699 goto exit;
1700 }
1701 env->CallBooleanMethod(jPatches, gArrayListMethods.add, jPatch);
1702 env->DeleteLocalRef(jPatch);
1703 jPatch = NULL;
1704 }
1705
1706exit:
Eric Laurentb36d1042016-04-14 18:00:38 -07001707
1708 nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1709 if (nGeneration == NULL) {
1710 jStatus = AUDIO_JAVA_ERROR;
1711 } else {
1712 nGeneration[0] = generation1;
1713 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1714 }
1715
Eric Laurentb69681c2014-05-19 19:02:51 -07001716 if (jSources != NULL) {
1717 env->DeleteLocalRef(jSources);
1718 }
1719 if (jSource != NULL) {
1720 env->DeleteLocalRef(jSource);
1721 }
1722 if (jSinks != NULL) {
1723 env->DeleteLocalRef(jSinks);
1724 }
1725 if (jSink != NULL) {
1726 env->DeleteLocalRef(jSink);
1727 }
1728 if (jPatch != NULL) {
1729 env->DeleteLocalRef(jPatch);
1730 }
1731 free(nPatches);
1732 return jStatus;
1733}
1734
Eric Laurent3a241992014-05-19 19:33:26 -07001735static jint
1736android_media_AudioSystem_setAudioPortConfig(JNIEnv *env, jobject clazz,
1737 jobject jAudioPortConfig)
1738{
1739 ALOGV("setAudioPortConfig");
1740 if (jAudioPortConfig == NULL) {
1741 return AUDIO_JAVA_BAD_VALUE;
1742 }
1743 if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
1744 return AUDIO_JAVA_BAD_VALUE;
1745 }
Mikhail Naganov304eafc2018-05-23 16:54:12 -07001746 struct audio_port_config nAudioPortConfig = {};
Eric Laurent6368a7d2014-11-19 12:18:32 -08001747 jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig, true);
Eric Laurent3a241992014-05-19 19:33:26 -07001748 if (jStatus != AUDIO_JAVA_SUCCESS) {
1749 return jStatus;
1750 }
1751 status_t status = AudioSystem::setAudioPortConfig(&nAudioPortConfig);
1752 ALOGV("AudioSystem::setAudioPortConfig() returned %d", status);
1753 jStatus = nativeToJavaStatus(status);
1754 return jStatus;
1755}
1756
Hongwei Wangf44a5682018-08-24 10:37:56 -07001757/**
1758 * Returns handle if the audio source is successfully started.
1759 */
1760static jint
1761android_media_AudioSystem_startAudioSource(JNIEnv *env, jobject clazz,
1762 jobject jAudioPortConfig,
1763 jobject jAudioAttributes)
1764{
1765 ALOGV("startAudioSource");
1766 if (jAudioPortConfig == NULL || jAudioAttributes == NULL) {
1767 return AUDIO_JAVA_BAD_VALUE;
1768 }
1769 if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
1770 return AUDIO_JAVA_BAD_VALUE;
1771 }
Hongwei Wangf44a5682018-08-24 10:37:56 -07001772 struct audio_port_config nAudioPortConfig = {};
1773 jint jStatus = convertAudioPortConfigToNativeWithDevicePort(env,
1774 &nAudioPortConfig, jAudioPortConfig, false);
1775 if (jStatus != AUDIO_JAVA_SUCCESS) {
1776 return jStatus;
1777 }
François Gaffieb4691282018-07-09 13:07:32 +02001778 auto paa = JNIAudioAttributeHelper::makeUnique();
1779 jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAudioAttributes, paa.get());
1780 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
Hongwei Wangf44a5682018-08-24 10:37:56 -07001781 return jStatus;
1782 }
1783 audio_port_handle_t handle;
François Gaffieb4691282018-07-09 13:07:32 +02001784 status_t status = AudioSystem::startAudioSource(&nAudioPortConfig, paa.get(), &handle);
Hongwei Wangf44a5682018-08-24 10:37:56 -07001785 ALOGV("AudioSystem::startAudioSource() returned %d handle %d", status, handle);
1786 return handle > 0 ? handle : nativeToJavaStatus(status);
1787}
1788
1789static jint
1790android_media_AudioSystem_stopAudioSource(JNIEnv *env, jobject clazz, jint handle)
1791{
1792 ALOGV("stopAudioSource");
1793 status_t status = AudioSystem::stopAudioSource(
1794 static_cast <audio_port_handle_t>(handle));
1795 ALOGV("AudioSystem::stopAudioSource() returned %d", status);
1796 return nativeToJavaStatus(status);
1797}
1798
Eric Laurent700e7342014-05-02 18:33:15 -07001799static void
1800android_media_AudioSystem_eventHandlerSetup(JNIEnv *env, jobject thiz, jobject weak_this)
1801{
1802 ALOGV("eventHandlerSetup");
1803
1804 sp<JNIAudioPortCallback> callback = new JNIAudioPortCallback(env, thiz, weak_this);
1805
Eric Laurent2615afb2015-03-25 14:51:08 -07001806 if (AudioSystem::addAudioPortCallback(callback) == NO_ERROR) {
1807 setJniCallback(env, thiz, callback);
1808 }
Eric Laurent700e7342014-05-02 18:33:15 -07001809}
1810
1811static void
1812android_media_AudioSystem_eventHandlerFinalize(JNIEnv *env, jobject thiz)
1813{
1814 ALOGV("eventHandlerFinalize");
1815
Eric Laurent2615afb2015-03-25 14:51:08 -07001816 sp<JNIAudioPortCallback> callback = setJniCallback(env, thiz, 0);
Eric Laurent700e7342014-05-02 18:33:15 -07001817
Eric Laurent2615afb2015-03-25 14:51:08 -07001818 if (callback != 0) {
1819 AudioSystem::removeAudioPortCallback(callback);
1820 }
Eric Laurent700e7342014-05-02 18:33:15 -07001821}
1822
Eric Laurentb634e1b2014-08-01 14:44:46 -07001823static jint
1824android_media_AudioSystem_getAudioHwSyncForSession(JNIEnv *env, jobject thiz, jint sessionId)
1825{
Glenn Kasten33b84042016-03-08 12:02:55 -08001826 return (jint) AudioSystem::getAudioHwSyncForSession((audio_session_t) sessionId);
Eric Laurentb634e1b2014-08-01 14:44:46 -07001827}
1828
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07001829static void
1830android_media_AudioSystem_registerDynPolicyCallback(JNIEnv *env, jobject thiz)
1831{
1832 AudioSystem::setDynPolicyCallback(android_media_AudioSystem_dyn_policy_callback);
1833}
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001834
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08001835static void
1836android_media_AudioSystem_registerRecordingCallback(JNIEnv *env, jobject thiz)
1837{
1838 AudioSystem::setRecordConfigCallback(android_media_AudioSystem_recording_callback);
1839}
1840
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001841
1842static jint convertAudioMixToNative(JNIEnv *env,
1843 AudioMix *nAudioMix,
1844 const jobject jAudioMix)
1845{
1846 nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType);
1847 nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags);
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07001848 nAudioMix->mDeviceType = (audio_devices_t)
1849 env->GetIntField(jAudioMix, gAudioMixFields.mDeviceType);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001850
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07001851 jstring jDeviceAddress = (jstring)env->GetObjectField(jAudioMix,
1852 gAudioMixFields.mDeviceAddress);
1853 const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
1854 nAudioMix->mDeviceAddress = String8(nDeviceAddress);
1855 env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
1856 env->DeleteLocalRef(jDeviceAddress);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001857
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07001858 nAudioMix->mCbFlags = env->GetIntField(jAudioMix, gAudioMixFields.mCallbackFlags);
1859
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001860 jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat);
1861 nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat,
1862 gAudioFormatFields.mSampleRate);
1863 nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat,
1864 gAudioFormatFields.mChannelMask));
1865 nAudioMix->mFormat.format = audioFormatToNative(env->GetIntField(jFormat,
1866 gAudioFormatFields.mEncoding));
1867 env->DeleteLocalRef(jFormat);
1868
1869 jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule);
1870 jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria);
1871 env->DeleteLocalRef(jRule);
1872 jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria,
1873 gArrayListMethods.toArray);
1874 env->DeleteLocalRef(jRuleCriteria);
1875
1876 jint numCriteria = env->GetArrayLength(jCriteria);
1877 if (numCriteria > MAX_CRITERIA_PER_MIX) {
1878 numCriteria = MAX_CRITERIA_PER_MIX;
1879 }
1880
1881 for (jint i = 0; i < numCriteria; i++) {
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001882 AudioMixMatchCriterion nCriterion;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001883
1884 jobject jCriterion = env->GetObjectArrayElement(jCriteria, i);
1885
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001886 nCriterion.mRule = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mRule);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001887
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001888 const uint32_t match_rule = nCriterion.mRule & ~RULE_EXCLUSION_MASK;
1889 switch (match_rule) {
1890 case RULE_MATCH_UID:
1891 nCriterion.mValue.mUid = env->GetIntField(jCriterion,
1892 gAudioMixMatchCriterionFields.mIntProp);
1893 break;
1894 case RULE_MATCH_ATTRIBUTE_USAGE:
1895 case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: {
1896 jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr);
François Gaffieb4691282018-07-09 13:07:32 +02001897
1898 auto paa = JNIAudioAttributeHelper::makeUnique();
1899 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAttributes, paa.get());
1900 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
1901 return jStatus;
1902 }
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001903 if (match_rule == RULE_MATCH_ATTRIBUTE_USAGE) {
François Gaffieb4691282018-07-09 13:07:32 +02001904 nCriterion.mValue.mUsage = paa->usage;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001905 } else {
François Gaffieb4691282018-07-09 13:07:32 +02001906 nCriterion.mValue.mSource = paa->source;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001907 }
1908 env->DeleteLocalRef(jAttributes);
1909 }
1910 break;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001911 }
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001912
1913 nAudioMix->mCriteria.add(nCriterion);
1914 env->DeleteLocalRef(jCriterion);
1915 }
1916
1917 env->DeleteLocalRef(jCriteria);
1918
1919 return (jint)AUDIO_JAVA_SUCCESS;
1920}
1921
1922static jint
1923android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz,
1924 jobject jMixesList, jboolean registration)
1925{
1926 ALOGV("registerPolicyMixes");
1927
1928 if (jMixesList == NULL) {
1929 return (jint)AUDIO_JAVA_BAD_VALUE;
1930 }
1931 if (!env->IsInstanceOf(jMixesList, gArrayListClass)) {
1932 return (jint)AUDIO_JAVA_BAD_VALUE;
1933 }
1934 jobjectArray jMixes = (jobjectArray)env->CallObjectMethod(jMixesList,
1935 gArrayListMethods.toArray);
1936 jint numMixes = env->GetArrayLength(jMixes);
1937 if (numMixes > MAX_MIXES_PER_POLICY) {
1938 numMixes = MAX_MIXES_PER_POLICY;
1939 }
1940
1941 status_t status;
1942 jint jStatus;
1943 jobject jAudioMix = NULL;
1944 Vector <AudioMix> mixes;
1945 for (jint i = 0; i < numMixes; i++) {
1946 jAudioMix = env->GetObjectArrayElement(jMixes, i);
1947 if (!env->IsInstanceOf(jAudioMix, gAudioMixClass)) {
1948 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1949 goto exit;
1950 }
1951 AudioMix mix;
1952 jStatus = convertAudioMixToNative(env, &mix, jAudioMix);
1953 env->DeleteLocalRef(jAudioMix);
1954 jAudioMix = NULL;
1955 if (jStatus != AUDIO_JAVA_SUCCESS) {
1956 goto exit;
1957 }
1958 mixes.add(mix);
1959 }
1960
1961 ALOGV("AudioSystem::registerPolicyMixes numMixes %d registration %d", numMixes, registration);
1962 status = AudioSystem::registerPolicyMixes(mixes, registration);
1963 ALOGV("AudioSystem::registerPolicyMixes() returned %d", status);
1964
1965 jStatus = nativeToJavaStatus(status);
1966 if (jStatus != AUDIO_JAVA_SUCCESS) {
1967 goto exit;
1968 }
1969
1970exit:
1971 if (jAudioMix != NULL) {
1972 env->DeleteLocalRef(jAudioMix);
1973 }
1974 return jStatus;
1975}
1976
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08001977static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz,
1978 jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) {
1979 if (deviceTypes == nullptr || deviceAddresses == nullptr) {
1980 return (jint) AUDIO_JAVA_BAD_VALUE;
1981 }
1982 jsize nb = env->GetArrayLength(deviceTypes);
1983 if (nb == 0 || nb != env->GetArrayLength(deviceAddresses)) {
1984 return (jint) AUDIO_JAVA_BAD_VALUE;
1985 }
1986 // retrieve all device types
1987 std::vector<audio_devices_t> deviceTypesVector;
1988 jint* typesPtr = nullptr;
1989 typesPtr = env->GetIntArrayElements(deviceTypes, 0);
1990 if (typesPtr == nullptr) {
1991 return (jint) AUDIO_JAVA_BAD_VALUE;
1992 }
1993 for (jint i = 0; i < nb; i++) {
1994 deviceTypesVector.push_back((audio_devices_t) typesPtr[i]);
1995 }
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08001996
1997 // check each address is a string and add device type/address to list for device affinity
1998 Vector<AudioDeviceTypeAddr> deviceVector;
1999 jclass stringClass = FindClassOrDie(env, "java/lang/String");
2000 for (jint i = 0; i < nb; i++) {
2001 jobject addrJobj = env->GetObjectArrayElement(deviceAddresses, i);
2002 if (!env->IsInstanceOf(addrJobj, stringClass)) {
2003 return (jint) AUDIO_JAVA_BAD_VALUE;
2004 }
2005 String8 address = String8(env->GetStringUTFChars((jstring) addrJobj, NULL));
2006 AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address);
2007 deviceVector.add(dev);
2008 }
Hongwei Wang94d58002019-02-13 16:59:32 -08002009 env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0);
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002010
2011 status_t status = AudioSystem::setUidDeviceAffinities((uid_t) uid, deviceVector);
2012 return (jint) nativeToJavaStatus(status);
2013}
2014
2015static jint android_media_AudioSystem_removeUidDeviceAffinities(JNIEnv *env, jobject clazz,
2016 jint uid) {
2017
2018 //###
2019 status_t status = NO_ERROR;//AudioSystem::removeUidDeviceAffinities();
2020 return (jint) nativeToJavaStatus(status);
2021}
2022
2023
Eric Laurent0867bed2015-05-20 14:49:08 -07002024static jint
2025android_media_AudioSystem_systemReady(JNIEnv *env, jobject thiz)
2026{
2027 return nativeToJavaStatus(AudioSystem::systemReady());
2028}
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002029
Eric Laurenteab40d12017-06-09 12:45:21 -07002030static jfloat
2031android_media_AudioSystem_getStreamVolumeDB(JNIEnv *env, jobject thiz,
2032 jint stream, jint index, jint device)
2033{
2034 return (jfloat)AudioSystem::getStreamVolumeDB((audio_stream_type_t)stream,
2035 (int)index,
2036 (audio_devices_t)device);
2037}
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002038
Jean-Michel Trivi980d38f2018-01-08 15:43:35 -08002039static jboolean
2040android_media_AudioSystem_isOffloadSupported(JNIEnv *env, jobject thiz,
2041 jint encoding, jint sampleRate, jint channelMask, jint channelIndexMask)
2042{
2043 audio_offload_info_t format = AUDIO_INFO_INITIALIZER;
2044 format.format = (audio_format_t) audioFormatToNative(encoding);
2045 format.sample_rate = (uint32_t) sampleRate;
2046 format.channel_mask = nativeChannelMaskFromJavaChannelMasks(channelMask, channelIndexMask);
2047 format.stream_type = AUDIO_STREAM_MUSIC;
2048 format.has_video = false;
2049 format.is_streaming = false;
2050 // offload duration unknown at this point:
2051 // client side code cannot access "audio.offload.min.duration.secs" property to make a query
2052 // agnostic of duration, so using acceptable estimate of 2mn
2053 format.duration_us = 120 * 1000000;
2054 return AudioSystem::isOffloadSupported(format);
2055}
2056
jiabinc0f49442018-01-05 10:23:50 -08002057static jint
2058android_media_AudioSystem_getMicrophones(JNIEnv *env, jobject thiz, jobject jMicrophonesInfo)
2059{
2060 ALOGV("getMicrophones");
2061
2062 if (jMicrophonesInfo == NULL) {
2063 ALOGE("jMicrophonesInfo NULL MicrophoneInfo ArrayList");
2064 return (jint)AUDIO_JAVA_BAD_VALUE;
2065 }
2066 if (!env->IsInstanceOf(jMicrophonesInfo, gArrayListClass)) {
2067 ALOGE("getMicrophones not an arraylist");
2068 return (jint)AUDIO_JAVA_BAD_VALUE;
2069 }
2070
2071 jint jStatus;
2072 std::vector<media::MicrophoneInfo> microphones;
2073 status_t status = AudioSystem::getMicrophones(&microphones);
2074 if (status != NO_ERROR) {
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002075 ALOGE("AudioSystem::getMicrophones error %d", status);
jiabinc0f49442018-01-05 10:23:50 -08002076 jStatus = nativeToJavaStatus(status);
2077 return jStatus;
2078 }
2079 if (microphones.size() == 0) {
2080 jStatus = (jint)AUDIO_JAVA_SUCCESS;
2081 return jStatus;
2082 }
2083 for (size_t i = 0; i < microphones.size(); i++) {
2084 jobject jMicrophoneInfo;
2085 jStatus = convertMicrophoneInfoFromNative(env, &jMicrophoneInfo, &microphones[i]);
2086 if (jStatus != AUDIO_JAVA_SUCCESS) {
2087 return jStatus;
2088 }
2089 env->CallBooleanMethod(jMicrophonesInfo, gArrayListMethods.add, jMicrophoneInfo);
2090 env->DeleteLocalRef(jMicrophoneInfo);
2091 }
2092
2093 return jStatus;
2094}
2095
jiabin39940752018-04-02 18:18:45 -07002096static jint
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002097android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP(
2098 JNIEnv *env, jobject thiz, jobject jEncodingFormatList)
2099{
2100 ALOGV("%s", __FUNCTION__);
2101 jint jStatus = AUDIO_JAVA_SUCCESS;
2102 if (!env->IsInstanceOf(jEncodingFormatList, gArrayListClass)) {
2103 ALOGE("%s: jEncodingFormatList not an ArrayList", __FUNCTION__);
2104 return (jint)AUDIO_JAVA_BAD_VALUE;
2105 }
2106 std::vector<audio_format_t> encodingFormats;
Eric Laurentfffeac82019-01-17 09:03:47 -08002107 status_t status = AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP(
2108 &encodingFormats);
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002109 if (status != NO_ERROR) {
2110 ALOGE("%s: error %d", __FUNCTION__, status);
2111 jStatus = nativeToJavaStatus(status);
2112 return jStatus;
2113 }
2114
2115 for (size_t i = 0; i < encodingFormats.size(); i++) {
2116 ScopedLocalRef<jobject> jEncodingFormat(
2117 env, env->NewObject(gIntegerClass, gIntegerCstor, encodingFormats[i]));
2118 env->CallBooleanMethod(jEncodingFormatList, gArrayListMethods.add,
2119 jEncodingFormat.get());
2120 }
2121 return jStatus;
2122}
2123
2124static jint
jiabin39940752018-04-02 18:18:45 -07002125android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
2126 jobject jSurroundFormats, jboolean reported)
2127{
2128 ALOGV("getSurroundFormats");
2129
2130 if (jSurroundFormats == NULL) {
2131 ALOGE("jSurroundFormats is NULL");
2132 return (jint)AUDIO_JAVA_BAD_VALUE;
2133 }
2134 if (!env->IsInstanceOf(jSurroundFormats, gMapClass)) {
2135 ALOGE("getSurroundFormats not a map");
2136 return (jint)AUDIO_JAVA_BAD_VALUE;
2137 }
2138
2139 jint jStatus;
2140 unsigned int numSurroundFormats = 0;
2141 audio_format_t *surroundFormats = NULL;
2142 bool *surroundFormatsEnabled = NULL;
2143 status_t status = AudioSystem::getSurroundFormats(
2144 &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
2145 if (status != NO_ERROR) {
2146 ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
2147 jStatus = nativeToJavaStatus(status);
2148 goto exit;
2149 }
2150 if (numSurroundFormats == 0) {
2151 jStatus = (jint)AUDIO_JAVA_SUCCESS;
2152 goto exit;
2153 }
2154 surroundFormats = (audio_format_t *)calloc(numSurroundFormats, sizeof(audio_format_t));
2155 surroundFormatsEnabled = (bool *)calloc(numSurroundFormats, sizeof(bool));
2156 status = AudioSystem::getSurroundFormats(
2157 &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
2158 jStatus = nativeToJavaStatus(status);
2159 if (status != NO_ERROR) {
2160 ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
2161 goto exit;
2162 }
2163 for (size_t i = 0; i < numSurroundFormats; i++) {
2164 jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor,
2165 audioFormatFromNative(surroundFormats[i]));
2166 jobject enabled = env->NewObject(gBooleanClass, gBooleanCstor, surroundFormatsEnabled[i]);
2167 env->CallObjectMethod(jSurroundFormats, gMapPut, surroundFormat, enabled);
2168 env->DeleteLocalRef(surroundFormat);
2169 env->DeleteLocalRef(enabled);
2170 }
2171
2172exit:
2173 free(surroundFormats);
2174 free(surroundFormatsEnabled);
2175 return jStatus;
2176}
2177
2178static jint
2179android_media_AudioSystem_setSurroundFormatEnabled(JNIEnv *env, jobject thiz,
2180 jint audioFormat, jboolean enabled)
2181{
2182 status_t status = AudioSystem::setSurroundFormatEnabled(audioFormatToNative(audioFormat),
2183 (bool)enabled);
2184 if (status != NO_ERROR) {
2185 ALOGE_IF(status != NO_ERROR, "AudioSystem::setSurroundFormatEnabled error %d", status);
2186 }
2187 return (jint)nativeToJavaStatus(status);
2188}
2189
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002190static jint android_media_AudioSystem_get_FCC_8(JNIEnv *env, jobject thiz) {
2191 return FCC_8;
2192}
2193
Eric Laurent1c9c1d52018-10-17 10:06:46 -07002194static jint
2195android_media_AudioSystem_setAssistantUid(JNIEnv *env, jobject thiz, jint uid)
2196{
2197 status_t status = AudioSystem::setAssistantUid(uid);
2198 return (jint)nativeToJavaStatus(status);
2199}
2200
2201static jint
2202android_media_AudioSystem_setA11yServicesUids(JNIEnv *env, jobject thiz, jintArray uids) {
2203 std::vector<uid_t> nativeUidsVector;
2204
2205 if (uids != nullptr) {
2206 jsize len = env->GetArrayLength(uids);
2207
2208 if (len > 0) {
2209 int *nativeUids = nullptr;
2210 nativeUids = env->GetIntArrayElements(uids, 0);
2211 if (nativeUids != nullptr) {
2212 for (size_t i = 0; i < len; i++) {
2213 nativeUidsVector.push_back(nativeUids[i]);
2214 }
2215 env->ReleaseIntArrayElements(uids, nativeUids, 0);
2216 }
2217 }
2218 }
2219 status_t status = AudioSystem::setA11yServicesUids(nativeUidsVector);
2220 return (jint)nativeToJavaStatus(status);
2221}
2222
jiabin66f9e722018-11-02 16:20:19 -07002223static jboolean
2224android_media_AudioSystem_isHapticPlaybackSupported(JNIEnv *env, jobject thiz)
2225{
2226 return AudioSystem::isHapticPlaybackSupported();
2227}
2228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002229// ----------------------------------------------------------------------------
2230
Daniel Micay76f6a862015-09-19 17:31:01 -04002231static const JNINativeMethod gMethods[] = {
Eric Laurenta553c252009-07-17 12:17:14 -07002232 {"setParameters", "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
2233 {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002234 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
2235 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
Jean-Michel Trivid6770542012-10-10 12:03:41 -07002236 {"isStreamActive", "(II)Z", (void *)android_media_AudioSystem_isStreamActive},
Jean-Michel Trivi679d5042013-02-04 16:24:09 -08002237 {"isStreamActiveRemotely","(II)Z", (void *)android_media_AudioSystem_isStreamActiveRemotely},
Jean-Michel Trivid6770542012-10-10 12:03:41 -07002238 {"isSourceActive", "(I)Z", (void *)android_media_AudioSystem_isSourceActive},
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -07002239 {"newAudioSessionId", "()I", (void *)android_media_AudioSystem_newAudioSessionId},
Jean-Michel Trivi292a6a42016-12-01 08:32:15 -08002240 {"newAudioPlayerId", "()I", (void *)android_media_AudioSystem_newAudioPlayerId},
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -08002241 {"setDeviceConnectionState", "(IILjava/lang/String;Ljava/lang/String;I)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
Eric Laurenta553c252009-07-17 12:17:14 -07002242 {"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -08002243 {"handleDeviceConfigChange", "(ILjava/lang/String;Ljava/lang/String;I)I", (void *)android_media_AudioSystem_handleDeviceConfigChange},
Eric Laurenta553c252009-07-17 12:17:14 -07002244 {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
Eric Laurenta553c252009-07-17 12:17:14 -07002245 {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
2246 {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
2247 {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume},
Eric Laurent9bc8358d2011-11-18 16:43:31 -08002248 {"setStreamVolumeIndex","(III)I", (void *)android_media_AudioSystem_setStreamVolumeIndex},
2249 {"getStreamVolumeIndex","(II)I", (void *)android_media_AudioSystem_getStreamVolumeIndex},
François Gaffieebb67d02018-09-14 15:05:04 +02002250 {"setVolumeIndexForAttributes","(Landroid/media/AudioAttributes;II)I", (void *)android_media_AudioSystem_setVolumeIndexForAttributes},
2251 {"getVolumeIndexForAttributes","(Landroid/media/AudioAttributes;I)I", (void *)android_media_AudioSystem_getVolumeIndexForAttributes},
2252 {"getMinVolumeIndexForAttributes","(Landroid/media/AudioAttributes;)I", (void *)android_media_AudioSystem_getMinVolumeIndexForAttributes},
2253 {"getMaxVolumeIndexForAttributes","(Landroid/media/AudioAttributes;)I", (void *)android_media_AudioSystem_getMaxVolumeIndexForAttributes},
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -04002254 {"setMasterVolume", "(F)I", (void *)android_media_AudioSystem_setMasterVolume},
2255 {"getMasterVolume", "()F", (void *)android_media_AudioSystem_getMasterVolume},
2256 {"setMasterMute", "(Z)I", (void *)android_media_AudioSystem_setMasterMute},
2257 {"getMasterMute", "()Z", (void *)android_media_AudioSystem_getMasterMute},
Andy Hungf04b84d2015-12-18 17:33:27 -08002258 {"setMasterMono", "(Z)I", (void *)android_media_AudioSystem_setMasterMono},
2259 {"getMasterMono", "()Z", (void *)android_media_AudioSystem_getMasterMono},
Edward Savage-Jones35c292f2017-01-13 09:04:34 +01002260 {"setMasterBalance", "(F)I", (void *)android_media_AudioSystem_setMasterBalance},
2261 {"getMasterBalance", "()F", (void *)android_media_AudioSystem_getMasterBalance},
Glenn Kasten8b4b97a2011-02-04 13:54:26 -08002262 {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream},
Glenn Kastenc6c43652012-09-24 17:32:30 -07002263 {"getPrimaryOutputSamplingRate", "()I", (void *)android_media_AudioSystem_getPrimaryOutputSamplingRate},
2264 {"getPrimaryOutputFrameCount", "()I", (void *)android_media_AudioSystem_getPrimaryOutputFrameCount},
Oliver Woodman61dcdf32013-06-26 12:43:36 +01002265 {"getOutputLatency", "(I)I", (void *)android_media_AudioSystem_getOutputLatency},
Andy Hung79583582018-01-23 13:58:02 -08002266 {"setLowRamDevice", "(ZJ)I", (void *)android_media_AudioSystem_setLowRamDevice},
Eric Laurentdfb881f2013-07-18 14:41:39 -07002267 {"checkAudioFlinger", "()I", (void *)android_media_AudioSystem_checkAudioFlinger},
Eric Laurentb69681c2014-05-19 19:02:51 -07002268 {"listAudioPorts", "(Ljava/util/ArrayList;[I)I",
2269 (void *)android_media_AudioSystem_listAudioPorts},
2270 {"createAudioPatch", "([Landroid/media/AudioPatch;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)I",
2271 (void *)android_media_AudioSystem_createAudioPatch},
2272 {"releaseAudioPatch", "(Landroid/media/AudioPatch;)I",
2273 (void *)android_media_AudioSystem_releaseAudioPatch},
2274 {"listAudioPatches", "(Ljava/util/ArrayList;[I)I",
2275 (void *)android_media_AudioSystem_listAudioPatches},
Eric Laurent3a241992014-05-19 19:33:26 -07002276 {"setAudioPortConfig", "(Landroid/media/AudioPortConfig;)I",
2277 (void *)android_media_AudioSystem_setAudioPortConfig},
Hongwei Wangf44a5682018-08-24 10:37:56 -07002278 {"startAudioSource", "(Landroid/media/AudioPortConfig;Landroid/media/AudioAttributes;)I",
2279 (void *)android_media_AudioSystem_startAudioSource},
2280 {"stopAudioSource", "(I)I", (void *)android_media_AudioSystem_stopAudioSource},
Eric Laurentb634e1b2014-08-01 14:44:46 -07002281 {"getAudioHwSyncForSession", "(I)I",
2282 (void *)android_media_AudioSystem_getAudioHwSyncForSession},
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002283 {"registerPolicyMixes", "(Ljava/util/ArrayList;Z)I",
2284 (void *)android_media_AudioSystem_registerPolicyMixes},
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002285 {"setUidDeviceAffinities", "(I[I[Ljava/lang/String;)I",
2286 (void *)android_media_AudioSystem_setUidDeviceAffinities},
2287 {"removeUidDeviceAffinities", "(I)I",
2288 (void *)android_media_AudioSystem_removeUidDeviceAffinities},
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002289 {"native_register_dynamic_policy_callback", "()V",
2290 (void *)android_media_AudioSystem_registerDynPolicyCallback},
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002291 {"native_register_recording_callback", "()V",
2292 (void *)android_media_AudioSystem_registerRecordingCallback},
Eric Laurent0867bed2015-05-20 14:49:08 -07002293 {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady},
Eric Laurenteab40d12017-06-09 12:45:21 -07002294 {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
Jean-Michel Trivi980d38f2018-01-08 15:43:35 -08002295 {"native_is_offload_supported", "(IIII)Z", (void *)android_media_AudioSystem_isOffloadSupported},
jiabinc0f49442018-01-05 10:23:50 -08002296 {"getMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioSystem_getMicrophones},
jiabin39940752018-04-02 18:18:45 -07002297 {"getSurroundFormats", "(Ljava/util/Map;Z)I", (void *)android_media_AudioSystem_getSurroundFormats},
2298 {"setSurroundFormatEnabled", "(IZ)I", (void *)android_media_AudioSystem_setSurroundFormatEnabled},
Eric Laurent1c9c1d52018-10-17 10:06:46 -07002299 {"setAssistantUid", "(I)I", (void *)android_media_AudioSystem_setAssistantUid},
2300 {"setA11yServicesUids", "([I)I", (void *)android_media_AudioSystem_setA11yServicesUids},
jiabin66f9e722018-11-02 16:20:19 -07002301 {"isHapticPlaybackSupported", "()Z", (void *)android_media_AudioSystem_isHapticPlaybackSupported},
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002302 {"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
2303 (void*)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002304};
2305
Daniel Micay76f6a862015-09-19 17:31:01 -04002306static const JNINativeMethod gEventHandlerMethods[] = {
Eric Laurent700e7342014-05-02 18:33:15 -07002307 {"native_setup",
2308 "(Ljava/lang/Object;)V",
2309 (void *)android_media_AudioSystem_eventHandlerSetup},
2310 {"native_finalize",
2311 "()V",
2312 (void *)android_media_AudioSystem_eventHandlerFinalize},
2313};
2314
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002315static const JNINativeMethod gGetFCC8Methods[] = {
2316 {"native_get_FCC_8", "()I", (void *)android_media_AudioSystem_get_FCC_8},
2317};
2318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319int register_android_media_AudioSystem(JNIEnv *env)
2320{
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002321 // This needs to be done before hooking up methods AudioTrackRoutingProxy (below)
2322 RegisterMethodsOrDie(env, kClassPathName, gGetFCC8Methods, NELEM(gGetFCC8Methods));
2323
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002324 jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
2325 gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
2326 gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
Eric Laurent09378972014-12-10 10:42:08 -08002327 gArrayListMethods.toArray = GetMethodIDOrDie(env, arrayListClass, "toArray", "()[Ljava/lang/Object;");
Eric Laurentb69681c2014-05-19 19:02:51 -07002328
jiabin39940752018-04-02 18:18:45 -07002329 jclass booleanClass = FindClassOrDie(env, "java/lang/Boolean");
2330 gBooleanClass = MakeGlobalRefOrDie(env, booleanClass);
2331 gBooleanCstor = GetMethodIDOrDie(env, booleanClass, "<init>", "(Z)V");
2332
2333 jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
2334 gIntegerClass = MakeGlobalRefOrDie(env, integerClass);
2335 gIntegerCstor = GetMethodIDOrDie(env, integerClass, "<init>", "(I)V");
2336
2337 jclass mapClass = FindClassOrDie(env, "java/util/Map");
2338 gMapClass = MakeGlobalRefOrDie(env, mapClass);
2339 gMapPut = GetMethodIDOrDie(env, mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
2340
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002341 jclass audioHandleClass = FindClassOrDie(env, "android/media/AudioHandle");
2342 gAudioHandleClass = MakeGlobalRefOrDie(env, audioHandleClass);
2343 gAudioHandleCstor = GetMethodIDOrDie(env, audioHandleClass, "<init>", "(I)V");
2344 gAudioHandleFields.mId = GetFieldIDOrDie(env, audioHandleClass, "mId", "I");
Eric Laurentb69681c2014-05-19 19:02:51 -07002345
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002346 jclass audioPortClass = FindClassOrDie(env, "android/media/AudioPort");
2347 gAudioPortClass = MakeGlobalRefOrDie(env, audioPortClass);
2348 gAudioPortCstor = GetMethodIDOrDie(env, audioPortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002349 "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002350 gAudioPortFields.mHandle = GetFieldIDOrDie(env, audioPortClass, "mHandle",
Eric Laurentb69681c2014-05-19 19:02:51 -07002351 "Landroid/media/AudioHandle;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002352 gAudioPortFields.mRole = GetFieldIDOrDie(env, audioPortClass, "mRole", "I");
2353 gAudioPortFields.mGains = GetFieldIDOrDie(env, audioPortClass, "mGains",
Eric Laurentb69681c2014-05-19 19:02:51 -07002354 "[Landroid/media/AudioGain;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002355 gAudioPortFields.mActiveConfig = GetFieldIDOrDie(env, audioPortClass, "mActiveConfig",
2356 "Landroid/media/AudioPortConfig;");
Eric Laurentb69681c2014-05-19 19:02:51 -07002357
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002358 jclass audioPortConfigClass = FindClassOrDie(env, "android/media/AudioPortConfig");
2359 gAudioPortConfigClass = MakeGlobalRefOrDie(env, audioPortConfigClass);
2360 gAudioPortConfigCstor = GetMethodIDOrDie(env, audioPortConfigClass, "<init>",
2361 "(Landroid/media/AudioPort;IIILandroid/media/AudioGainConfig;)V");
2362 gAudioPortConfigFields.mPort = GetFieldIDOrDie(env, audioPortConfigClass, "mPort",
Eric Laurentb69681c2014-05-19 19:02:51 -07002363 "Landroid/media/AudioPort;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002364 gAudioPortConfigFields.mSamplingRate = GetFieldIDOrDie(env, audioPortConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002365 "mSamplingRate", "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002366 gAudioPortConfigFields.mChannelMask = GetFieldIDOrDie(env, audioPortConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002367 "mChannelMask", "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002368 gAudioPortConfigFields.mFormat = GetFieldIDOrDie(env, audioPortConfigClass, "mFormat", "I");
2369 gAudioPortConfigFields.mGain = GetFieldIDOrDie(env, audioPortConfigClass, "mGain",
Eric Laurentb69681c2014-05-19 19:02:51 -07002370 "Landroid/media/AudioGainConfig;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002371 gAudioPortConfigFields.mConfigMask = GetFieldIDOrDie(env, audioPortConfigClass, "mConfigMask",
2372 "I");
Eric Laurentb69681c2014-05-19 19:02:51 -07002373
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002374 jclass audioDevicePortConfigClass = FindClassOrDie(env, "android/media/AudioDevicePortConfig");
2375 gAudioDevicePortConfigClass = MakeGlobalRefOrDie(env, audioDevicePortConfigClass);
2376 gAudioDevicePortConfigCstor = GetMethodIDOrDie(env, audioDevicePortConfigClass, "<init>",
2377 "(Landroid/media/AudioDevicePort;IIILandroid/media/AudioGainConfig;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002378
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002379 jclass audioMixPortConfigClass = FindClassOrDie(env, "android/media/AudioMixPortConfig");
2380 gAudioMixPortConfigClass = MakeGlobalRefOrDie(env, audioMixPortConfigClass);
2381 gAudioMixPortConfigCstor = GetMethodIDOrDie(env, audioMixPortConfigClass, "<init>",
2382 "(Landroid/media/AudioMixPort;IIILandroid/media/AudioGainConfig;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002383
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002384 jclass audioDevicePortClass = FindClassOrDie(env, "android/media/AudioDevicePort");
2385 gAudioDevicePortClass = MakeGlobalRefOrDie(env, audioDevicePortClass);
2386 gAudioDevicePortCstor = GetMethodIDOrDie(env, audioDevicePortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002387 "(Landroid/media/AudioHandle;Ljava/lang/String;[I[I[I[I[Landroid/media/AudioGain;ILjava/lang/String;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002388
Hongwei Wangf44a5682018-08-24 10:37:56 -07002389 // When access AudioPort as AudioDevicePort
2390 gAudioPortFields.mType = GetFieldIDOrDie(env, audioDevicePortClass, "mType", "I");
2391 gAudioPortFields.mAddress = GetFieldIDOrDie(env, audioDevicePortClass, "mAddress",
2392 "Ljava/lang/String;");
2393
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002394 jclass audioMixPortClass = FindClassOrDie(env, "android/media/AudioMixPort");
2395 gAudioMixPortClass = MakeGlobalRefOrDie(env, audioMixPortClass);
2396 gAudioMixPortCstor = GetMethodIDOrDie(env, audioMixPortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002397 "(Landroid/media/AudioHandle;IILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002398
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002399 jclass audioGainClass = FindClassOrDie(env, "android/media/AudioGain");
2400 gAudioGainClass = MakeGlobalRefOrDie(env, audioGainClass);
2401 gAudioGainCstor = GetMethodIDOrDie(env, audioGainClass, "<init>", "(IIIIIIIII)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002402
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002403 jclass audioGainConfigClass = FindClassOrDie(env, "android/media/AudioGainConfig");
2404 gAudioGainConfigClass = MakeGlobalRefOrDie(env, audioGainConfigClass);
2405 gAudioGainConfigCstor = GetMethodIDOrDie(env, audioGainConfigClass, "<init>",
Eric Laurentb69681c2014-05-19 19:02:51 -07002406 "(ILandroid/media/AudioGain;II[II)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002407 gAudioGainConfigFields.mIndex = GetFieldIDOrDie(env, gAudioGainConfigClass, "mIndex", "I");
2408 gAudioGainConfigFields.mMode = GetFieldIDOrDie(env, audioGainConfigClass, "mMode", "I");
2409 gAudioGainConfigFields.mChannelMask = GetFieldIDOrDie(env, audioGainConfigClass, "mChannelMask",
Eric Laurentb69681c2014-05-19 19:02:51 -07002410 "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002411 gAudioGainConfigFields.mValues = GetFieldIDOrDie(env, audioGainConfigClass, "mValues", "[I");
2412 gAudioGainConfigFields.mRampDurationMs = GetFieldIDOrDie(env, audioGainConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002413 "mRampDurationMs", "I");
2414
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002415 jclass audioPatchClass = FindClassOrDie(env, "android/media/AudioPatch");
2416 gAudioPatchClass = MakeGlobalRefOrDie(env, audioPatchClass);
2417 gAudioPatchCstor = GetMethodIDOrDie(env, audioPatchClass, "<init>",
Eric Laurentb69681c2014-05-19 19:02:51 -07002418"(Landroid/media/AudioHandle;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002419 gAudioPatchFields.mHandle = GetFieldIDOrDie(env, audioPatchClass, "mHandle",
Eric Laurentb69681c2014-05-19 19:02:51 -07002420 "Landroid/media/AudioHandle;");
2421
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002422 jclass eventHandlerClass = FindClassOrDie(env, kEventHandlerClassPathName);
Eric Laurent2615afb2015-03-25 14:51:08 -07002423 gAudioPortEventHandlerMethods.postEventFromNative = GetStaticMethodIDOrDie(
2424 env, eventHandlerClass, "postEventFromNative",
2425 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
2426 gEventHandlerFields.mJniCallback = GetFieldIDOrDie(env,
2427 eventHandlerClass, "mJniCallback", "J");
Eric Laurent700e7342014-05-02 18:33:15 -07002428
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002429 gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative =
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002430 GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
2431 "dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V");
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002432 gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative =
2433 GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
Eric Laurentc7a0cdf2018-11-30 12:16:52 -08002434 "recordingCallbackFromNative", "(IIIIIZ[I[Landroid/media/audiofx/AudioEffect$Descriptor;[Landroid/media/audiofx/AudioEffect$Descriptor;I)V");
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002435
Eric Laurent09378972014-12-10 10:42:08 -08002436 jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix");
2437 gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass);
2438 gAudioMixFields.mRule = GetFieldIDOrDie(env, audioMixClass, "mRule",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002439 "Landroid/media/audiopolicy/AudioMixingRule;");
Eric Laurent09378972014-12-10 10:42:08 -08002440 gAudioMixFields.mFormat = GetFieldIDOrDie(env, audioMixClass, "mFormat",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002441 "Landroid/media/AudioFormat;");
Eric Laurent09378972014-12-10 10:42:08 -08002442 gAudioMixFields.mRouteFlags = GetFieldIDOrDie(env, audioMixClass, "mRouteFlags", "I");
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07002443 gAudioMixFields.mDeviceType = GetFieldIDOrDie(env, audioMixClass, "mDeviceSystemType", "I");
2444 gAudioMixFields.mDeviceAddress = GetFieldIDOrDie(env, audioMixClass, "mDeviceAddress",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002445 "Ljava/lang/String;");
Eric Laurent09378972014-12-10 10:42:08 -08002446 gAudioMixFields.mMixType = GetFieldIDOrDie(env, audioMixClass, "mMixType", "I");
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002447 gAudioMixFields.mCallbackFlags = GetFieldIDOrDie(env, audioMixClass, "mCallbackFlags", "I");
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002448
Eric Laurent09378972014-12-10 10:42:08 -08002449 jclass audioFormatClass = FindClassOrDie(env, "android/media/AudioFormat");
2450 gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass);
2451 gAudioFormatFields.mEncoding = GetFieldIDOrDie(env, audioFormatClass, "mEncoding", "I");
2452 gAudioFormatFields.mSampleRate = GetFieldIDOrDie(env, audioFormatClass, "mSampleRate", "I");
2453 gAudioFormatFields.mChannelMask = GetFieldIDOrDie(env, audioFormatClass, "mChannelMask", "I");
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002454
Eric Laurent09378972014-12-10 10:42:08 -08002455 jclass audioMixingRuleClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule");
2456 gAudioMixingRuleClass = MakeGlobalRefOrDie(env, audioMixingRuleClass);
2457 gAudioMixingRuleFields.mCriteria = GetFieldIDOrDie(env, audioMixingRuleClass, "mCriteria",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002458 "Ljava/util/ArrayList;");
2459
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08002460 jclass audioMixMatchCriterionClass =
2461 FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion");
2462 gAudioMixMatchCriterionClass = MakeGlobalRefOrDie(env,audioMixMatchCriterionClass);
2463 gAudioMixMatchCriterionFields.mAttr = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mAttr",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002464 "Landroid/media/AudioAttributes;");
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08002465 gAudioMixMatchCriterionFields.mIntProp = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mIntProp",
2466 "I");
2467 gAudioMixMatchCriterionFields.mRule = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mRule",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002468 "I");
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002469 // AudioTrackRoutingProxy methods
2470 gClsAudioTrackRoutingProxy =
2471 android::FindClassOrDie(env, "android/media/AudioTrackRoutingProxy");
2472 // make sure this reference doesn't get deleted
2473 gClsAudioTrackRoutingProxy = (jclass)env->NewGlobalRef(gClsAudioTrackRoutingProxy);
2474
2475 gMidAudioTrackRoutingProxy_ctor =
2476 android::GetMethodIDOrDie(env, gClsAudioTrackRoutingProxy, "<init>", "(J)V");
2477 gMidAudioTrackRoutingProxy_release =
2478 android::GetMethodIDOrDie(env, gClsAudioTrackRoutingProxy, "native_release", "()V");
2479
2480 // AudioRecordRoutingProxy
2481 gClsAudioRecordRoutingProxy =
2482 android::FindClassOrDie(env, "android/media/AudioRecordRoutingProxy");
2483 // make sure this reference doesn't get deleted
2484 gClsAudioRecordRoutingProxy = (jclass)env->NewGlobalRef(gClsAudioRecordRoutingProxy);
2485
2486 gMidAudioRecordRoutingProxy_ctor =
2487 android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "<init>", "(J)V");
2488 gMidAudioRecordRoutingProxy_release =
2489 android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "native_release", "()V");
2490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002491 AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
Glenn Kasten18db49a2012-03-12 16:29:55 -07002492
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002493 RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
2494 return RegisterMethodsOrDie(env, kEventHandlerClassPathName, gEventHandlerMethods,
2495 NELEM(gEventHandlerMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002496}