blob: a296d647657bb6cfe5b3e4f491a381846fdb06c4 [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;
Kevin Rocarda3a4bbb2019-03-07 18:29:48 -0800147 jfieldID mAllowPrivilegedPlaybackCapture;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800148 // other fields unused by JNI
149} gAudioMixingRuleFields;
150
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800151static jclass gAudioMixMatchCriterionClass;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800152static struct {
153 jfieldID mAttr;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800154 jfieldID mIntProp;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800155 jfieldID mRule;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -0800156} gAudioMixMatchCriterionFields;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -0800157
Eric Laurent700e7342014-05-02 18:33:15 -0700158static const char* const kEventHandlerClassPathName =
159 "android/media/AudioPortEventHandler";
Eric Laurent2615afb2015-03-25 14:51:08 -0700160static struct {
161 jfieldID mJniCallback;
162} gEventHandlerFields;
163static struct {
164 jmethodID postEventFromNative;
165} gAudioPortEventHandlerMethods;
166
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700167static struct {
168 jmethodID postDynPolicyEventFromNative;
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800169 jmethodID postRecordConfigEventFromNative;
170} gAudioPolicyEventHandlerMethods;
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700171
Paul McLeanb3ae6d92018-11-05 15:16:59 -0700172//
173// JNI Initialization for OpenSLES routing
174//
175jmethodID gMidAudioTrackRoutingProxy_ctor;
176jmethodID gMidAudioTrackRoutingProxy_release;
177jmethodID gMidAudioRecordRoutingProxy_ctor;
178jmethodID gMidAudioRecordRoutingProxy_release;
179
180jclass gClsAudioTrackRoutingProxy;
181jclass gClsAudioRecordRoutingProxy;
182
Eric Laurent2615afb2015-03-25 14:51:08 -0700183static Mutex gLock;
Eric Laurentb69681c2014-05-19 19:02:51 -0700184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185enum AudioError {
186 kAudioStatusOk = 0,
187 kAudioStatusError = 1,
188 kAudioStatusMediaServerDied = 100
189};
190
Eric Laurent700e7342014-05-02 18:33:15 -0700191enum {
192 AUDIOPORT_EVENT_PORT_LIST_UPDATED = 1,
193 AUDIOPORT_EVENT_PATCH_LIST_UPDATED = 2,
194 AUDIOPORT_EVENT_SERVICE_DIED = 3,
195};
196
Eric Laurentb69681c2014-05-19 19:02:51 -0700197#define MAX_PORT_GENERATION_SYNC_ATTEMPTS 5
198
Eric Laurent700e7342014-05-02 18:33:15 -0700199// ----------------------------------------------------------------------------
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700200// ref-counted object for audio port callbacks
Eric Laurent700e7342014-05-02 18:33:15 -0700201class JNIAudioPortCallback: public AudioSystem::AudioPortCallback
202{
203public:
204 JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
205 ~JNIAudioPortCallback();
206
207 virtual void onAudioPortListUpdate();
208 virtual void onAudioPatchListUpdate();
209 virtual void onServiceDied();
210
211private:
212 void sendEvent(int event);
213
Eric Laurent2615afb2015-03-25 14:51:08 -0700214 jclass mClass; // Reference to AudioPortEventHandler class
215 jobject mObject; // Weak ref to AudioPortEventHandler Java object to call on
Eric Laurent700e7342014-05-02 18:33:15 -0700216};
217
218JNIAudioPortCallback::JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
219{
220
Eric Laurent2615afb2015-03-25 14:51:08 -0700221 // Hold onto the AudioPortEventHandler class for use in calling the static method
Eric Laurent700e7342014-05-02 18:33:15 -0700222 // that posts events to the application thread.
223 jclass clazz = env->GetObjectClass(thiz);
224 if (clazz == NULL) {
225 ALOGE("Can't find class %s", kEventHandlerClassPathName);
226 return;
227 }
228 mClass = (jclass)env->NewGlobalRef(clazz);
229
Eric Laurent2615afb2015-03-25 14:51:08 -0700230 // We use a weak reference so the AudioPortEventHandler object can be garbage collected.
Eric Laurent700e7342014-05-02 18:33:15 -0700231 // The reference is only used as a proxy for callbacks.
232 mObject = env->NewGlobalRef(weak_thiz);
233}
234
235JNIAudioPortCallback::~JNIAudioPortCallback()
236{
237 // remove global references
238 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent449c5882014-11-12 11:07:48 -0800239 if (env == NULL) {
240 return;
241 }
Eric Laurent700e7342014-05-02 18:33:15 -0700242 env->DeleteGlobalRef(mObject);
243 env->DeleteGlobalRef(mClass);
244}
245
246void JNIAudioPortCallback::sendEvent(int event)
247{
248 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent449c5882014-11-12 11:07:48 -0800249 if (env == NULL) {
250 return;
251 }
Eric Laurent2615afb2015-03-25 14:51:08 -0700252 env->CallStaticVoidMethod(mClass, gAudioPortEventHandlerMethods.postEventFromNative, mObject,
Eric Laurent700e7342014-05-02 18:33:15 -0700253 event, 0, 0, NULL);
254 if (env->ExceptionCheck()) {
255 ALOGW("An exception occurred while notifying an event.");
256 env->ExceptionClear();
257 }
258}
259
260void JNIAudioPortCallback::onAudioPortListUpdate()
261{
262 sendEvent(AUDIOPORT_EVENT_PORT_LIST_UPDATED);
263}
264
265void JNIAudioPortCallback::onAudioPatchListUpdate()
266{
267 sendEvent(AUDIOPORT_EVENT_PATCH_LIST_UPDATED);
268}
269
270void JNIAudioPortCallback::onServiceDied()
271{
272 sendEvent(AUDIOPORT_EVENT_SERVICE_DIED);
273}
274
Eric Laurent2615afb2015-03-25 14:51:08 -0700275static sp<JNIAudioPortCallback> setJniCallback(JNIEnv* env,
276 jobject thiz,
277 const sp<JNIAudioPortCallback>& callback)
278{
279 Mutex::Autolock l(gLock);
280 sp<JNIAudioPortCallback> old =
281 (JNIAudioPortCallback*)env->GetLongField(thiz, gEventHandlerFields.mJniCallback);
282 if (callback.get()) {
283 callback->incStrong((void*)setJniCallback);
284 }
285 if (old != 0) {
286 old->decStrong((void*)setJniCallback);
287 }
288 env->SetLongField(thiz, gEventHandlerFields.mJniCallback, (jlong)callback.get());
289 return old;
290}
291
Mikhail Naganov5caa57d2018-04-02 10:35:45 -0700292#define check_AudioSystem_Command(status) _check_AudioSystem_Command(__func__, (status))
293
294static int _check_AudioSystem_Command(const char* caller, status_t status)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295{
Mikhail Naganov5caa57d2018-04-02 10:35:45 -0700296 ALOGE_IF(status, "Command failed for %s: %d", caller, status);
Eric Laurentdfb881f2013-07-18 14:41:39 -0700297 switch (status) {
298 case DEAD_OBJECT:
299 return kAudioStatusMediaServerDied;
300 case NO_ERROR:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 return kAudioStatusOk;
Eric Laurentdfb881f2013-07-18 14:41:39 -0700302 default:
303 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 }
Eric Laurentdfb881f2013-07-18 14:41:39 -0700305 return kAudioStatusError;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306}
307
Ashok Bhat075e9a12014-01-06 13:45:09 +0000308static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
310{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000311 return (jint) check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312}
313
314static jboolean
315android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
316{
317 bool state = false;
318 AudioSystem::isMicrophoneMuted(&state);
319 return state;
320}
321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322static jboolean
Eric Laurent25101b02011-02-02 09:33:30 -0800323android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324{
325 bool state = false;
Glenn Kastenbc1d77b2012-01-12 16:38:12 -0800326 AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 return state;
328}
329
Jean-Michel Trivid6770542012-10-10 12:03:41 -0700330static jboolean
Jean-Michel Trivi679d5042013-02-04 16:24:09 -0800331android_media_AudioSystem_isStreamActiveRemotely(JNIEnv *env, jobject thiz, jint stream,
332 jint inPastMs)
333{
334 bool state = false;
335 AudioSystem::isStreamActiveRemotely((audio_stream_type_t) stream, &state, inPastMs);
336 return state;
337}
338
339static jboolean
Jean-Michel Trivid6770542012-10-10 12:03:41 -0700340android_media_AudioSystem_isSourceActive(JNIEnv *env, jobject thiz, jint source)
341{
342 bool state = false;
343 AudioSystem::isSourceActive((audio_source_t) source, &state);
344 return state;
345}
346
Ashok Bhat075e9a12014-01-06 13:45:09 +0000347static jint
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -0700348android_media_AudioSystem_newAudioSessionId(JNIEnv *env, jobject thiz)
349{
Glenn Kasten211d9052016-02-26 16:22:40 -0800350 return AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -0700351}
352
353static jint
Jean-Michel Trivi292a6a42016-12-01 08:32:15 -0800354android_media_AudioSystem_newAudioPlayerId(JNIEnv *env, jobject thiz)
355{
356 return AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_PLAYER);
357}
358
359static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700360android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361{
Eric Laurenta553c252009-07-17 12:17:14 -0700362 const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
363 String8 c_keyValuePairs8;
364 if (keyValuePairs) {
Dan Albert66987492014-11-20 11:41:21 -0800365 c_keyValuePairs8 = String8(
366 reinterpret_cast<const char16_t*>(c_keyValuePairs),
367 env->GetStringLength(keyValuePairs));
Eric Laurenta553c252009-07-17 12:17:14 -0700368 env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
369 }
Glenn Kastenc94752a2013-12-19 12:40:33 -0800370 int status = check_AudioSystem_Command(AudioSystem::setParameters(c_keyValuePairs8));
Ashok Bhat075e9a12014-01-06 13:45:09 +0000371 return (jint) status;
Eric Laurenta553c252009-07-17 12:17:14 -0700372}
373
374static jstring
375android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
376{
377 const jchar* c_keys = env->GetStringCritical(keys, 0);
378 String8 c_keys8;
379 if (keys) {
Dan Albert66987492014-11-20 11:41:21 -0800380 c_keys8 = String8(reinterpret_cast<const char16_t*>(c_keys),
381 env->GetStringLength(keys));
Eric Laurenta553c252009-07-17 12:17:14 -0700382 env->ReleaseStringCritical(keys, c_keys);
383 }
Glenn Kastenc94752a2013-12-19 12:40:33 -0800384 return env->NewStringUTF(AudioSystem::getParameters(c_keys8).string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385}
386
Glenn Kastened0079d2011-04-04 10:50:50 -0700387static void
388android_media_AudioSystem_error_callback(status_t err)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389{
Eric Laurent539719a2013-07-18 14:08:00 -0700390 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent0e7a4d92010-10-15 12:33:16 -0700391 if (env == NULL) {
392 return;
393 }
394
Glenn Kastened0079d2011-04-04 10:50:50 -0700395 jclass clazz = env->FindClass(kClassPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396
Eric Laurentdfb881f2013-07-18 14:41:39 -0700397 env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz,
398 "errorCallbackFromNative","(I)V"),
399 check_AudioSystem_Command(err));
Viorel Sumanb637ccf2014-05-30 16:51:07 +0300400
401 env->DeleteLocalRef(clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402}
403
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700404static void
405android_media_AudioSystem_dyn_policy_callback(int event, String8 regId, int val)
406{
407 JNIEnv *env = AndroidRuntime::getJNIEnv();
408 if (env == NULL) {
409 return;
410 }
411
412 jclass clazz = env->FindClass(kClassPathName);
413 const char* zechars = regId.string();
414 jstring zestring = env->NewStringUTF(zechars);
415
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800416 env->CallStaticVoidMethod(clazz, gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative,
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700417 event, zestring, val);
418
419 env->ReleaseStringUTFChars(zestring, zechars);
420 env->DeleteLocalRef(clazz);
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800421}
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700422
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800423static void
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800424android_media_AudioSystem_recording_callback(int event,
425 const record_client_info_t *clientInfo,
426 const audio_config_base_t *clientConfig,
427 std::vector<effect_descriptor_t> clientEffects,
428 const audio_config_base_t *deviceConfig,
429 std::vector<effect_descriptor_t> effects __unused,
430 audio_patch_handle_t patchHandle,
431 audio_source_t source)
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800432{
433 JNIEnv *env = AndroidRuntime::getJNIEnv();
434 if (env == NULL) {
435 return;
436 }
Jean-Michel Trivi66ffacf2017-02-04 17:25:31 -0800437 if (clientInfo == NULL || clientConfig == NULL || deviceConfig == NULL) {
438 ALOGE("Unexpected null client/device info or configurations in recording callback");
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800439 return;
440 }
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800441
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800442 // create an array for 2*3 integers to store the record configurations (client + device)
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800443 // plus 1 integer for the patch handle
444 const int REC_PARAM_SIZE = 7;
445 jintArray recParamArray = env->NewIntArray(REC_PARAM_SIZE);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800446 if (recParamArray == NULL) {
447 ALOGE("recording callback: Couldn't allocate int array for configuration data");
448 return;
449 }
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800450 jint recParamData[REC_PARAM_SIZE];
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800451 recParamData[0] = (jint) audioFormatFromNative(clientConfig->format);
452 // FIXME this doesn't support index-based masks
453 recParamData[1] = (jint) inChannelMaskFromNative(clientConfig->channel_mask);
454 recParamData[2] = (jint) clientConfig->sample_rate;
455 recParamData[3] = (jint) audioFormatFromNative(deviceConfig->format);
456 // FIXME this doesn't support index-based masks
457 recParamData[4] = (jint) inChannelMaskFromNative(deviceConfig->channel_mask);
458 recParamData[5] = (jint) deviceConfig->sample_rate;
Jean-Michel Trivi8ab72802016-02-25 16:31:45 -0800459 recParamData[6] = (jint) patchHandle;
460 env->SetIntArrayRegion(recParamArray, 0, REC_PARAM_SIZE, recParamData);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800461
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800462 jobjectArray jClientEffects;
463 convertAudioEffectDescriptorVectorFromNative(env, &jClientEffects, clientEffects);
464
465 jobjectArray jEffects;
466 convertAudioEffectDescriptorVectorFromNative(env, &jEffects, effects);
467
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800468 // callback into java
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -0800469 jclass clazz = env->FindClass(kClassPathName);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800470
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800471 env->CallStaticVoidMethod(clazz,
472 gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative,
473 event, (jint) clientInfo->uid, clientInfo->session,
474 clientInfo->source, clientInfo->port_id, clientInfo->silenced,
475 recParamArray, jClientEffects, jEffects, source);
476 env->DeleteLocalRef(clazz);
Jean-Michel Trivi33fd8162016-02-22 10:52:41 -0800477 env->DeleteLocalRef(recParamArray);
Eric Laurentc7a0cdf2018-11-30 12:16:52 -0800478 env->DeleteLocalRef(jClientEffects);
479 env->DeleteLocalRef(jEffects);
Jean-Michel Trivi5a561092015-04-23 18:48:08 -0700480}
481
Ashok Bhat075e9a12014-01-06 13:45:09 +0000482static jint
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -0800483android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name,
Eric Laurent1d43aec2019-01-16 18:24:08 -0800484 jint codec)
Eric Laurenta553c252009-07-17 12:17:14 -0700485{
486 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Paul McLean10804eb2015-01-28 11:16:35 -0800487 const char *c_name = env->GetStringUTFChars(device_name, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700488 int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
489 static_cast <audio_policy_dev_state_t>(state),
Eric Laurent1d43aec2019-01-16 18:24:08 -0800490 c_address, c_name,
491 static_cast <audio_format_t>(codec)));
Eric Laurenta553c252009-07-17 12:17:14 -0700492 env->ReleaseStringUTFChars(device_address, c_address);
Paul McLean10804eb2015-01-28 11:16:35 -0800493 env->ReleaseStringUTFChars(device_name, c_name);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000494 return (jint) status;
Eric Laurenta553c252009-07-17 12:17:14 -0700495}
496
Ashok Bhat075e9a12014-01-06 13:45:09 +0000497static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700498android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
499{
500 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700501 int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
Eric Laurenta553c252009-07-17 12:17:14 -0700502 c_address));
503 env->ReleaseStringUTFChars(device_address, c_address);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000504 return (jint) state;
Eric Laurenta553c252009-07-17 12:17:14 -0700505}
506
Ashok Bhat075e9a12014-01-06 13:45:09 +0000507static jint
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -0800508android_media_AudioSystem_handleDeviceConfigChange(JNIEnv *env, jobject thiz, jint device, jstring device_address, jstring device_name,
Eric Laurent1d43aec2019-01-16 18:24:08 -0800509 jint codec)
Pavlin Radoslavov44a4ef02016-12-21 12:05:51 -0800510{
511 const char *c_address = env->GetStringUTFChars(device_address, NULL);
512 const char *c_name = env->GetStringUTFChars(device_name, NULL);
513 int status = check_AudioSystem_Command(AudioSystem::handleDeviceConfigChange(static_cast <audio_devices_t>(device),
Eric Laurent1d43aec2019-01-16 18:24:08 -0800514 c_address, c_name, static_cast <audio_format_t>(codec)));
Pavlin Radoslavov44a4ef02016-12-21 12:05:51 -0800515 env->ReleaseStringUTFChars(device_address, c_address);
516 env->ReleaseStringUTFChars(device_name, c_name);
517 return (jint) status;
518}
519
520static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700521android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
522{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000523 return (jint) check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state));
Eric Laurenta553c252009-07-17 12:17:14 -0700524}
525
Ashok Bhat075e9a12014-01-06 13:45:09 +0000526static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700527android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
528{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000529 return (jint) check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700530 static_cast <audio_policy_forced_cfg_t>(config)));
Eric Laurenta553c252009-07-17 12:17:14 -0700531}
532
Ashok Bhat075e9a12014-01-06 13:45:09 +0000533static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700534android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
535{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000536 return static_cast <jint>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
Eric Laurenta553c252009-07-17 12:17:14 -0700537}
538
Ashok Bhat075e9a12014-01-06 13:45:09 +0000539static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700540android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
541{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000542 return (jint) check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
Eric Laurenta553c252009-07-17 12:17:14 -0700543 indexMin,
544 indexMax));
545}
546
Ashok Bhat075e9a12014-01-06 13:45:09 +0000547static jint
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800548android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
549 jobject thiz,
550 jint stream,
551 jint index,
552 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700553{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000554 return (jint) check_AudioSystem_Command(
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800555 AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
556 index,
557 (audio_devices_t)device));
Eric Laurenta553c252009-07-17 12:17:14 -0700558}
559
Ashok Bhat075e9a12014-01-06 13:45:09 +0000560static jint
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800561android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env,
562 jobject thiz,
563 jint stream,
564 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700565{
566 int index;
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800567 if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
568 &index,
569 (audio_devices_t)device)
570 != NO_ERROR) {
Eric Laurenta553c252009-07-17 12:17:14 -0700571 index = -1;
572 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000573 return (jint) index;
Eric Laurenta553c252009-07-17 12:17:14 -0700574}
575
Ashok Bhat075e9a12014-01-06 13:45:09 +0000576static jint
François Gaffieebb67d02018-09-14 15:05:04 +0200577android_media_AudioSystem_setVolumeIndexForAttributes(JNIEnv *env,
578 jobject thiz,
579 jobject jaa,
580 jint index,
581 jint device)
582{
583 // read the AudioAttributes values
584 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
585 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
586 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
587 return jStatus;
588 }
589 return (jint) check_AudioSystem_Command(
590 AudioSystem::setVolumeIndexForAttributes(*(paa.get()), index, (audio_devices_t)device));
591}
592
593static jint
594android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env,
595 jobject thiz,
596 jobject jaa,
597 jint device)
598{
599 // read the AudioAttributes values
600 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
601 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
602 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
603 return jStatus;
604 }
605 int index;
606 if (AudioSystem::getVolumeIndexForAttributes(*(paa.get()), index, (audio_devices_t)device)
607 != NO_ERROR) {
608 index = -1;
609 }
610 return (jint) index;
611}
612
613static jint
614android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env,
615 jobject thiz,
616 jobject jaa)
617{
618 // read the AudioAttributes values
619 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
620 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
621 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
622 return jStatus;
623 }
624 int index;
625 if (AudioSystem::getMinVolumeIndexForAttributes(*(paa.get()), index)
626 != NO_ERROR) {
627 index = -1;
628 }
629 return (jint) index;
630}
631
632static jint
633android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env,
634 jobject thiz,
635 jobject jaa)
636{
637 // read the AudioAttributes values
638 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
639 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
640 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
641 return jStatus;
642 }
643 int index;
644 if (AudioSystem::getMaxVolumeIndexForAttributes(*(paa.get()), index)
645 != NO_ERROR) {
646 index = -1;
647 }
648 return (jint) index;
649}
650
651static jint
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400652android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
653{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000654 return (jint) check_AudioSystem_Command(AudioSystem::setMasterVolume(value));
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400655}
656
657static jfloat
658android_media_AudioSystem_getMasterVolume(JNIEnv *env, jobject thiz)
659{
660 float value;
661 if (AudioSystem::getMasterVolume(&value) != NO_ERROR) {
662 value = -1.0;
663 }
664 return value;
665}
666
Ashok Bhat075e9a12014-01-06 13:45:09 +0000667static jint
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400668android_media_AudioSystem_setMasterMute(JNIEnv *env, jobject thiz, jboolean mute)
669{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000670 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMute(mute));
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400671}
672
Vladimir Markoc1bcdbb2014-10-29 20:34:15 +0000673static jboolean
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400674android_media_AudioSystem_getMasterMute(JNIEnv *env, jobject thiz)
675{
676 bool mute;
677 if (AudioSystem::getMasterMute(&mute) != NO_ERROR) {
678 mute = false;
679 }
680 return mute;
681}
682
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800683static jint
Andy Hungf04b84d2015-12-18 17:33:27 -0800684android_media_AudioSystem_setMasterMono(JNIEnv *env, jobject thiz, jboolean mono)
685{
686 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMono(mono));
687}
688
689static jboolean
690android_media_AudioSystem_getMasterMono(JNIEnv *env, jobject thiz)
691{
692 bool mono;
693 if (AudioSystem::getMasterMono(&mono) != NO_ERROR) {
694 mono = false;
695 }
696 return mono;
697}
698
699static jint
Edward Savage-Jones35c292f2017-01-13 09:04:34 +0100700android_media_AudioSystem_setMasterBalance(JNIEnv *env, jobject thiz, jfloat balance)
701{
702 return (jint) check_AudioSystem_Command(AudioSystem::setMasterBalance(balance));
703}
704
705static jfloat
706android_media_AudioSystem_getMasterBalance(JNIEnv *env, jobject thiz)
707{
708 float balance;
709 const status_t status = AudioSystem::getMasterBalance(&balance);
710 if (status != NO_ERROR) {
711 ALOGW("%s getMasterBalance error %d, returning 0.f, audioserver down?", __func__, status);
712 balance = 0.f;
713 }
714 return balance;
715}
716
717static jint
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800718android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
719{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700720 return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800721}
722
Glenn Kastenc6c43652012-09-24 17:32:30 -0700723static jint
724android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz)
725{
726 return (jint) AudioSystem::getPrimaryOutputSamplingRate();
727}
728
729static jint
730android_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv *env, jobject clazz)
731{
732 return (jint) AudioSystem::getPrimaryOutputFrameCount();
733}
734
Oliver Woodman61dcdf32013-06-26 12:43:36 +0100735static jint
736android_media_AudioSystem_getOutputLatency(JNIEnv *env, jobject clazz, jint stream)
737{
738 uint32_t afLatency;
739 if (AudioSystem::getOutputLatency(&afLatency, static_cast <audio_stream_type_t>(stream))
740 != NO_ERROR) {
741 afLatency = -1;
742 }
743 return (jint) afLatency;
744}
745
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700746static jint
Andy Hung79583582018-01-23 13:58:02 -0800747android_media_AudioSystem_setLowRamDevice(
748 JNIEnv *env, jobject clazz, jboolean isLowRamDevice, jlong totalMemory)
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700749{
Andy Hung79583582018-01-23 13:58:02 -0800750 return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice, (int64_t) totalMemory);
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700751}
752
Ashok Bhat075e9a12014-01-06 13:45:09 +0000753static jint
Eric Laurentdfb881f2013-07-18 14:41:39 -0700754android_media_AudioSystem_checkAudioFlinger(JNIEnv *env, jobject clazz)
755{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000756 return (jint) check_AudioSystem_Command(AudioSystem::checkAudioFlinger());
Eric Laurentdfb881f2013-07-18 14:41:39 -0700757}
758
Eric Laurentb69681c2014-05-19 19:02:51 -0700759
760static bool useInChannelMask(audio_port_type_t type, audio_port_role_t role)
761{
762 return ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) ||
763 ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK));
764}
765
Eric Laurent3a241992014-05-19 19:33:26 -0700766static void convertAudioGainConfigToNative(JNIEnv *env,
767 struct audio_gain_config *nAudioGainConfig,
768 const jobject jAudioGainConfig,
769 bool useInMask)
770{
771 nAudioGainConfig->index = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mIndex);
772 nAudioGainConfig->mode = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mMode);
773 ALOGV("convertAudioGainConfigToNative got gain index %d", nAudioGainConfig->index);
774 jint jMask = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mChannelMask);
775 audio_channel_mask_t nMask;
776 if (useInMask) {
777 nMask = inChannelMaskToNative(jMask);
778 ALOGV("convertAudioGainConfigToNative IN mask java %x native %x", jMask, nMask);
779 } else {
780 nMask = outChannelMaskToNative(jMask);
781 ALOGV("convertAudioGainConfigToNative OUT mask java %x native %x", jMask, nMask);
782 }
783 nAudioGainConfig->channel_mask = nMask;
784 nAudioGainConfig->ramp_duration_ms = env->GetIntField(jAudioGainConfig,
785 gAudioGainConfigFields.mRampDurationMs);
786 jintArray jValues = (jintArray)env->GetObjectField(jAudioGainConfig,
787 gAudioGainConfigFields.mValues);
788 int *nValues = env->GetIntArrayElements(jValues, NULL);
789 size_t size = env->GetArrayLength(jValues);
790 memcpy(nAudioGainConfig->values, nValues, size * sizeof(int));
791 env->DeleteLocalRef(jValues);
792}
793
Eric Laurentb69681c2014-05-19 19:02:51 -0700794static jint convertAudioPortConfigToNative(JNIEnv *env,
795 struct audio_port_config *nAudioPortConfig,
Eric Laurent6368a7d2014-11-19 12:18:32 -0800796 const jobject jAudioPortConfig,
797 bool useConfigMask)
Eric Laurentb69681c2014-05-19 19:02:51 -0700798{
799 jobject jAudioPort = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mPort);
800 jobject jHandle = env->GetObjectField(jAudioPort, gAudioPortFields.mHandle);
801 nAudioPortConfig->id = env->GetIntField(jHandle, gAudioHandleFields.mId);
802 nAudioPortConfig->role = (audio_port_role_t)env->GetIntField(jAudioPort,
803 gAudioPortFields.mRole);
804 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
805 nAudioPortConfig->type = AUDIO_PORT_TYPE_DEVICE;
806 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
807 nAudioPortConfig->type = AUDIO_PORT_TYPE_MIX;
808 } else {
809 env->DeleteLocalRef(jAudioPort);
810 env->DeleteLocalRef(jHandle);
811 return (jint)AUDIO_JAVA_ERROR;
812 }
813 ALOGV("convertAudioPortConfigToNative handle %d role %d type %d",
814 nAudioPortConfig->id, nAudioPortConfig->role, nAudioPortConfig->type);
815
Eric Laurent6368a7d2014-11-19 12:18:32 -0800816 unsigned int configMask = 0;
817
Eric Laurentb69681c2014-05-19 19:02:51 -0700818 nAudioPortConfig->sample_rate = env->GetIntField(jAudioPortConfig,
819 gAudioPortConfigFields.mSamplingRate);
Eric Laurent6368a7d2014-11-19 12:18:32 -0800820 if (nAudioPortConfig->sample_rate != 0) {
821 configMask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
822 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700823
824 bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role);
825 audio_channel_mask_t nMask;
826 jint jMask = env->GetIntField(jAudioPortConfig,
827 gAudioPortConfigFields.mChannelMask);
828 if (useInMask) {
829 nMask = inChannelMaskToNative(jMask);
830 ALOGV("convertAudioPortConfigToNative IN mask java %x native %x", jMask, nMask);
831 } else {
832 nMask = outChannelMaskToNative(jMask);
833 ALOGV("convertAudioPortConfigToNative OUT mask java %x native %x", jMask, nMask);
834 }
835 nAudioPortConfig->channel_mask = nMask;
Eric Laurent6368a7d2014-11-19 12:18:32 -0800836 if (nAudioPortConfig->channel_mask != AUDIO_CHANNEL_NONE) {
837 configMask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
838 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700839
840 jint jFormat = env->GetIntField(jAudioPortConfig, gAudioPortConfigFields.mFormat);
841 audio_format_t nFormat = audioFormatToNative(jFormat);
842 ALOGV("convertAudioPortConfigToNative format %d native %d", jFormat, nFormat);
843 nAudioPortConfig->format = nFormat;
Eric Laurent6368a7d2014-11-19 12:18:32 -0800844 if (nAudioPortConfig->format != AUDIO_FORMAT_DEFAULT &&
845 nAudioPortConfig->format != AUDIO_FORMAT_INVALID) {
846 configMask |= AUDIO_PORT_CONFIG_FORMAT;
847 }
848
Eric Laurentb69681c2014-05-19 19:02:51 -0700849 jobject jGain = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mGain);
850 if (jGain != NULL) {
Eric Laurent3a241992014-05-19 19:33:26 -0700851 convertAudioGainConfigToNative(env, &nAudioPortConfig->gain, jGain, useInMask);
Eric Laurentb69681c2014-05-19 19:02:51 -0700852 env->DeleteLocalRef(jGain);
Eric Laurent6368a7d2014-11-19 12:18:32 -0800853 configMask |= AUDIO_PORT_CONFIG_GAIN;
Eric Laurentb69681c2014-05-19 19:02:51 -0700854 } else {
855 ALOGV("convertAudioPortConfigToNative no gain");
856 nAudioPortConfig->gain.index = -1;
857 }
Eric Laurent6368a7d2014-11-19 12:18:32 -0800858 if (useConfigMask) {
859 nAudioPortConfig->config_mask = env->GetIntField(jAudioPortConfig,
860 gAudioPortConfigFields.mConfigMask);
861 } else {
862 nAudioPortConfig->config_mask = configMask;
863 }
Eric Laurentb69681c2014-05-19 19:02:51 -0700864 env->DeleteLocalRef(jAudioPort);
865 env->DeleteLocalRef(jHandle);
866 return (jint)AUDIO_JAVA_SUCCESS;
867}
868
Hongwei Wangf44a5682018-08-24 10:37:56 -0700869/**
870 * Extends convertAudioPortConfigToNative with extra device port info.
871 * Mix / Session specific info is not fulfilled.
872 */
873static jint convertAudioPortConfigToNativeWithDevicePort(JNIEnv *env,
874 struct audio_port_config *nAudioPortConfig,
875 const jobject jAudioPortConfig,
876 bool useConfigMask)
877{
878 jint jStatus = convertAudioPortConfigToNative(env,
879 nAudioPortConfig,
880 jAudioPortConfig,
881 useConfigMask);
882 if (jStatus != AUDIO_JAVA_SUCCESS) {
883 return jStatus;
884 }
885 // Supports AUDIO_PORT_TYPE_DEVICE only
886 if (nAudioPortConfig->type != AUDIO_PORT_TYPE_DEVICE) {
887 return (jint)AUDIO_JAVA_BAD_VALUE;
888 }
889
890 jobject jAudioDevicePort = env->GetObjectField(jAudioPortConfig,
891 gAudioPortConfigFields.mPort);
892 nAudioPortConfig->ext.device.type = env->GetIntField(jAudioDevicePort,
893 gAudioPortFields.mType);
894 jstring jDeviceAddress = (jstring)env->GetObjectField(jAudioDevicePort,
895 gAudioPortFields.mAddress);
896 const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
897 strncpy(nAudioPortConfig->ext.device.address,
898 nDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN - 1);
899 env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
900 env->DeleteLocalRef(jDeviceAddress);
901 env->DeleteLocalRef(jAudioDevicePort);
902 return jStatus;
903}
904
Eric Laurentb69681c2014-05-19 19:02:51 -0700905static jint convertAudioPortConfigFromNative(JNIEnv *env,
906 jobject jAudioPort,
907 jobject *jAudioPortConfig,
908 const struct audio_port_config *nAudioPortConfig)
909{
910 jint jStatus = AUDIO_JAVA_SUCCESS;
911 jobject jAudioGainConfig = NULL;
912 jobject jAudioGain = NULL;
913 jintArray jGainValues;
914 bool audioportCreated = false;
915
916 ALOGV("convertAudioPortConfigFromNative jAudioPort %p", jAudioPort);
917
918 if (jAudioPort == NULL) {
919 jobject jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
920 nAudioPortConfig->id);
921
922 ALOGV("convertAudioPortConfigFromNative handle %d is a %s", nAudioPortConfig->id,
923 nAudioPortConfig->type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix");
924
925 if (jHandle == NULL) {
926 return (jint)AUDIO_JAVA_ERROR;
927 }
928 // create dummy port and port config objects with just the correct handle
929 // and configuration data. The actual AudioPortConfig objects will be
930 // constructed by java code with correct class type (device, mix etc...)
931 // and reference to AudioPort instance in this client
932 jAudioPort = env->NewObject(gAudioPortClass, gAudioPortCstor,
Paul McLeanf29e5f32015-06-15 10:19:22 -0700933 jHandle, // handle
934 0, // role
935 NULL, // name
936 NULL, // samplingRates
937 NULL, // channelMasks
938 NULL, // channelIndexMasks
939 NULL, // formats
940 NULL); // gains
Eric Laurentb69681c2014-05-19 19:02:51 -0700941 env->DeleteLocalRef(jHandle);
942 if (jAudioPort == NULL) {
943 return (jint)AUDIO_JAVA_ERROR;
944 }
945 ALOGV("convertAudioPortConfigFromNative jAudioPort created for handle %d",
946 nAudioPortConfig->id);
947
948 audioportCreated = true;
949 }
950
951 bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role);
952
953 audio_channel_mask_t nMask;
954 jint jMask;
955
956 int gainIndex = nAudioPortConfig->gain.index;
957 if (gainIndex >= 0) {
958 ALOGV("convertAudioPortConfigFromNative gain found with index %d mode %x",
959 gainIndex, nAudioPortConfig->gain.mode);
960 if (audioportCreated) {
961 ALOGV("convertAudioPortConfigFromNative creating gain");
962 jAudioGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
963 gainIndex,
964 0,
965 0,
966 0,
967 0,
968 0,
969 0,
970 0,
971 0);
972 if (jAudioGain == NULL) {
973 ALOGV("convertAudioPortConfigFromNative creating gain FAILED");
974 jStatus = (jint)AUDIO_JAVA_ERROR;
975 goto exit;
976 }
977 } else {
978 ALOGV("convertAudioPortConfigFromNative reading gain from port");
979 jobjectArray jGains = (jobjectArray)env->GetObjectField(jAudioPort,
980 gAudioPortFields.mGains);
981 if (jGains == NULL) {
982 ALOGV("convertAudioPortConfigFromNative could not get gains from port");
983 jStatus = (jint)AUDIO_JAVA_ERROR;
984 goto exit;
985 }
986 jAudioGain = env->GetObjectArrayElement(jGains, gainIndex);
987 env->DeleteLocalRef(jGains);
988 if (jAudioGain == NULL) {
989 ALOGV("convertAudioPortConfigFromNative could not get gain at index %d", gainIndex);
990 jStatus = (jint)AUDIO_JAVA_ERROR;
991 goto exit;
992 }
993 }
Eric Laurent0078c7c2014-06-04 09:49:52 -0700994 int numValues;
995 if (useInMask) {
996 numValues = audio_channel_count_from_in_mask(nAudioPortConfig->gain.channel_mask);
997 } else {
998 numValues = audio_channel_count_from_out_mask(nAudioPortConfig->gain.channel_mask);
999 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001000 jGainValues = env->NewIntArray(numValues);
1001 if (jGainValues == NULL) {
1002 ALOGV("convertAudioPortConfigFromNative could not create gain values %d", numValues);
1003 jStatus = (jint)AUDIO_JAVA_ERROR;
1004 goto exit;
1005 }
1006 env->SetIntArrayRegion(jGainValues, 0, numValues,
1007 nAudioPortConfig->gain.values);
1008
1009 nMask = nAudioPortConfig->gain.channel_mask;
1010 if (useInMask) {
1011 jMask = inChannelMaskFromNative(nMask);
1012 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1013 } else {
1014 jMask = outChannelMaskFromNative(nMask);
1015 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1016 }
1017
1018 jAudioGainConfig = env->NewObject(gAudioGainConfigClass,
1019 gAudioGainConfigCstor,
1020 gainIndex,
1021 jAudioGain,
1022 nAudioPortConfig->gain.mode,
1023 jMask,
1024 jGainValues,
1025 nAudioPortConfig->gain.ramp_duration_ms);
1026 env->DeleteLocalRef(jGainValues);
1027 if (jAudioGainConfig == NULL) {
1028 ALOGV("convertAudioPortConfigFromNative could not create gain config");
1029 jStatus = (jint)AUDIO_JAVA_ERROR;
1030 goto exit;
1031 }
1032 }
1033 jclass clazz;
1034 jmethodID methodID;
1035 if (audioportCreated) {
1036 clazz = gAudioPortConfigClass;
1037 methodID = gAudioPortConfigCstor;
1038 ALOGV("convertAudioPortConfigFromNative building a generic port config");
1039 } else {
1040 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
1041 clazz = gAudioDevicePortConfigClass;
1042 methodID = gAudioDevicePortConfigCstor;
1043 ALOGV("convertAudioPortConfigFromNative building a device config");
1044 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
1045 clazz = gAudioMixPortConfigClass;
1046 methodID = gAudioMixPortConfigCstor;
1047 ALOGV("convertAudioPortConfigFromNative building a mix config");
1048 } else {
1049 jStatus = (jint)AUDIO_JAVA_ERROR;
1050 goto exit;
1051 }
1052 }
1053 nMask = nAudioPortConfig->channel_mask;
1054 if (useInMask) {
1055 jMask = inChannelMaskFromNative(nMask);
1056 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1057 } else {
1058 jMask = outChannelMaskFromNative(nMask);
1059 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1060 }
1061
1062 *jAudioPortConfig = env->NewObject(clazz, methodID,
1063 jAudioPort,
1064 nAudioPortConfig->sample_rate,
1065 jMask,
1066 audioFormatFromNative(nAudioPortConfig->format),
1067 jAudioGainConfig);
1068 if (*jAudioPortConfig == NULL) {
1069 ALOGV("convertAudioPortConfigFromNative could not create new port config");
1070 jStatus = (jint)AUDIO_JAVA_ERROR;
1071 } else {
1072 ALOGV("convertAudioPortConfigFromNative OK");
1073 }
1074
1075exit:
1076 if (audioportCreated) {
1077 env->DeleteLocalRef(jAudioPort);
1078 if (jAudioGain != NULL) {
1079 env->DeleteLocalRef(jAudioGain);
1080 }
1081 }
1082 if (jAudioGainConfig != NULL) {
1083 env->DeleteLocalRef(jAudioGainConfig);
1084 }
1085 return jStatus;
1086}
1087
Paul McLean4e5e9e92015-06-17 10:10:11 -07001088static bool hasFormat(int* formats, size_t size, int format) {
1089 for (size_t index = 0; index < size; index++) {
1090 if (formats[index] == format) {
1091 return true; // found
1092 }
1093 }
1094 return false; // not found
1095}
1096
Andy Hung737d9fb2016-08-16 18:38:49 -07001097// TODO: pull out to separate file
1098template <typename T, size_t N>
1099static constexpr size_t array_size(const T (&)[N]) {
1100 return N;
1101}
1102
Eric Laurentb69681c2014-05-19 19:02:51 -07001103static jint convertAudioPortFromNative(JNIEnv *env,
1104 jobject *jAudioPort, const struct audio_port *nAudioPort)
1105{
1106 jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
1107 jintArray jSamplingRates = NULL;
1108 jintArray jChannelMasks = NULL;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001109 jintArray jChannelIndexMasks = NULL;
Paul McLean4e5e9e92015-06-17 10:10:11 -07001110 int* cFormats = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001111 jintArray jFormats = NULL;
1112 jobjectArray jGains = NULL;
1113 jobject jHandle = NULL;
xiaomi/hanli82840c42017-07-19 18:53:03 +08001114 jobject jAudioPortConfig = NULL;
Paul McLean10804eb2015-01-28 11:16:35 -08001115 jstring jDeviceName = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001116 bool useInMask;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001117 size_t numPositionMasks = 0;
1118 size_t numIndexMasks = 0;
Paul McLean2db94372015-06-18 12:47:34 -07001119 size_t numUniqueFormats = 0;
1120
Paul McLean10804eb2015-01-28 11:16:35 -08001121 ALOGV("convertAudioPortFromNative id %d role %d type %d name %s",
1122 nAudioPort->id, nAudioPort->role, nAudioPort->type, nAudioPort->name);
Eric Laurentb69681c2014-05-19 19:02:51 -07001123
Andy Hung737d9fb2016-08-16 18:38:49 -07001124 // Verify audio port array count info.
1125 if (nAudioPort->num_sample_rates > array_size(nAudioPort->sample_rates)
1126 || nAudioPort->num_channel_masks > array_size(nAudioPort->channel_masks)
1127 || nAudioPort->num_formats > array_size(nAudioPort->formats)
1128 || nAudioPort->num_gains > array_size(nAudioPort->gains)) {
1129
1130 std::stringstream ss;
1131 ss << "convertAudioPortFromNative array count out of bounds:"
1132 << " num_sample_rates " << nAudioPort->num_sample_rates
1133 << " num_channel_masks " << nAudioPort->num_channel_masks
1134 << " num_formats " << nAudioPort->num_formats
1135 << " num_gains " << nAudioPort->num_gains
1136 ;
1137 std::string s = ss.str();
1138
1139 // Prefer to log through Java wtf instead of native ALOGE.
1140 ScopedLocalRef<jclass> jLogClass(env, env->FindClass("android/util/Log"));
1141 jmethodID jWtfId = (jLogClass.get() == nullptr)
1142 ? nullptr
1143 : env->GetStaticMethodID(jLogClass.get(), "wtf",
1144 "(Ljava/lang/String;Ljava/lang/String;)I");
1145 if (jWtfId != nullptr) {
1146 ScopedLocalRef<jstring> jMessage(env, env->NewStringUTF(s.c_str()));
1147 ScopedLocalRef<jstring> jTag(env, env->NewStringUTF(LOG_TAG));
1148 (void)env->CallStaticIntMethod(jLogClass.get(), jWtfId, jTag.get(), jMessage.get());
1149 } else {
1150 ALOGE("%s", s.c_str());
1151 }
1152 jStatus = (jint)AUDIO_JAVA_ERROR;
1153 goto exit;
1154 }
1155
Eric Laurentb69681c2014-05-19 19:02:51 -07001156 jSamplingRates = env->NewIntArray(nAudioPort->num_sample_rates);
1157 if (jSamplingRates == NULL) {
1158 jStatus = (jint)AUDIO_JAVA_ERROR;
1159 goto exit;
1160 }
1161 if (nAudioPort->num_sample_rates) {
1162 env->SetIntArrayRegion(jSamplingRates, 0, nAudioPort->num_sample_rates,
1163 (jint *)nAudioPort->sample_rates);
1164 }
1165
Paul McLeanf29e5f32015-06-15 10:19:22 -07001166 // count up how many masks are positional and indexed
1167 for(size_t index = 0; index < nAudioPort->num_channel_masks; index++) {
1168 const audio_channel_mask_t mask = nAudioPort->channel_masks[index];
1169 if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1170 numIndexMasks++;
1171 } else {
1172 numPositionMasks++;
1173 }
1174 }
1175
1176 jChannelMasks = env->NewIntArray(numPositionMasks);
Eric Laurentb69681c2014-05-19 19:02:51 -07001177 if (jChannelMasks == NULL) {
1178 jStatus = (jint)AUDIO_JAVA_ERROR;
1179 goto exit;
1180 }
Paul McLeanf29e5f32015-06-15 10:19:22 -07001181 jChannelIndexMasks = env->NewIntArray(numIndexMasks);
1182 if (jChannelIndexMasks == NULL) {
1183 jStatus = (jint)AUDIO_JAVA_ERROR;
1184 goto exit;
1185 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001186 useInMask = useInChannelMask(nAudioPort->type, nAudioPort->role);
1187
Paul McLeanf29e5f32015-06-15 10:19:22 -07001188 // put the masks in the output arrays
1189 for (size_t maskIndex = 0, posMaskIndex = 0, indexedMaskIndex = 0;
1190 maskIndex < nAudioPort->num_channel_masks; maskIndex++) {
1191 const audio_channel_mask_t mask = nAudioPort->channel_masks[maskIndex];
1192 if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1193 jint jMask = audio_channel_mask_get_bits(mask);
1194 env->SetIntArrayRegion(jChannelIndexMasks, indexedMaskIndex++, 1, &jMask);
Eric Laurentb69681c2014-05-19 19:02:51 -07001195 } else {
Paul McLeanf29e5f32015-06-15 10:19:22 -07001196 jint jMask = useInMask ? inChannelMaskFromNative(mask)
1197 : outChannelMaskFromNative(mask);
1198 env->SetIntArrayRegion(jChannelMasks, posMaskIndex++, 1, &jMask);
Eric Laurentb69681c2014-05-19 19:02:51 -07001199 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001200 }
1201
Paul McLeanf29e5f32015-06-15 10:19:22 -07001202 // formats
Paul McLean2db94372015-06-18 12:47:34 -07001203 if (nAudioPort->num_formats != 0) {
1204 cFormats = new int[nAudioPort->num_formats];
1205 for (size_t index = 0; index < nAudioPort->num_formats; index++) {
1206 int format = audioFormatFromNative(nAudioPort->formats[index]);
1207 if (!hasFormat(cFormats, numUniqueFormats, format)) {
1208 cFormats[numUniqueFormats++] = format;
1209 }
Paul McLean4e5e9e92015-06-17 10:10:11 -07001210 }
1211 }
1212 jFormats = env->NewIntArray(numUniqueFormats);
Eric Laurentb69681c2014-05-19 19:02:51 -07001213 if (jFormats == NULL) {
1214 jStatus = (jint)AUDIO_JAVA_ERROR;
1215 goto exit;
1216 }
Paul McLean2db94372015-06-18 12:47:34 -07001217 if (numUniqueFormats != 0) {
1218 env->SetIntArrayRegion(jFormats, 0, numUniqueFormats, cFormats);
1219 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001220
Paul McLeanf29e5f32015-06-15 10:19:22 -07001221 // gains
Eric Laurentb69681c2014-05-19 19:02:51 -07001222 jGains = env->NewObjectArray(nAudioPort->num_gains,
1223 gAudioGainClass, NULL);
1224 if (jGains == NULL) {
1225 jStatus = (jint)AUDIO_JAVA_ERROR;
1226 goto exit;
1227 }
Paul McLeanf29e5f32015-06-15 10:19:22 -07001228
Eric Laurentb69681c2014-05-19 19:02:51 -07001229 for (size_t j = 0; j < nAudioPort->num_gains; j++) {
1230 audio_channel_mask_t nMask = nAudioPort->gains[j].channel_mask;
Paul McLeanf29e5f32015-06-15 10:19:22 -07001231 jint jMask;
Eric Laurentb69681c2014-05-19 19:02:51 -07001232 if (useInMask) {
1233 jMask = inChannelMaskFromNative(nMask);
1234 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1235 } else {
1236 jMask = outChannelMaskFromNative(nMask);
1237 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1238 }
1239
1240 jobject jGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
1241 j,
1242 nAudioPort->gains[j].mode,
1243 jMask,
1244 nAudioPort->gains[j].min_value,
1245 nAudioPort->gains[j].max_value,
1246 nAudioPort->gains[j].default_value,
1247 nAudioPort->gains[j].step_value,
1248 nAudioPort->gains[j].min_ramp_ms,
1249 nAudioPort->gains[j].max_ramp_ms);
1250 if (jGain == NULL) {
1251 jStatus = (jint)AUDIO_JAVA_ERROR;
1252 goto exit;
1253 }
1254 env->SetObjectArrayElement(jGains, j, jGain);
1255 env->DeleteLocalRef(jGain);
1256 }
1257
1258 jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1259 nAudioPort->id);
1260 if (jHandle == NULL) {
1261 jStatus = (jint)AUDIO_JAVA_ERROR;
1262 goto exit;
1263 }
1264
Paul McLean10804eb2015-01-28 11:16:35 -08001265 jDeviceName = env->NewStringUTF(nAudioPort->name);
1266
Eric Laurentb69681c2014-05-19 19:02:51 -07001267 if (nAudioPort->type == AUDIO_PORT_TYPE_DEVICE) {
1268 ALOGV("convertAudioPortFromNative is a device %08x", nAudioPort->ext.device.type);
1269 jstring jAddress = env->NewStringUTF(nAudioPort->ext.device.address);
1270 *jAudioPort = env->NewObject(gAudioDevicePortClass, gAudioDevicePortCstor,
Paul McLean10804eb2015-01-28 11:16:35 -08001271 jHandle, jDeviceName,
Paul McLeanf29e5f32015-06-15 10:19:22 -07001272 jSamplingRates, jChannelMasks, jChannelIndexMasks,
1273 jFormats, jGains,
Eric Laurentb69681c2014-05-19 19:02:51 -07001274 nAudioPort->ext.device.type, jAddress);
1275 env->DeleteLocalRef(jAddress);
1276 } else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) {
1277 ALOGV("convertAudioPortFromNative is a mix");
1278 *jAudioPort = env->NewObject(gAudioMixPortClass, gAudioMixPortCstor,
Eric Laurent4bcdba82015-05-01 11:37:49 -07001279 jHandle, nAudioPort->ext.mix.handle,
1280 nAudioPort->role, jDeviceName,
Paul McLeanf29e5f32015-06-15 10:19:22 -07001281 jSamplingRates, jChannelMasks, jChannelIndexMasks,
Eric Laurentb69681c2014-05-19 19:02:51 -07001282 jFormats, jGains);
1283 } else {
1284 ALOGE("convertAudioPortFromNative unknown nAudioPort type %d", nAudioPort->type);
1285 jStatus = (jint)AUDIO_JAVA_ERROR;
1286 goto exit;
1287 }
1288 if (*jAudioPort == NULL) {
1289 jStatus = (jint)AUDIO_JAVA_ERROR;
1290 goto exit;
1291 }
1292
Eric Laurentb69681c2014-05-19 19:02:51 -07001293 jStatus = convertAudioPortConfigFromNative(env,
1294 *jAudioPort,
1295 &jAudioPortConfig,
1296 &nAudioPort->active_config);
1297 if (jStatus != AUDIO_JAVA_SUCCESS) {
Andy Hung737d9fb2016-08-16 18:38:49 -07001298 goto exit;
Eric Laurentb69681c2014-05-19 19:02:51 -07001299 }
1300
1301 env->SetObjectField(*jAudioPort, gAudioPortFields.mActiveConfig, jAudioPortConfig);
1302
1303exit:
Paul McLean10804eb2015-01-28 11:16:35 -08001304 if (jDeviceName != NULL) {
1305 env->DeleteLocalRef(jDeviceName);
1306 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001307 if (jSamplingRates != NULL) {
1308 env->DeleteLocalRef(jSamplingRates);
1309 }
1310 if (jChannelMasks != NULL) {
1311 env->DeleteLocalRef(jChannelMasks);
1312 }
Paul McLean4e5e9e92015-06-17 10:10:11 -07001313 if (jChannelIndexMasks != NULL) {
1314 env->DeleteLocalRef(jChannelIndexMasks);
1315 }
1316 if (cFormats != NULL) {
1317 delete[] cFormats;
1318 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001319 if (jFormats != NULL) {
1320 env->DeleteLocalRef(jFormats);
1321 }
1322 if (jGains != NULL) {
1323 env->DeleteLocalRef(jGains);
1324 }
1325 if (jHandle != NULL) {
1326 env->DeleteLocalRef(jHandle);
1327 }
xiaomi/hanli82840c42017-07-19 18:53:03 +08001328 if (jAudioPortConfig != NULL) {
1329 env->DeleteLocalRef(jAudioPortConfig);
1330 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001331
1332 return jStatus;
1333}
1334
Eric Laurentb69681c2014-05-19 19:02:51 -07001335static jint
1336android_media_AudioSystem_listAudioPorts(JNIEnv *env, jobject clazz,
1337 jobject jPorts, jintArray jGeneration)
1338{
1339 ALOGV("listAudioPorts");
1340
1341 if (jPorts == NULL) {
1342 ALOGE("listAudioPorts NULL AudioPort ArrayList");
1343 return (jint)AUDIO_JAVA_BAD_VALUE;
1344 }
1345 if (!env->IsInstanceOf(jPorts, gArrayListClass)) {
1346 ALOGE("listAudioPorts not an arraylist");
1347 return (jint)AUDIO_JAVA_BAD_VALUE;
1348 }
1349
1350 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1351 return (jint)AUDIO_JAVA_BAD_VALUE;
1352 }
1353
1354 status_t status;
1355 unsigned int generation1;
1356 unsigned int generation;
1357 unsigned int numPorts;
1358 jint *nGeneration;
1359 struct audio_port *nPorts = NULL;
1360 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
Eric Laurentb36d1042016-04-14 18:00:38 -07001361 jint jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001362
1363 // get the port count and all the ports until they both return the same generation
1364 do {
1365 if (attempts-- < 0) {
1366 status = TIMED_OUT;
1367 break;
1368 }
1369
1370 numPorts = 0;
1371 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE,
1372 AUDIO_PORT_TYPE_NONE,
1373 &numPorts,
1374 NULL,
1375 &generation1);
Eric Laurentb36d1042016-04-14 18:00:38 -07001376 if (status != NO_ERROR) {
Eric Laurentb69681c2014-05-19 19:02:51 -07001377 ALOGE_IF(status != NO_ERROR, "AudioSystem::listAudioPorts error %d", status);
1378 break;
1379 }
Eric Laurentb36d1042016-04-14 18:00:38 -07001380 if (numPorts == 0) {
1381 jStatus = (jint)AUDIO_JAVA_SUCCESS;
1382 goto exit;
1383 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001384 nPorts = (struct audio_port *)realloc(nPorts, numPorts * sizeof(struct audio_port));
1385
1386 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE,
1387 AUDIO_PORT_TYPE_NONE,
1388 &numPorts,
1389 nPorts,
1390 &generation);
1391 ALOGV("listAudioPorts AudioSystem::listAudioPorts numPorts %d generation %d generation1 %d",
1392 numPorts, generation, generation1);
1393 } while (generation1 != generation && status == NO_ERROR);
1394
Eric Laurentb36d1042016-04-14 18:00:38 -07001395 jStatus = nativeToJavaStatus(status);
Eric Laurentb69681c2014-05-19 19:02:51 -07001396 if (jStatus != AUDIO_JAVA_SUCCESS) {
1397 goto exit;
1398 }
1399
Eric Laurentb69681c2014-05-19 19:02:51 -07001400 for (size_t i = 0; i < numPorts; i++) {
xiaomi/hanli82840c42017-07-19 18:53:03 +08001401 jobject jAudioPort = NULL;
Eric Laurentb69681c2014-05-19 19:02:51 -07001402 jStatus = convertAudioPortFromNative(env, &jAudioPort, &nPorts[i]);
1403 if (jStatus != AUDIO_JAVA_SUCCESS) {
1404 goto exit;
1405 }
1406 env->CallBooleanMethod(jPorts, gArrayListMethods.add, jAudioPort);
xiaomi/hanli82840c42017-07-19 18:53:03 +08001407 if (jAudioPort != NULL) {
1408 env->DeleteLocalRef(jAudioPort);
1409 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001410 }
1411
1412exit:
Eric Laurentb36d1042016-04-14 18:00:38 -07001413 nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1414 if (nGeneration == NULL) {
1415 jStatus = (jint)AUDIO_JAVA_ERROR;
1416 } else {
1417 nGeneration[0] = generation1;
1418 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1419 }
Eric Laurentb69681c2014-05-19 19:02:51 -07001420 free(nPorts);
1421 return jStatus;
1422}
1423
1424static int
1425android_media_AudioSystem_createAudioPatch(JNIEnv *env, jobject clazz,
1426 jobjectArray jPatches, jobjectArray jSources, jobjectArray jSinks)
1427{
1428 status_t status;
1429 jint jStatus;
1430
1431 ALOGV("createAudioPatch");
1432 if (jPatches == NULL || jSources == NULL || jSinks == NULL) {
1433 return (jint)AUDIO_JAVA_BAD_VALUE;
1434 }
1435
1436 if (env->GetArrayLength(jPatches) != 1) {
1437 return (jint)AUDIO_JAVA_BAD_VALUE;
1438 }
1439 jint numSources = env->GetArrayLength(jSources);
1440 if (numSources == 0 || numSources > AUDIO_PATCH_PORTS_MAX) {
1441 return (jint)AUDIO_JAVA_BAD_VALUE;
1442 }
1443
1444 jint numSinks = env->GetArrayLength(jSinks);
1445 if (numSinks == 0 || numSinks > AUDIO_PATCH_PORTS_MAX) {
1446 return (jint)AUDIO_JAVA_BAD_VALUE;
1447 }
1448
1449 audio_patch_handle_t handle = (audio_patch_handle_t)0;
1450 jobject jPatch = env->GetObjectArrayElement(jPatches, 0);
1451 jobject jPatchHandle = NULL;
1452 if (jPatch != NULL) {
1453 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1454 return (jint)AUDIO_JAVA_BAD_VALUE;
1455 }
1456 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1457 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1458 }
1459
Mikhail Naganov304eafc2018-05-23 16:54:12 -07001460 struct audio_patch nPatch = { .id = handle };
Eric Laurentb69681c2014-05-19 19:02:51 -07001461
Eric Laurentb69681c2014-05-19 19:02:51 -07001462 jobject jSource = NULL;
1463 jobject jSink = NULL;
1464
1465 for (jint i = 0; i < numSources; i++) {
1466 jSource = env->GetObjectArrayElement(jSources, i);
1467 if (!env->IsInstanceOf(jSource, gAudioPortConfigClass)) {
1468 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1469 goto exit;
1470 }
Eric Laurent6368a7d2014-11-19 12:18:32 -08001471 jStatus = convertAudioPortConfigToNative(env, &nPatch.sources[i], jSource, false);
Eric Laurentb69681c2014-05-19 19:02:51 -07001472 env->DeleteLocalRef(jSource);
1473 jSource = NULL;
1474 if (jStatus != AUDIO_JAVA_SUCCESS) {
1475 goto exit;
1476 }
1477 nPatch.num_sources++;
1478 }
1479
1480 for (jint i = 0; i < numSinks; i++) {
1481 jSink = env->GetObjectArrayElement(jSinks, i);
1482 if (!env->IsInstanceOf(jSink, gAudioPortConfigClass)) {
1483 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1484 goto exit;
1485 }
Eric Laurent6368a7d2014-11-19 12:18:32 -08001486 jStatus = convertAudioPortConfigToNative(env, &nPatch.sinks[i], jSink, false);
Eric Laurentb69681c2014-05-19 19:02:51 -07001487 env->DeleteLocalRef(jSink);
1488 jSink = NULL;
1489 if (jStatus != AUDIO_JAVA_SUCCESS) {
1490 goto exit;
1491 }
1492 nPatch.num_sinks++;
1493 }
1494
1495 ALOGV("AudioSystem::createAudioPatch");
1496 status = AudioSystem::createAudioPatch(&nPatch, &handle);
1497 ALOGV("AudioSystem::createAudioPatch() returned %d hande %d", status, handle);
1498
1499 jStatus = nativeToJavaStatus(status);
1500 if (jStatus != AUDIO_JAVA_SUCCESS) {
1501 goto exit;
1502 }
1503
1504 if (jPatchHandle == NULL) {
1505 jPatchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1506 handle);
1507 if (jPatchHandle == NULL) {
1508 jStatus = (jint)AUDIO_JAVA_ERROR;
1509 goto exit;
1510 }
1511 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor, jPatchHandle, jSources, jSinks);
1512 if (jPatch == NULL) {
1513 jStatus = (jint)AUDIO_JAVA_ERROR;
1514 goto exit;
1515 }
1516 env->SetObjectArrayElement(jPatches, 0, jPatch);
1517 } else {
1518 env->SetIntField(jPatchHandle, gAudioHandleFields.mId, handle);
1519 }
1520
1521exit:
1522 if (jPatchHandle != NULL) {
1523 env->DeleteLocalRef(jPatchHandle);
1524 }
1525 if (jPatch != NULL) {
1526 env->DeleteLocalRef(jPatch);
1527 }
1528 if (jSource != NULL) {
1529 env->DeleteLocalRef(jSource);
1530 }
1531 if (jSink != NULL) {
1532 env->DeleteLocalRef(jSink);
1533 }
1534 return jStatus;
1535}
1536
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001537static jint
Eric Laurentb69681c2014-05-19 19:02:51 -07001538android_media_AudioSystem_releaseAudioPatch(JNIEnv *env, jobject clazz,
1539 jobject jPatch)
1540{
1541 ALOGV("releaseAudioPatch");
1542 if (jPatch == NULL) {
1543 return (jint)AUDIO_JAVA_BAD_VALUE;
1544 }
1545
1546 audio_patch_handle_t handle = (audio_patch_handle_t)0;
1547 jobject jPatchHandle = NULL;
1548 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1549 return (jint)AUDIO_JAVA_BAD_VALUE;
1550 }
1551 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1552 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1553 env->DeleteLocalRef(jPatchHandle);
1554
1555 ALOGV("AudioSystem::releaseAudioPatch");
1556 status_t status = AudioSystem::releaseAudioPatch(handle);
1557 ALOGV("AudioSystem::releaseAudioPatch() returned %d", status);
1558 jint jStatus = nativeToJavaStatus(status);
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001559 return jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001560}
1561
1562static jint
1563android_media_AudioSystem_listAudioPatches(JNIEnv *env, jobject clazz,
1564 jobject jPatches, jintArray jGeneration)
1565{
1566 ALOGV("listAudioPatches");
1567 if (jPatches == NULL) {
1568 ALOGE("listAudioPatches NULL AudioPatch ArrayList");
1569 return (jint)AUDIO_JAVA_BAD_VALUE;
1570 }
1571 if (!env->IsInstanceOf(jPatches, gArrayListClass)) {
1572 ALOGE("listAudioPatches not an arraylist");
1573 return (jint)AUDIO_JAVA_BAD_VALUE;
1574 }
1575
1576 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1577 return (jint)AUDIO_JAVA_BAD_VALUE;
1578 }
1579
1580 status_t status;
1581 unsigned int generation1;
1582 unsigned int generation;
1583 unsigned int numPatches;
1584 jint *nGeneration;
1585 struct audio_patch *nPatches = NULL;
1586 jobjectArray jSources = NULL;
1587 jobject jSource = NULL;
1588 jobjectArray jSinks = NULL;
1589 jobject jSink = NULL;
1590 jobject jPatch = NULL;
1591 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
Eric Laurentb36d1042016-04-14 18:00:38 -07001592 jint jStatus;
Eric Laurentb69681c2014-05-19 19:02:51 -07001593
1594 // get the patch count and all the patches until they both return the same generation
1595 do {
1596 if (attempts-- < 0) {
1597 status = TIMED_OUT;
1598 break;
1599 }
1600
1601 numPatches = 0;
1602 status = AudioSystem::listAudioPatches(&numPatches,
1603 NULL,
1604 &generation1);
Eric Laurentb36d1042016-04-14 18:00:38 -07001605 if (status != NO_ERROR) {
Eric Laurentb69681c2014-05-19 19:02:51 -07001606 ALOGE_IF(status != NO_ERROR, "listAudioPatches AudioSystem::listAudioPatches error %d",
1607 status);
1608 break;
1609 }
Eric Laurentb36d1042016-04-14 18:00:38 -07001610 if (numPatches == 0) {
1611 jStatus = (jint)AUDIO_JAVA_SUCCESS;
1612 goto exit;
1613 }
1614
Eric Laurentb69681c2014-05-19 19:02:51 -07001615 nPatches = (struct audio_patch *)realloc(nPatches, numPatches * sizeof(struct audio_patch));
1616
1617 status = AudioSystem::listAudioPatches(&numPatches,
1618 nPatches,
1619 &generation);
1620 ALOGV("listAudioPatches AudioSystem::listAudioPatches numPatches %d generation %d generation1 %d",
1621 numPatches, generation, generation1);
1622
1623 } while (generation1 != generation && status == NO_ERROR);
1624
Eric Laurentb36d1042016-04-14 18:00:38 -07001625 jStatus = nativeToJavaStatus(status);
Eric Laurentb69681c2014-05-19 19:02:51 -07001626 if (jStatus != AUDIO_JAVA_SUCCESS) {
1627 goto exit;
1628 }
1629
Eric Laurentb69681c2014-05-19 19:02:51 -07001630 for (size_t i = 0; i < numPatches; i++) {
1631 jobject patchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1632 nPatches[i].id);
1633 if (patchHandle == NULL) {
1634 jStatus = AUDIO_JAVA_ERROR;
1635 goto exit;
1636 }
Dan Albert46d84442014-11-18 16:07:51 -08001637 ALOGV("listAudioPatches patch %zu num_sources %d num_sinks %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001638 i, nPatches[i].num_sources, nPatches[i].num_sinks);
1639
1640 env->SetIntField(patchHandle, gAudioHandleFields.mId, nPatches[i].id);
1641
1642 // load sources
1643 jSources = env->NewObjectArray(nPatches[i].num_sources,
1644 gAudioPortConfigClass, NULL);
1645 if (jSources == NULL) {
1646 jStatus = AUDIO_JAVA_ERROR;
1647 goto exit;
1648 }
1649
1650 for (size_t j = 0; j < nPatches[i].num_sources; j++) {
1651 jStatus = convertAudioPortConfigFromNative(env,
1652 NULL,
1653 &jSource,
1654 &nPatches[i].sources[j]);
1655 if (jStatus != AUDIO_JAVA_SUCCESS) {
1656 goto exit;
1657 }
1658 env->SetObjectArrayElement(jSources, j, jSource);
1659 env->DeleteLocalRef(jSource);
1660 jSource = NULL;
Dan Albert46d84442014-11-18 16:07:51 -08001661 ALOGV("listAudioPatches patch %zu source %zu is a %s handle %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001662 i, j,
1663 nPatches[i].sources[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1664 nPatches[i].sources[j].id);
1665 }
1666 // load sinks
1667 jSinks = env->NewObjectArray(nPatches[i].num_sinks,
1668 gAudioPortConfigClass, NULL);
1669 if (jSinks == NULL) {
1670 jStatus = AUDIO_JAVA_ERROR;
1671 goto exit;
1672 }
1673
1674 for (size_t j = 0; j < nPatches[i].num_sinks; j++) {
1675 jStatus = convertAudioPortConfigFromNative(env,
1676 NULL,
1677 &jSink,
1678 &nPatches[i].sinks[j]);
1679
1680 if (jStatus != AUDIO_JAVA_SUCCESS) {
1681 goto exit;
1682 }
1683 env->SetObjectArrayElement(jSinks, j, jSink);
1684 env->DeleteLocalRef(jSink);
1685 jSink = NULL;
Dan Albert46d84442014-11-18 16:07:51 -08001686 ALOGV("listAudioPatches patch %zu sink %zu is a %s handle %d",
Eric Laurentb69681c2014-05-19 19:02:51 -07001687 i, j,
1688 nPatches[i].sinks[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1689 nPatches[i].sinks[j].id);
1690 }
1691
1692 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor,
1693 patchHandle, jSources, jSinks);
1694 env->DeleteLocalRef(jSources);
1695 jSources = NULL;
1696 env->DeleteLocalRef(jSinks);
1697 jSinks = NULL;
1698 if (jPatch == NULL) {
1699 jStatus = AUDIO_JAVA_ERROR;
1700 goto exit;
1701 }
1702 env->CallBooleanMethod(jPatches, gArrayListMethods.add, jPatch);
1703 env->DeleteLocalRef(jPatch);
1704 jPatch = NULL;
1705 }
1706
1707exit:
Eric Laurentb36d1042016-04-14 18:00:38 -07001708
1709 nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1710 if (nGeneration == NULL) {
1711 jStatus = AUDIO_JAVA_ERROR;
1712 } else {
1713 nGeneration[0] = generation1;
1714 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1715 }
1716
Eric Laurentb69681c2014-05-19 19:02:51 -07001717 if (jSources != NULL) {
1718 env->DeleteLocalRef(jSources);
1719 }
1720 if (jSource != NULL) {
1721 env->DeleteLocalRef(jSource);
1722 }
1723 if (jSinks != NULL) {
1724 env->DeleteLocalRef(jSinks);
1725 }
1726 if (jSink != NULL) {
1727 env->DeleteLocalRef(jSink);
1728 }
1729 if (jPatch != NULL) {
1730 env->DeleteLocalRef(jPatch);
1731 }
1732 free(nPatches);
1733 return jStatus;
1734}
1735
Eric Laurent3a241992014-05-19 19:33:26 -07001736static jint
1737android_media_AudioSystem_setAudioPortConfig(JNIEnv *env, jobject clazz,
1738 jobject jAudioPortConfig)
1739{
1740 ALOGV("setAudioPortConfig");
1741 if (jAudioPortConfig == NULL) {
1742 return AUDIO_JAVA_BAD_VALUE;
1743 }
1744 if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
1745 return AUDIO_JAVA_BAD_VALUE;
1746 }
Mikhail Naganov304eafc2018-05-23 16:54:12 -07001747 struct audio_port_config nAudioPortConfig = {};
Eric Laurent6368a7d2014-11-19 12:18:32 -08001748 jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig, true);
Eric Laurent3a241992014-05-19 19:33:26 -07001749 if (jStatus != AUDIO_JAVA_SUCCESS) {
1750 return jStatus;
1751 }
1752 status_t status = AudioSystem::setAudioPortConfig(&nAudioPortConfig);
1753 ALOGV("AudioSystem::setAudioPortConfig() returned %d", status);
1754 jStatus = nativeToJavaStatus(status);
1755 return jStatus;
1756}
1757
Hongwei Wangf44a5682018-08-24 10:37:56 -07001758/**
1759 * Returns handle if the audio source is successfully started.
1760 */
1761static jint
1762android_media_AudioSystem_startAudioSource(JNIEnv *env, jobject clazz,
1763 jobject jAudioPortConfig,
1764 jobject jAudioAttributes)
1765{
1766 ALOGV("startAudioSource");
1767 if (jAudioPortConfig == NULL || jAudioAttributes == NULL) {
1768 return AUDIO_JAVA_BAD_VALUE;
1769 }
1770 if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
1771 return AUDIO_JAVA_BAD_VALUE;
1772 }
Hongwei Wangf44a5682018-08-24 10:37:56 -07001773 struct audio_port_config nAudioPortConfig = {};
1774 jint jStatus = convertAudioPortConfigToNativeWithDevicePort(env,
1775 &nAudioPortConfig, jAudioPortConfig, false);
1776 if (jStatus != AUDIO_JAVA_SUCCESS) {
1777 return jStatus;
1778 }
François Gaffieb4691282018-07-09 13:07:32 +02001779 auto paa = JNIAudioAttributeHelper::makeUnique();
1780 jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAudioAttributes, paa.get());
1781 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
Hongwei Wangf44a5682018-08-24 10:37:56 -07001782 return jStatus;
1783 }
1784 audio_port_handle_t handle;
François Gaffieb4691282018-07-09 13:07:32 +02001785 status_t status = AudioSystem::startAudioSource(&nAudioPortConfig, paa.get(), &handle);
Hongwei Wangf44a5682018-08-24 10:37:56 -07001786 ALOGV("AudioSystem::startAudioSource() returned %d handle %d", status, handle);
1787 return handle > 0 ? handle : nativeToJavaStatus(status);
1788}
1789
1790static jint
1791android_media_AudioSystem_stopAudioSource(JNIEnv *env, jobject clazz, jint handle)
1792{
1793 ALOGV("stopAudioSource");
1794 status_t status = AudioSystem::stopAudioSource(
1795 static_cast <audio_port_handle_t>(handle));
1796 ALOGV("AudioSystem::stopAudioSource() returned %d", status);
1797 return nativeToJavaStatus(status);
1798}
1799
Eric Laurent700e7342014-05-02 18:33:15 -07001800static void
1801android_media_AudioSystem_eventHandlerSetup(JNIEnv *env, jobject thiz, jobject weak_this)
1802{
1803 ALOGV("eventHandlerSetup");
1804
1805 sp<JNIAudioPortCallback> callback = new JNIAudioPortCallback(env, thiz, weak_this);
1806
Eric Laurent2615afb2015-03-25 14:51:08 -07001807 if (AudioSystem::addAudioPortCallback(callback) == NO_ERROR) {
1808 setJniCallback(env, thiz, callback);
1809 }
Eric Laurent700e7342014-05-02 18:33:15 -07001810}
1811
1812static void
1813android_media_AudioSystem_eventHandlerFinalize(JNIEnv *env, jobject thiz)
1814{
1815 ALOGV("eventHandlerFinalize");
1816
Eric Laurent2615afb2015-03-25 14:51:08 -07001817 sp<JNIAudioPortCallback> callback = setJniCallback(env, thiz, 0);
Eric Laurent700e7342014-05-02 18:33:15 -07001818
Eric Laurent2615afb2015-03-25 14:51:08 -07001819 if (callback != 0) {
1820 AudioSystem::removeAudioPortCallback(callback);
1821 }
Eric Laurent700e7342014-05-02 18:33:15 -07001822}
1823
Eric Laurentb634e1b2014-08-01 14:44:46 -07001824static jint
1825android_media_AudioSystem_getAudioHwSyncForSession(JNIEnv *env, jobject thiz, jint sessionId)
1826{
Glenn Kasten33b84042016-03-08 12:02:55 -08001827 return (jint) AudioSystem::getAudioHwSyncForSession((audio_session_t) sessionId);
Eric Laurentb634e1b2014-08-01 14:44:46 -07001828}
1829
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07001830static void
1831android_media_AudioSystem_registerDynPolicyCallback(JNIEnv *env, jobject thiz)
1832{
1833 AudioSystem::setDynPolicyCallback(android_media_AudioSystem_dyn_policy_callback);
1834}
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001835
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08001836static void
1837android_media_AudioSystem_registerRecordingCallback(JNIEnv *env, jobject thiz)
1838{
1839 AudioSystem::setRecordConfigCallback(android_media_AudioSystem_recording_callback);
1840}
1841
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001842
1843static jint convertAudioMixToNative(JNIEnv *env,
1844 AudioMix *nAudioMix,
1845 const jobject jAudioMix)
1846{
1847 nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType);
1848 nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags);
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07001849 nAudioMix->mDeviceType = (audio_devices_t)
1850 env->GetIntField(jAudioMix, gAudioMixFields.mDeviceType);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001851
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07001852 jstring jDeviceAddress = (jstring)env->GetObjectField(jAudioMix,
1853 gAudioMixFields.mDeviceAddress);
1854 const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
1855 nAudioMix->mDeviceAddress = String8(nDeviceAddress);
1856 env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
1857 env->DeleteLocalRef(jDeviceAddress);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001858
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07001859 nAudioMix->mCbFlags = env->GetIntField(jAudioMix, gAudioMixFields.mCallbackFlags);
1860
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001861 jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat);
1862 nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat,
1863 gAudioFormatFields.mSampleRate);
1864 nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat,
1865 gAudioFormatFields.mChannelMask));
1866 nAudioMix->mFormat.format = audioFormatToNative(env->GetIntField(jFormat,
1867 gAudioFormatFields.mEncoding));
1868 env->DeleteLocalRef(jFormat);
1869
1870 jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule);
1871 jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria);
Kevin Rocarda3a4bbb2019-03-07 18:29:48 -08001872 nAudioMix->mAllowPrivilegedPlaybackCapture =
1873 env->GetBooleanField(jRule, gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001874 env->DeleteLocalRef(jRule);
1875 jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria,
1876 gArrayListMethods.toArray);
1877 env->DeleteLocalRef(jRuleCriteria);
1878
1879 jint numCriteria = env->GetArrayLength(jCriteria);
1880 if (numCriteria > MAX_CRITERIA_PER_MIX) {
1881 numCriteria = MAX_CRITERIA_PER_MIX;
1882 }
1883
1884 for (jint i = 0; i < numCriteria; i++) {
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001885 AudioMixMatchCriterion nCriterion;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001886
1887 jobject jCriterion = env->GetObjectArrayElement(jCriteria, i);
1888
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001889 nCriterion.mRule = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mRule);
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001890
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001891 const uint32_t match_rule = nCriterion.mRule & ~RULE_EXCLUSION_MASK;
1892 switch (match_rule) {
1893 case RULE_MATCH_UID:
1894 nCriterion.mValue.mUid = env->GetIntField(jCriterion,
1895 gAudioMixMatchCriterionFields.mIntProp);
1896 break;
1897 case RULE_MATCH_ATTRIBUTE_USAGE:
1898 case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: {
1899 jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr);
François Gaffieb4691282018-07-09 13:07:32 +02001900
1901 auto paa = JNIAudioAttributeHelper::makeUnique();
1902 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAttributes, paa.get());
1903 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
1904 return jStatus;
1905 }
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001906 if (match_rule == RULE_MATCH_ATTRIBUTE_USAGE) {
François Gaffieb4691282018-07-09 13:07:32 +02001907 nCriterion.mValue.mUsage = paa->usage;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001908 } else {
François Gaffieb4691282018-07-09 13:07:32 +02001909 nCriterion.mValue.mSource = paa->source;
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08001910 }
1911 env->DeleteLocalRef(jAttributes);
1912 }
1913 break;
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001914 }
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08001915
1916 nAudioMix->mCriteria.add(nCriterion);
1917 env->DeleteLocalRef(jCriterion);
1918 }
1919
1920 env->DeleteLocalRef(jCriteria);
1921
1922 return (jint)AUDIO_JAVA_SUCCESS;
1923}
1924
1925static jint
1926android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz,
1927 jobject jMixesList, jboolean registration)
1928{
1929 ALOGV("registerPolicyMixes");
1930
1931 if (jMixesList == NULL) {
1932 return (jint)AUDIO_JAVA_BAD_VALUE;
1933 }
1934 if (!env->IsInstanceOf(jMixesList, gArrayListClass)) {
1935 return (jint)AUDIO_JAVA_BAD_VALUE;
1936 }
1937 jobjectArray jMixes = (jobjectArray)env->CallObjectMethod(jMixesList,
1938 gArrayListMethods.toArray);
1939 jint numMixes = env->GetArrayLength(jMixes);
1940 if (numMixes > MAX_MIXES_PER_POLICY) {
1941 numMixes = MAX_MIXES_PER_POLICY;
1942 }
1943
1944 status_t status;
1945 jint jStatus;
1946 jobject jAudioMix = NULL;
1947 Vector <AudioMix> mixes;
1948 for (jint i = 0; i < numMixes; i++) {
1949 jAudioMix = env->GetObjectArrayElement(jMixes, i);
1950 if (!env->IsInstanceOf(jAudioMix, gAudioMixClass)) {
1951 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1952 goto exit;
1953 }
1954 AudioMix mix;
1955 jStatus = convertAudioMixToNative(env, &mix, jAudioMix);
1956 env->DeleteLocalRef(jAudioMix);
1957 jAudioMix = NULL;
1958 if (jStatus != AUDIO_JAVA_SUCCESS) {
1959 goto exit;
1960 }
1961 mixes.add(mix);
1962 }
1963
1964 ALOGV("AudioSystem::registerPolicyMixes numMixes %d registration %d", numMixes, registration);
1965 status = AudioSystem::registerPolicyMixes(mixes, registration);
1966 ALOGV("AudioSystem::registerPolicyMixes() returned %d", status);
1967
1968 jStatus = nativeToJavaStatus(status);
1969 if (jStatus != AUDIO_JAVA_SUCCESS) {
1970 goto exit;
1971 }
1972
1973exit:
1974 if (jAudioMix != NULL) {
1975 env->DeleteLocalRef(jAudioMix);
1976 }
1977 return jStatus;
1978}
1979
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08001980static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz,
1981 jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) {
1982 if (deviceTypes == nullptr || deviceAddresses == nullptr) {
1983 return (jint) AUDIO_JAVA_BAD_VALUE;
1984 }
1985 jsize nb = env->GetArrayLength(deviceTypes);
1986 if (nb == 0 || nb != env->GetArrayLength(deviceAddresses)) {
1987 return (jint) AUDIO_JAVA_BAD_VALUE;
1988 }
1989 // retrieve all device types
1990 std::vector<audio_devices_t> deviceTypesVector;
1991 jint* typesPtr = nullptr;
1992 typesPtr = env->GetIntArrayElements(deviceTypes, 0);
1993 if (typesPtr == nullptr) {
1994 return (jint) AUDIO_JAVA_BAD_VALUE;
1995 }
1996 for (jint i = 0; i < nb; i++) {
1997 deviceTypesVector.push_back((audio_devices_t) typesPtr[i]);
1998 }
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08001999
2000 // check each address is a string and add device type/address to list for device affinity
2001 Vector<AudioDeviceTypeAddr> deviceVector;
2002 jclass stringClass = FindClassOrDie(env, "java/lang/String");
2003 for (jint i = 0; i < nb; i++) {
2004 jobject addrJobj = env->GetObjectArrayElement(deviceAddresses, i);
2005 if (!env->IsInstanceOf(addrJobj, stringClass)) {
2006 return (jint) AUDIO_JAVA_BAD_VALUE;
2007 }
2008 String8 address = String8(env->GetStringUTFChars((jstring) addrJobj, NULL));
2009 AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address);
2010 deviceVector.add(dev);
2011 }
Hongwei Wang94d58002019-02-13 16:59:32 -08002012 env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0);
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002013
2014 status_t status = AudioSystem::setUidDeviceAffinities((uid_t) uid, deviceVector);
2015 return (jint) nativeToJavaStatus(status);
2016}
2017
2018static jint android_media_AudioSystem_removeUidDeviceAffinities(JNIEnv *env, jobject clazz,
2019 jint uid) {
2020
2021 //###
2022 status_t status = NO_ERROR;//AudioSystem::removeUidDeviceAffinities();
2023 return (jint) nativeToJavaStatus(status);
2024}
2025
2026
Eric Laurent0867bed2015-05-20 14:49:08 -07002027static jint
2028android_media_AudioSystem_systemReady(JNIEnv *env, jobject thiz)
2029{
2030 return nativeToJavaStatus(AudioSystem::systemReady());
2031}
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002032
Eric Laurenteab40d12017-06-09 12:45:21 -07002033static jfloat
2034android_media_AudioSystem_getStreamVolumeDB(JNIEnv *env, jobject thiz,
2035 jint stream, jint index, jint device)
2036{
2037 return (jfloat)AudioSystem::getStreamVolumeDB((audio_stream_type_t)stream,
2038 (int)index,
2039 (audio_devices_t)device);
2040}
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002041
Jean-Michel Trivi980d38f2018-01-08 15:43:35 -08002042static jboolean
2043android_media_AudioSystem_isOffloadSupported(JNIEnv *env, jobject thiz,
Jean-Michel Trivif3fd84a2019-03-21 16:08:50 -07002044 jint encoding, jint sampleRate, jint channelMask, jint channelIndexMask, jint streamType)
Jean-Michel Trivi980d38f2018-01-08 15:43:35 -08002045{
2046 audio_offload_info_t format = AUDIO_INFO_INITIALIZER;
2047 format.format = (audio_format_t) audioFormatToNative(encoding);
2048 format.sample_rate = (uint32_t) sampleRate;
2049 format.channel_mask = nativeChannelMaskFromJavaChannelMasks(channelMask, channelIndexMask);
Jean-Michel Trivif3fd84a2019-03-21 16:08:50 -07002050 format.stream_type = (audio_stream_type_t) streamType;
Jean-Michel Trivi980d38f2018-01-08 15:43:35 -08002051 format.has_video = false;
2052 format.is_streaming = false;
2053 // offload duration unknown at this point:
2054 // client side code cannot access "audio.offload.min.duration.secs" property to make a query
2055 // agnostic of duration, so using acceptable estimate of 2mn
2056 format.duration_us = 120 * 1000000;
2057 return AudioSystem::isOffloadSupported(format);
2058}
2059
jiabinc0f49442018-01-05 10:23:50 -08002060static jint
2061android_media_AudioSystem_getMicrophones(JNIEnv *env, jobject thiz, jobject jMicrophonesInfo)
2062{
2063 ALOGV("getMicrophones");
2064
2065 if (jMicrophonesInfo == NULL) {
2066 ALOGE("jMicrophonesInfo NULL MicrophoneInfo ArrayList");
2067 return (jint)AUDIO_JAVA_BAD_VALUE;
2068 }
2069 if (!env->IsInstanceOf(jMicrophonesInfo, gArrayListClass)) {
2070 ALOGE("getMicrophones not an arraylist");
2071 return (jint)AUDIO_JAVA_BAD_VALUE;
2072 }
2073
2074 jint jStatus;
2075 std::vector<media::MicrophoneInfo> microphones;
2076 status_t status = AudioSystem::getMicrophones(&microphones);
2077 if (status != NO_ERROR) {
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002078 ALOGE("AudioSystem::getMicrophones error %d", status);
jiabinc0f49442018-01-05 10:23:50 -08002079 jStatus = nativeToJavaStatus(status);
2080 return jStatus;
2081 }
2082 if (microphones.size() == 0) {
2083 jStatus = (jint)AUDIO_JAVA_SUCCESS;
2084 return jStatus;
2085 }
2086 for (size_t i = 0; i < microphones.size(); i++) {
2087 jobject jMicrophoneInfo;
2088 jStatus = convertMicrophoneInfoFromNative(env, &jMicrophoneInfo, &microphones[i]);
2089 if (jStatus != AUDIO_JAVA_SUCCESS) {
2090 return jStatus;
2091 }
2092 env->CallBooleanMethod(jMicrophonesInfo, gArrayListMethods.add, jMicrophoneInfo);
2093 env->DeleteLocalRef(jMicrophoneInfo);
2094 }
2095
2096 return jStatus;
2097}
2098
jiabin39940752018-04-02 18:18:45 -07002099static jint
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002100android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP(
2101 JNIEnv *env, jobject thiz, jobject jEncodingFormatList)
2102{
2103 ALOGV("%s", __FUNCTION__);
2104 jint jStatus = AUDIO_JAVA_SUCCESS;
2105 if (!env->IsInstanceOf(jEncodingFormatList, gArrayListClass)) {
2106 ALOGE("%s: jEncodingFormatList not an ArrayList", __FUNCTION__);
2107 return (jint)AUDIO_JAVA_BAD_VALUE;
2108 }
2109 std::vector<audio_format_t> encodingFormats;
Eric Laurentfffeac82019-01-17 09:03:47 -08002110 status_t status = AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP(
2111 &encodingFormats);
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002112 if (status != NO_ERROR) {
2113 ALOGE("%s: error %d", __FUNCTION__, status);
2114 jStatus = nativeToJavaStatus(status);
2115 return jStatus;
2116 }
2117
2118 for (size_t i = 0; i < encodingFormats.size(); i++) {
2119 ScopedLocalRef<jobject> jEncodingFormat(
2120 env, env->NewObject(gIntegerClass, gIntegerCstor, encodingFormats[i]));
2121 env->CallBooleanMethod(jEncodingFormatList, gArrayListMethods.add,
2122 jEncodingFormat.get());
2123 }
2124 return jStatus;
2125}
2126
2127static jint
jiabin39940752018-04-02 18:18:45 -07002128android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
2129 jobject jSurroundFormats, jboolean reported)
2130{
2131 ALOGV("getSurroundFormats");
2132
2133 if (jSurroundFormats == NULL) {
2134 ALOGE("jSurroundFormats is NULL");
2135 return (jint)AUDIO_JAVA_BAD_VALUE;
2136 }
2137 if (!env->IsInstanceOf(jSurroundFormats, gMapClass)) {
2138 ALOGE("getSurroundFormats not a map");
2139 return (jint)AUDIO_JAVA_BAD_VALUE;
2140 }
2141
2142 jint jStatus;
2143 unsigned int numSurroundFormats = 0;
2144 audio_format_t *surroundFormats = NULL;
2145 bool *surroundFormatsEnabled = NULL;
2146 status_t status = AudioSystem::getSurroundFormats(
2147 &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
2148 if (status != NO_ERROR) {
2149 ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
2150 jStatus = nativeToJavaStatus(status);
2151 goto exit;
2152 }
2153 if (numSurroundFormats == 0) {
2154 jStatus = (jint)AUDIO_JAVA_SUCCESS;
2155 goto exit;
2156 }
2157 surroundFormats = (audio_format_t *)calloc(numSurroundFormats, sizeof(audio_format_t));
2158 surroundFormatsEnabled = (bool *)calloc(numSurroundFormats, sizeof(bool));
2159 status = AudioSystem::getSurroundFormats(
2160 &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
2161 jStatus = nativeToJavaStatus(status);
2162 if (status != NO_ERROR) {
2163 ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
2164 goto exit;
2165 }
2166 for (size_t i = 0; i < numSurroundFormats; i++) {
2167 jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor,
2168 audioFormatFromNative(surroundFormats[i]));
2169 jobject enabled = env->NewObject(gBooleanClass, gBooleanCstor, surroundFormatsEnabled[i]);
2170 env->CallObjectMethod(jSurroundFormats, gMapPut, surroundFormat, enabled);
2171 env->DeleteLocalRef(surroundFormat);
2172 env->DeleteLocalRef(enabled);
2173 }
2174
2175exit:
2176 free(surroundFormats);
2177 free(surroundFormatsEnabled);
2178 return jStatus;
2179}
2180
2181static jint
2182android_media_AudioSystem_setSurroundFormatEnabled(JNIEnv *env, jobject thiz,
2183 jint audioFormat, jboolean enabled)
2184{
2185 status_t status = AudioSystem::setSurroundFormatEnabled(audioFormatToNative(audioFormat),
2186 (bool)enabled);
2187 if (status != NO_ERROR) {
2188 ALOGE_IF(status != NO_ERROR, "AudioSystem::setSurroundFormatEnabled error %d", status);
2189 }
2190 return (jint)nativeToJavaStatus(status);
2191}
2192
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002193static jint android_media_AudioSystem_get_FCC_8(JNIEnv *env, jobject thiz) {
2194 return FCC_8;
2195}
2196
Eric Laurent1c9c1d52018-10-17 10:06:46 -07002197static jint
2198android_media_AudioSystem_setAssistantUid(JNIEnv *env, jobject thiz, jint uid)
2199{
2200 status_t status = AudioSystem::setAssistantUid(uid);
2201 return (jint)nativeToJavaStatus(status);
2202}
2203
2204static jint
2205android_media_AudioSystem_setA11yServicesUids(JNIEnv *env, jobject thiz, jintArray uids) {
2206 std::vector<uid_t> nativeUidsVector;
2207
2208 if (uids != nullptr) {
2209 jsize len = env->GetArrayLength(uids);
2210
2211 if (len > 0) {
2212 int *nativeUids = nullptr;
2213 nativeUids = env->GetIntArrayElements(uids, 0);
2214 if (nativeUids != nullptr) {
2215 for (size_t i = 0; i < len; i++) {
2216 nativeUidsVector.push_back(nativeUids[i]);
2217 }
2218 env->ReleaseIntArrayElements(uids, nativeUids, 0);
2219 }
2220 }
2221 }
2222 status_t status = AudioSystem::setA11yServicesUids(nativeUidsVector);
2223 return (jint)nativeToJavaStatus(status);
2224}
2225
jiabin66f9e722018-11-02 16:20:19 -07002226static jboolean
2227android_media_AudioSystem_isHapticPlaybackSupported(JNIEnv *env, jobject thiz)
2228{
2229 return AudioSystem::isHapticPlaybackSupported();
2230}
2231
Kevin Rocard7919c2a2019-03-21 10:28:01 -07002232static jint
2233android_media_AudioSystem_setAllowedCapturePolicy(JNIEnv *env, jobject thiz, jint uid, jint flags) {
2234 return AudioSystem::setAllowedCapturePolicy(uid, flags);
2235}
2236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002237// ----------------------------------------------------------------------------
2238
Daniel Micay76f6a862015-09-19 17:31:01 -04002239static const JNINativeMethod gMethods[] = {
Eric Laurenta553c252009-07-17 12:17:14 -07002240 {"setParameters", "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
2241 {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002242 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
2243 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
Jean-Michel Trivid6770542012-10-10 12:03:41 -07002244 {"isStreamActive", "(II)Z", (void *)android_media_AudioSystem_isStreamActive},
Jean-Michel Trivi679d5042013-02-04 16:24:09 -08002245 {"isStreamActiveRemotely","(II)Z", (void *)android_media_AudioSystem_isStreamActiveRemotely},
Jean-Michel Trivid6770542012-10-10 12:03:41 -07002246 {"isSourceActive", "(I)Z", (void *)android_media_AudioSystem_isSourceActive},
Jean-Michel Trivi8a21f5d2014-06-05 15:03:52 -07002247 {"newAudioSessionId", "()I", (void *)android_media_AudioSystem_newAudioSessionId},
Jean-Michel Trivi292a6a42016-12-01 08:32:15 -08002248 {"newAudioPlayerId", "()I", (void *)android_media_AudioSystem_newAudioPlayerId},
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -08002249 {"setDeviceConnectionState", "(IILjava/lang/String;Ljava/lang/String;I)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
Eric Laurenta553c252009-07-17 12:17:14 -07002250 {"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
Aniket Kumar Lata9fbc2052019-01-11 02:02:33 -08002251 {"handleDeviceConfigChange", "(ILjava/lang/String;Ljava/lang/String;I)I", (void *)android_media_AudioSystem_handleDeviceConfigChange},
Eric Laurenta553c252009-07-17 12:17:14 -07002252 {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
Eric Laurenta553c252009-07-17 12:17:14 -07002253 {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
2254 {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
2255 {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume},
Eric Laurent9bc8358d2011-11-18 16:43:31 -08002256 {"setStreamVolumeIndex","(III)I", (void *)android_media_AudioSystem_setStreamVolumeIndex},
2257 {"getStreamVolumeIndex","(II)I", (void *)android_media_AudioSystem_getStreamVolumeIndex},
François Gaffieebb67d02018-09-14 15:05:04 +02002258 {"setVolumeIndexForAttributes","(Landroid/media/AudioAttributes;II)I", (void *)android_media_AudioSystem_setVolumeIndexForAttributes},
2259 {"getVolumeIndexForAttributes","(Landroid/media/AudioAttributes;I)I", (void *)android_media_AudioSystem_getVolumeIndexForAttributes},
2260 {"getMinVolumeIndexForAttributes","(Landroid/media/AudioAttributes;)I", (void *)android_media_AudioSystem_getMinVolumeIndexForAttributes},
2261 {"getMaxVolumeIndexForAttributes","(Landroid/media/AudioAttributes;)I", (void *)android_media_AudioSystem_getMaxVolumeIndexForAttributes},
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -04002262 {"setMasterVolume", "(F)I", (void *)android_media_AudioSystem_setMasterVolume},
2263 {"getMasterVolume", "()F", (void *)android_media_AudioSystem_getMasterVolume},
2264 {"setMasterMute", "(Z)I", (void *)android_media_AudioSystem_setMasterMute},
2265 {"getMasterMute", "()Z", (void *)android_media_AudioSystem_getMasterMute},
Andy Hungf04b84d2015-12-18 17:33:27 -08002266 {"setMasterMono", "(Z)I", (void *)android_media_AudioSystem_setMasterMono},
2267 {"getMasterMono", "()Z", (void *)android_media_AudioSystem_getMasterMono},
Edward Savage-Jones35c292f2017-01-13 09:04:34 +01002268 {"setMasterBalance", "(F)I", (void *)android_media_AudioSystem_setMasterBalance},
2269 {"getMasterBalance", "()F", (void *)android_media_AudioSystem_getMasterBalance},
Glenn Kasten8b4b97a2011-02-04 13:54:26 -08002270 {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream},
Glenn Kastenc6c43652012-09-24 17:32:30 -07002271 {"getPrimaryOutputSamplingRate", "()I", (void *)android_media_AudioSystem_getPrimaryOutputSamplingRate},
2272 {"getPrimaryOutputFrameCount", "()I", (void *)android_media_AudioSystem_getPrimaryOutputFrameCount},
Oliver Woodman61dcdf32013-06-26 12:43:36 +01002273 {"getOutputLatency", "(I)I", (void *)android_media_AudioSystem_getOutputLatency},
Andy Hung79583582018-01-23 13:58:02 -08002274 {"setLowRamDevice", "(ZJ)I", (void *)android_media_AudioSystem_setLowRamDevice},
Eric Laurentdfb881f2013-07-18 14:41:39 -07002275 {"checkAudioFlinger", "()I", (void *)android_media_AudioSystem_checkAudioFlinger},
Eric Laurentb69681c2014-05-19 19:02:51 -07002276 {"listAudioPorts", "(Ljava/util/ArrayList;[I)I",
2277 (void *)android_media_AudioSystem_listAudioPorts},
2278 {"createAudioPatch", "([Landroid/media/AudioPatch;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)I",
2279 (void *)android_media_AudioSystem_createAudioPatch},
2280 {"releaseAudioPatch", "(Landroid/media/AudioPatch;)I",
2281 (void *)android_media_AudioSystem_releaseAudioPatch},
2282 {"listAudioPatches", "(Ljava/util/ArrayList;[I)I",
2283 (void *)android_media_AudioSystem_listAudioPatches},
Eric Laurent3a241992014-05-19 19:33:26 -07002284 {"setAudioPortConfig", "(Landroid/media/AudioPortConfig;)I",
2285 (void *)android_media_AudioSystem_setAudioPortConfig},
Hongwei Wangf44a5682018-08-24 10:37:56 -07002286 {"startAudioSource", "(Landroid/media/AudioPortConfig;Landroid/media/AudioAttributes;)I",
2287 (void *)android_media_AudioSystem_startAudioSource},
2288 {"stopAudioSource", "(I)I", (void *)android_media_AudioSystem_stopAudioSource},
Eric Laurentb634e1b2014-08-01 14:44:46 -07002289 {"getAudioHwSyncForSession", "(I)I",
2290 (void *)android_media_AudioSystem_getAudioHwSyncForSession},
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002291 {"registerPolicyMixes", "(Ljava/util/ArrayList;Z)I",
2292 (void *)android_media_AudioSystem_registerPolicyMixes},
Jean-Michel Trivid6f65de2018-12-18 18:49:14 -08002293 {"setUidDeviceAffinities", "(I[I[Ljava/lang/String;)I",
2294 (void *)android_media_AudioSystem_setUidDeviceAffinities},
2295 {"removeUidDeviceAffinities", "(I)I",
2296 (void *)android_media_AudioSystem_removeUidDeviceAffinities},
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002297 {"native_register_dynamic_policy_callback", "()V",
2298 (void *)android_media_AudioSystem_registerDynPolicyCallback},
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002299 {"native_register_recording_callback", "()V",
2300 (void *)android_media_AudioSystem_registerRecordingCallback},
Eric Laurent0867bed2015-05-20 14:49:08 -07002301 {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady},
Eric Laurenteab40d12017-06-09 12:45:21 -07002302 {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
Jean-Michel Trivif3fd84a2019-03-21 16:08:50 -07002303 {"native_is_offload_supported", "(IIIII)Z", (void *)android_media_AudioSystem_isOffloadSupported},
jiabinc0f49442018-01-05 10:23:50 -08002304 {"getMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioSystem_getMicrophones},
jiabin39940752018-04-02 18:18:45 -07002305 {"getSurroundFormats", "(Ljava/util/Map;Z)I", (void *)android_media_AudioSystem_getSurroundFormats},
2306 {"setSurroundFormatEnabled", "(IZ)I", (void *)android_media_AudioSystem_setSurroundFormatEnabled},
Eric Laurent1c9c1d52018-10-17 10:06:46 -07002307 {"setAssistantUid", "(I)I", (void *)android_media_AudioSystem_setAssistantUid},
2308 {"setA11yServicesUids", "([I)I", (void *)android_media_AudioSystem_setA11yServicesUids},
jiabin66f9e722018-11-02 16:20:19 -07002309 {"isHapticPlaybackSupported", "()Z", (void *)android_media_AudioSystem_isHapticPlaybackSupported},
Arun Mirpuricb102fa2019-01-11 18:39:21 -08002310 {"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
2311 (void*)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
Kevin Rocard7919c2a2019-03-21 10:28:01 -07002312 {"setAllowedCapturePolicy", "(II)I", (void *)android_media_AudioSystem_setAllowedCapturePolicy},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313};
2314
Daniel Micay76f6a862015-09-19 17:31:01 -04002315static const JNINativeMethod gEventHandlerMethods[] = {
Eric Laurent700e7342014-05-02 18:33:15 -07002316 {"native_setup",
2317 "(Ljava/lang/Object;)V",
2318 (void *)android_media_AudioSystem_eventHandlerSetup},
2319 {"native_finalize",
2320 "()V",
2321 (void *)android_media_AudioSystem_eventHandlerFinalize},
2322};
2323
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002324static const JNINativeMethod gGetFCC8Methods[] = {
2325 {"native_get_FCC_8", "()I", (void *)android_media_AudioSystem_get_FCC_8},
2326};
2327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328int register_android_media_AudioSystem(JNIEnv *env)
2329{
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002330 // This needs to be done before hooking up methods AudioTrackRoutingProxy (below)
2331 RegisterMethodsOrDie(env, kClassPathName, gGetFCC8Methods, NELEM(gGetFCC8Methods));
2332
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002333 jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
2334 gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
2335 gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
Eric Laurent09378972014-12-10 10:42:08 -08002336 gArrayListMethods.toArray = GetMethodIDOrDie(env, arrayListClass, "toArray", "()[Ljava/lang/Object;");
Eric Laurentb69681c2014-05-19 19:02:51 -07002337
jiabin39940752018-04-02 18:18:45 -07002338 jclass booleanClass = FindClassOrDie(env, "java/lang/Boolean");
2339 gBooleanClass = MakeGlobalRefOrDie(env, booleanClass);
2340 gBooleanCstor = GetMethodIDOrDie(env, booleanClass, "<init>", "(Z)V");
2341
2342 jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
2343 gIntegerClass = MakeGlobalRefOrDie(env, integerClass);
2344 gIntegerCstor = GetMethodIDOrDie(env, integerClass, "<init>", "(I)V");
2345
2346 jclass mapClass = FindClassOrDie(env, "java/util/Map");
2347 gMapClass = MakeGlobalRefOrDie(env, mapClass);
2348 gMapPut = GetMethodIDOrDie(env, mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
2349
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002350 jclass audioHandleClass = FindClassOrDie(env, "android/media/AudioHandle");
2351 gAudioHandleClass = MakeGlobalRefOrDie(env, audioHandleClass);
2352 gAudioHandleCstor = GetMethodIDOrDie(env, audioHandleClass, "<init>", "(I)V");
2353 gAudioHandleFields.mId = GetFieldIDOrDie(env, audioHandleClass, "mId", "I");
Eric Laurentb69681c2014-05-19 19:02:51 -07002354
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002355 jclass audioPortClass = FindClassOrDie(env, "android/media/AudioPort");
2356 gAudioPortClass = MakeGlobalRefOrDie(env, audioPortClass);
2357 gAudioPortCstor = GetMethodIDOrDie(env, audioPortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002358 "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002359 gAudioPortFields.mHandle = GetFieldIDOrDie(env, audioPortClass, "mHandle",
Eric Laurentb69681c2014-05-19 19:02:51 -07002360 "Landroid/media/AudioHandle;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002361 gAudioPortFields.mRole = GetFieldIDOrDie(env, audioPortClass, "mRole", "I");
2362 gAudioPortFields.mGains = GetFieldIDOrDie(env, audioPortClass, "mGains",
Eric Laurentb69681c2014-05-19 19:02:51 -07002363 "[Landroid/media/AudioGain;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002364 gAudioPortFields.mActiveConfig = GetFieldIDOrDie(env, audioPortClass, "mActiveConfig",
2365 "Landroid/media/AudioPortConfig;");
Eric Laurentb69681c2014-05-19 19:02:51 -07002366
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002367 jclass audioPortConfigClass = FindClassOrDie(env, "android/media/AudioPortConfig");
2368 gAudioPortConfigClass = MakeGlobalRefOrDie(env, audioPortConfigClass);
2369 gAudioPortConfigCstor = GetMethodIDOrDie(env, audioPortConfigClass, "<init>",
2370 "(Landroid/media/AudioPort;IIILandroid/media/AudioGainConfig;)V");
2371 gAudioPortConfigFields.mPort = GetFieldIDOrDie(env, audioPortConfigClass, "mPort",
Eric Laurentb69681c2014-05-19 19:02:51 -07002372 "Landroid/media/AudioPort;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002373 gAudioPortConfigFields.mSamplingRate = GetFieldIDOrDie(env, audioPortConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002374 "mSamplingRate", "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002375 gAudioPortConfigFields.mChannelMask = GetFieldIDOrDie(env, audioPortConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002376 "mChannelMask", "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002377 gAudioPortConfigFields.mFormat = GetFieldIDOrDie(env, audioPortConfigClass, "mFormat", "I");
2378 gAudioPortConfigFields.mGain = GetFieldIDOrDie(env, audioPortConfigClass, "mGain",
Eric Laurentb69681c2014-05-19 19:02:51 -07002379 "Landroid/media/AudioGainConfig;");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002380 gAudioPortConfigFields.mConfigMask = GetFieldIDOrDie(env, audioPortConfigClass, "mConfigMask",
2381 "I");
Eric Laurentb69681c2014-05-19 19:02:51 -07002382
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002383 jclass audioDevicePortConfigClass = FindClassOrDie(env, "android/media/AudioDevicePortConfig");
2384 gAudioDevicePortConfigClass = MakeGlobalRefOrDie(env, audioDevicePortConfigClass);
2385 gAudioDevicePortConfigCstor = GetMethodIDOrDie(env, audioDevicePortConfigClass, "<init>",
2386 "(Landroid/media/AudioDevicePort;IIILandroid/media/AudioGainConfig;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002387
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002388 jclass audioMixPortConfigClass = FindClassOrDie(env, "android/media/AudioMixPortConfig");
2389 gAudioMixPortConfigClass = MakeGlobalRefOrDie(env, audioMixPortConfigClass);
2390 gAudioMixPortConfigCstor = GetMethodIDOrDie(env, audioMixPortConfigClass, "<init>",
2391 "(Landroid/media/AudioMixPort;IIILandroid/media/AudioGainConfig;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002392
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002393 jclass audioDevicePortClass = FindClassOrDie(env, "android/media/AudioDevicePort");
2394 gAudioDevicePortClass = MakeGlobalRefOrDie(env, audioDevicePortClass);
2395 gAudioDevicePortCstor = GetMethodIDOrDie(env, audioDevicePortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002396 "(Landroid/media/AudioHandle;Ljava/lang/String;[I[I[I[I[Landroid/media/AudioGain;ILjava/lang/String;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002397
Hongwei Wangf44a5682018-08-24 10:37:56 -07002398 // When access AudioPort as AudioDevicePort
2399 gAudioPortFields.mType = GetFieldIDOrDie(env, audioDevicePortClass, "mType", "I");
2400 gAudioPortFields.mAddress = GetFieldIDOrDie(env, audioDevicePortClass, "mAddress",
2401 "Ljava/lang/String;");
2402
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002403 jclass audioMixPortClass = FindClassOrDie(env, "android/media/AudioMixPort");
2404 gAudioMixPortClass = MakeGlobalRefOrDie(env, audioMixPortClass);
2405 gAudioMixPortCstor = GetMethodIDOrDie(env, audioMixPortClass, "<init>",
Paul McLeanf29e5f32015-06-15 10:19:22 -07002406 "(Landroid/media/AudioHandle;IILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002407
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002408 jclass audioGainClass = FindClassOrDie(env, "android/media/AudioGain");
2409 gAudioGainClass = MakeGlobalRefOrDie(env, audioGainClass);
2410 gAudioGainCstor = GetMethodIDOrDie(env, audioGainClass, "<init>", "(IIIIIIIII)V");
Eric Laurentb69681c2014-05-19 19:02:51 -07002411
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002412 jclass audioGainConfigClass = FindClassOrDie(env, "android/media/AudioGainConfig");
2413 gAudioGainConfigClass = MakeGlobalRefOrDie(env, audioGainConfigClass);
2414 gAudioGainConfigCstor = GetMethodIDOrDie(env, audioGainConfigClass, "<init>",
Eric Laurentb69681c2014-05-19 19:02:51 -07002415 "(ILandroid/media/AudioGain;II[II)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002416 gAudioGainConfigFields.mIndex = GetFieldIDOrDie(env, gAudioGainConfigClass, "mIndex", "I");
2417 gAudioGainConfigFields.mMode = GetFieldIDOrDie(env, audioGainConfigClass, "mMode", "I");
2418 gAudioGainConfigFields.mChannelMask = GetFieldIDOrDie(env, audioGainConfigClass, "mChannelMask",
Eric Laurentb69681c2014-05-19 19:02:51 -07002419 "I");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002420 gAudioGainConfigFields.mValues = GetFieldIDOrDie(env, audioGainConfigClass, "mValues", "[I");
2421 gAudioGainConfigFields.mRampDurationMs = GetFieldIDOrDie(env, audioGainConfigClass,
Eric Laurentb69681c2014-05-19 19:02:51 -07002422 "mRampDurationMs", "I");
2423
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002424 jclass audioPatchClass = FindClassOrDie(env, "android/media/AudioPatch");
2425 gAudioPatchClass = MakeGlobalRefOrDie(env, audioPatchClass);
2426 gAudioPatchCstor = GetMethodIDOrDie(env, audioPatchClass, "<init>",
Eric Laurentb69681c2014-05-19 19:02:51 -07002427"(Landroid/media/AudioHandle;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002428 gAudioPatchFields.mHandle = GetFieldIDOrDie(env, audioPatchClass, "mHandle",
Eric Laurentb69681c2014-05-19 19:02:51 -07002429 "Landroid/media/AudioHandle;");
2430
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002431 jclass eventHandlerClass = FindClassOrDie(env, kEventHandlerClassPathName);
Eric Laurent2615afb2015-03-25 14:51:08 -07002432 gAudioPortEventHandlerMethods.postEventFromNative = GetStaticMethodIDOrDie(
2433 env, eventHandlerClass, "postEventFromNative",
2434 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
2435 gEventHandlerFields.mJniCallback = GetFieldIDOrDie(env,
2436 eventHandlerClass, "mJniCallback", "J");
Eric Laurent700e7342014-05-02 18:33:15 -07002437
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002438 gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative =
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002439 GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
2440 "dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V");
Jean-Michel Trivid3c71f02015-12-07 11:59:31 -08002441 gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative =
2442 GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
Eric Laurentc7a0cdf2018-11-30 12:16:52 -08002443 "recordingCallbackFromNative", "(IIIIIZ[I[Landroid/media/audiofx/AudioEffect$Descriptor;[Landroid/media/audiofx/AudioEffect$Descriptor;I)V");
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002444
Eric Laurent09378972014-12-10 10:42:08 -08002445 jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix");
2446 gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass);
2447 gAudioMixFields.mRule = GetFieldIDOrDie(env, audioMixClass, "mRule",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002448 "Landroid/media/audiopolicy/AudioMixingRule;");
Eric Laurent09378972014-12-10 10:42:08 -08002449 gAudioMixFields.mFormat = GetFieldIDOrDie(env, audioMixClass, "mFormat",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002450 "Landroid/media/AudioFormat;");
Eric Laurent09378972014-12-10 10:42:08 -08002451 gAudioMixFields.mRouteFlags = GetFieldIDOrDie(env, audioMixClass, "mRouteFlags", "I");
Jean-Michel Trivi4ad39882016-03-14 18:46:41 -07002452 gAudioMixFields.mDeviceType = GetFieldIDOrDie(env, audioMixClass, "mDeviceSystemType", "I");
2453 gAudioMixFields.mDeviceAddress = GetFieldIDOrDie(env, audioMixClass, "mDeviceAddress",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002454 "Ljava/lang/String;");
Eric Laurent09378972014-12-10 10:42:08 -08002455 gAudioMixFields.mMixType = GetFieldIDOrDie(env, audioMixClass, "mMixType", "I");
Jean-Michel Trivi5a561092015-04-23 18:48:08 -07002456 gAudioMixFields.mCallbackFlags = GetFieldIDOrDie(env, audioMixClass, "mCallbackFlags", "I");
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002457
Eric Laurent09378972014-12-10 10:42:08 -08002458 jclass audioFormatClass = FindClassOrDie(env, "android/media/AudioFormat");
2459 gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass);
2460 gAudioFormatFields.mEncoding = GetFieldIDOrDie(env, audioFormatClass, "mEncoding", "I");
2461 gAudioFormatFields.mSampleRate = GetFieldIDOrDie(env, audioFormatClass, "mSampleRate", "I");
2462 gAudioFormatFields.mChannelMask = GetFieldIDOrDie(env, audioFormatClass, "mChannelMask", "I");
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002463
Eric Laurent09378972014-12-10 10:42:08 -08002464 jclass audioMixingRuleClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule");
2465 gAudioMixingRuleClass = MakeGlobalRefOrDie(env, audioMixingRuleClass);
2466 gAudioMixingRuleFields.mCriteria = GetFieldIDOrDie(env, audioMixingRuleClass, "mCriteria",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002467 "Ljava/util/ArrayList;");
Kevin Rocarda3a4bbb2019-03-07 18:29:48 -08002468 gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture =
2469 GetFieldIDOrDie(env, audioMixingRuleClass, "mAllowPrivilegedPlaybackCapture", "Z");
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002470
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08002471 jclass audioMixMatchCriterionClass =
2472 FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion");
2473 gAudioMixMatchCriterionClass = MakeGlobalRefOrDie(env,audioMixMatchCriterionClass);
2474 gAudioMixMatchCriterionFields.mAttr = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mAttr",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002475 "Landroid/media/AudioAttributes;");
Jean-Michel Triviba6b4b42016-02-10 14:26:35 -08002476 gAudioMixMatchCriterionFields.mIntProp = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mIntProp",
2477 "I");
2478 gAudioMixMatchCriterionFields.mRule = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mRule",
Eric Laurent7f5eb9f2014-12-01 19:36:30 -08002479 "I");
Paul McLeanb3ae6d92018-11-05 15:16:59 -07002480 // AudioTrackRoutingProxy methods
2481 gClsAudioTrackRoutingProxy =
2482 android::FindClassOrDie(env, "android/media/AudioTrackRoutingProxy");
2483 // make sure this reference doesn't get deleted
2484 gClsAudioTrackRoutingProxy = (jclass)env->NewGlobalRef(gClsAudioTrackRoutingProxy);
2485
2486 gMidAudioTrackRoutingProxy_ctor =
2487 android::GetMethodIDOrDie(env, gClsAudioTrackRoutingProxy, "<init>", "(J)V");
2488 gMidAudioTrackRoutingProxy_release =
2489 android::GetMethodIDOrDie(env, gClsAudioTrackRoutingProxy, "native_release", "()V");
2490
2491 // AudioRecordRoutingProxy
2492 gClsAudioRecordRoutingProxy =
2493 android::FindClassOrDie(env, "android/media/AudioRecordRoutingProxy");
2494 // make sure this reference doesn't get deleted
2495 gClsAudioRecordRoutingProxy = (jclass)env->NewGlobalRef(gClsAudioRecordRoutingProxy);
2496
2497 gMidAudioRecordRoutingProxy_ctor =
2498 android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "<init>", "(J)V");
2499 gMidAudioRecordRoutingProxy_release =
2500 android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "native_release", "()V");
2501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002502 AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
Glenn Kasten18db49a2012-03-12 16:29:55 -07002503
Andreas Gampeed6b9df2014-11-20 22:02:20 -08002504 RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
2505 return RegisterMethodsOrDie(env, kEventHandlerClassPathName, gEventHandlerMethods,
2506 NELEM(gEventHandlerMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002507}