1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "AudioPolicyEffects"
18 //#define LOG_NDEBUG 0
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <memory>
24 #include <cutils/misc.h>
25 #include <media/AudioEffect.h>
26 #include <media/EffectsConfig.h>
27 #include <mediautils/ServiceUtilities.h>
28 #include <system/audio.h>
29 #include <system/audio_effects/audio_effects_conf.h>
30 #include <utils/Vector.h>
31 #include <utils/SortedVector.h>
32 #include <cutils/config_utils.h>
33 #include <binder/IPCThreadState.h>
34 #include "AudioPolicyEffects.h"
35
36 namespace android {
37
38 using content::AttributionSourceState;
39
40 // ----------------------------------------------------------------------------
41 // AudioPolicyEffects Implementation
42 // ----------------------------------------------------------------------------
43
AudioPolicyEffects()44 AudioPolicyEffects::AudioPolicyEffects()
45 {
46 status_t loadResult = loadAudioEffectXmlConfig();
47 if (loadResult == NO_ERROR) {
48 mDefaultDeviceEffectFuture = std::async(
49 std::launch::async, &AudioPolicyEffects::initDefaultDeviceEffects, this);
50 } else if (loadResult < 0) {
51 ALOGW("Failed to load XML effect configuration, fallback to .conf");
52 // load automatic audio effect modules
53 if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
54 loadAudioEffectConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
55 } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
56 loadAudioEffectConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
57 }
58 } else if (loadResult > 0) {
59 ALOGE("Effect config is partially invalid, skipped %d elements", loadResult);
60 }
61 }
62
63
~AudioPolicyEffects()64 AudioPolicyEffects::~AudioPolicyEffects()
65 {
66 size_t i = 0;
67 // release audio input processing resources
68 for (i = 0; i < mInputSources.size(); i++) {
69 delete mInputSources.valueAt(i);
70 }
71 mInputSources.clear();
72
73 for (i = 0; i < mInputSessions.size(); i++) {
74 mInputSessions.valueAt(i)->mEffects.clear();
75 delete mInputSessions.valueAt(i);
76 }
77 mInputSessions.clear();
78
79 // release audio output processing resources
80 for (i = 0; i < mOutputStreams.size(); i++) {
81 delete mOutputStreams.valueAt(i);
82 }
83 mOutputStreams.clear();
84
85 for (i = 0; i < mOutputSessions.size(); i++) {
86 mOutputSessions.valueAt(i)->mEffects.clear();
87 delete mOutputSessions.valueAt(i);
88 }
89 mOutputSessions.clear();
90 }
91
92
addInputEffects(audio_io_handle_t input,audio_source_t inputSource,audio_session_t audioSession)93 status_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input,
94 audio_source_t inputSource,
95 audio_session_t audioSession)
96 {
97 status_t status = NO_ERROR;
98
99 // create audio pre processors according to input source
100 audio_source_t aliasSource = (inputSource == AUDIO_SOURCE_HOTWORD) ?
101 AUDIO_SOURCE_VOICE_RECOGNITION : inputSource;
102
103 Mutex::Autolock _l(mLock);
104 ssize_t index = mInputSources.indexOfKey(aliasSource);
105 if (index < 0) {
106 ALOGV("addInputEffects(): no processing needs to be attached to this source");
107 return status;
108 }
109 ssize_t idx = mInputSessions.indexOfKey(audioSession);
110 EffectVector *sessionDesc;
111 if (idx < 0) {
112 sessionDesc = new EffectVector(audioSession);
113 mInputSessions.add(audioSession, sessionDesc);
114 } else {
115 // EffectVector is existing and we just need to increase ref count
116 sessionDesc = mInputSessions.valueAt(idx);
117 }
118 sessionDesc->mRefCount++;
119
120 ALOGV("addInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
121 if (sessionDesc->mRefCount == 1) {
122 int64_t token = IPCThreadState::self()->clearCallingIdentity();
123 Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
124 for (size_t i = 0; i < effects.size(); i++) {
125 EffectDesc *effect = effects[i];
126 AttributionSourceState attributionSource;
127 attributionSource.packageName = "android";
128 attributionSource.token = sp<BBinder>::make();
129 sp<AudioEffect> fx = new AudioEffect(attributionSource);
130 fx->set(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
131 status_t status = fx->initCheck();
132 if (status != NO_ERROR && status != ALREADY_EXISTS) {
133 ALOGW("addInputEffects(): failed to create Fx %s on source %d",
134 effect->mName, (int32_t)aliasSource);
135 // fx goes out of scope and strong ref on AudioEffect is released
136 continue;
137 }
138 for (size_t j = 0; j < effect->mParams.size(); j++) {
139 fx->setParameter(effect->mParams[j]);
140 }
141 ALOGV("addInputEffects(): added Fx %s on source: %d",
142 effect->mName, (int32_t)aliasSource);
143 sessionDesc->mEffects.add(fx);
144 }
145 sessionDesc->setProcessorEnabled(true);
146 IPCThreadState::self()->restoreCallingIdentity(token);
147 }
148 return status;
149 }
150
151
releaseInputEffects(audio_io_handle_t input,audio_session_t audioSession)152 status_t AudioPolicyEffects::releaseInputEffects(audio_io_handle_t input,
153 audio_session_t audioSession)
154 {
155 status_t status = NO_ERROR;
156
157 Mutex::Autolock _l(mLock);
158 ssize_t index = mInputSessions.indexOfKey(audioSession);
159 if (index < 0) {
160 return status;
161 }
162 EffectVector *sessionDesc = mInputSessions.valueAt(index);
163 sessionDesc->mRefCount--;
164 ALOGV("releaseInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
165 if (sessionDesc->mRefCount == 0) {
166 sessionDesc->setProcessorEnabled(false);
167 delete sessionDesc;
168 mInputSessions.removeItemsAt(index);
169 ALOGV("releaseInputEffects(): all effects released");
170 }
171 return status;
172 }
173
queryDefaultInputEffects(audio_session_t audioSession,effect_descriptor_t * descriptors,uint32_t * count)174 status_t AudioPolicyEffects::queryDefaultInputEffects(audio_session_t audioSession,
175 effect_descriptor_t *descriptors,
176 uint32_t *count)
177 {
178 status_t status = NO_ERROR;
179
180 Mutex::Autolock _l(mLock);
181 size_t index;
182 for (index = 0; index < mInputSessions.size(); index++) {
183 if (mInputSessions.valueAt(index)->mSessionId == audioSession) {
184 break;
185 }
186 }
187 if (index == mInputSessions.size()) {
188 *count = 0;
189 return BAD_VALUE;
190 }
191 Vector< sp<AudioEffect> > effects = mInputSessions.valueAt(index)->mEffects;
192
193 for (size_t i = 0; i < effects.size(); i++) {
194 effect_descriptor_t desc = effects[i]->descriptor();
195 if (i < *count) {
196 descriptors[i] = desc;
197 }
198 }
199 if (effects.size() > *count) {
200 status = NO_MEMORY;
201 }
202 *count = effects.size();
203 return status;
204 }
205
206
queryDefaultOutputSessionEffects(audio_session_t audioSession,effect_descriptor_t * descriptors,uint32_t * count)207 status_t AudioPolicyEffects::queryDefaultOutputSessionEffects(audio_session_t audioSession,
208 effect_descriptor_t *descriptors,
209 uint32_t *count)
210 {
211 status_t status = NO_ERROR;
212
213 Mutex::Autolock _l(mLock);
214 size_t index;
215 for (index = 0; index < mOutputSessions.size(); index++) {
216 if (mOutputSessions.valueAt(index)->mSessionId == audioSession) {
217 break;
218 }
219 }
220 if (index == mOutputSessions.size()) {
221 *count = 0;
222 return BAD_VALUE;
223 }
224 Vector< sp<AudioEffect> > effects = mOutputSessions.valueAt(index)->mEffects;
225
226 for (size_t i = 0; i < effects.size(); i++) {
227 effect_descriptor_t desc = effects[i]->descriptor();
228 if (i < *count) {
229 descriptors[i] = desc;
230 }
231 }
232 if (effects.size() > *count) {
233 status = NO_MEMORY;
234 }
235 *count = effects.size();
236 return status;
237 }
238
239
addOutputSessionEffects(audio_io_handle_t output,audio_stream_type_t stream,audio_session_t audioSession)240 status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
241 audio_stream_type_t stream,
242 audio_session_t audioSession)
243 {
244 status_t status = NO_ERROR;
245
246 Mutex::Autolock _l(mLock);
247 // create audio processors according to stream
248 // FIXME: should we have specific post processing settings for internal streams?
249 // default to media for now.
250 if (stream >= AUDIO_STREAM_PUBLIC_CNT) {
251 stream = AUDIO_STREAM_MUSIC;
252 }
253 ssize_t index = mOutputStreams.indexOfKey(stream);
254 if (index < 0) {
255 ALOGV("addOutputSessionEffects(): no output processing needed for this stream");
256 return NO_ERROR;
257 }
258
259 ssize_t idx = mOutputSessions.indexOfKey(audioSession);
260 EffectVector *procDesc;
261 if (idx < 0) {
262 procDesc = new EffectVector(audioSession);
263 mOutputSessions.add(audioSession, procDesc);
264 } else {
265 // EffectVector is existing and we just need to increase ref count
266 procDesc = mOutputSessions.valueAt(idx);
267 }
268 procDesc->mRefCount++;
269
270 ALOGV("addOutputSessionEffects(): session: %d, refCount: %d",
271 audioSession, procDesc->mRefCount);
272 if (procDesc->mRefCount == 1) {
273 // make sure effects are associated to audio server even if we are executing a binder call
274 int64_t token = IPCThreadState::self()->clearCallingIdentity();
275 Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects;
276 for (size_t i = 0; i < effects.size(); i++) {
277 EffectDesc *effect = effects[i];
278 AttributionSourceState attributionSource;
279 attributionSource.packageName = "android";
280 attributionSource.token = sp<BBinder>::make();
281 sp<AudioEffect> fx = new AudioEffect(attributionSource);
282 fx->set(NULL, &effect->mUuid, 0, 0, 0, audioSession, output);
283 status_t status = fx->initCheck();
284 if (status != NO_ERROR && status != ALREADY_EXISTS) {
285 ALOGE("addOutputSessionEffects(): failed to create Fx %s on session %d",
286 effect->mName, audioSession);
287 // fx goes out of scope and strong ref on AudioEffect is released
288 continue;
289 }
290 ALOGV("addOutputSessionEffects(): added Fx %s on session: %d for stream: %d",
291 effect->mName, audioSession, (int32_t)stream);
292 procDesc->mEffects.add(fx);
293 }
294
295 procDesc->setProcessorEnabled(true);
296 IPCThreadState::self()->restoreCallingIdentity(token);
297 }
298 return status;
299 }
300
releaseOutputSessionEffects(audio_io_handle_t output,audio_stream_type_t stream,audio_session_t audioSession)301 status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output,
302 audio_stream_type_t stream,
303 audio_session_t audioSession)
304 {
305 status_t status = NO_ERROR;
306 (void) output; // argument not used for now
307 (void) stream; // argument not used for now
308
309 Mutex::Autolock _l(mLock);
310 ssize_t index = mOutputSessions.indexOfKey(audioSession);
311 if (index < 0) {
312 ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream");
313 return NO_ERROR;
314 }
315
316 EffectVector *procDesc = mOutputSessions.valueAt(index);
317 procDesc->mRefCount--;
318 ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d",
319 audioSession, procDesc->mRefCount);
320 if (procDesc->mRefCount == 0) {
321 procDesc->setProcessorEnabled(false);
322 procDesc->mEffects.clear();
323 delete procDesc;
324 mOutputSessions.removeItemsAt(index);
325 ALOGV("releaseOutputSessionEffects(): output processing released from session: %d",
326 audioSession);
327 }
328 return status;
329 }
330
addSourceDefaultEffect(const effect_uuid_t * type,const String16 & opPackageName,const effect_uuid_t * uuid,int32_t priority,audio_source_t source,audio_unique_id_t * id)331 status_t AudioPolicyEffects::addSourceDefaultEffect(const effect_uuid_t *type,
332 const String16& opPackageName,
333 const effect_uuid_t *uuid,
334 int32_t priority,
335 audio_source_t source,
336 audio_unique_id_t* id)
337 {
338 if (uuid == NULL || type == NULL) {
339 ALOGE("addSourceDefaultEffect(): Null uuid or type uuid pointer");
340 return BAD_VALUE;
341 }
342
343 // HOTWORD, FM_TUNER and ECHO_REFERENCE are special case sources > MAX.
344 if (source < AUDIO_SOURCE_DEFAULT ||
345 (source > AUDIO_SOURCE_MAX &&
346 source != AUDIO_SOURCE_HOTWORD &&
347 source != AUDIO_SOURCE_FM_TUNER &&
348 source != AUDIO_SOURCE_ECHO_REFERENCE &&
349 source != AUDIO_SOURCE_ULTRASOUND)) {
350 ALOGE("addSourceDefaultEffect(): Unsupported source type %d", source);
351 return BAD_VALUE;
352 }
353
354 // Check that |uuid| or |type| corresponds to an effect on the system.
355 effect_descriptor_t descriptor = {};
356 status_t res = AudioEffect::getEffectDescriptor(
357 uuid, type, EFFECT_FLAG_TYPE_PRE_PROC, &descriptor);
358 if (res != OK) {
359 ALOGE("addSourceDefaultEffect(): Failed to find effect descriptor matching uuid/type.");
360 return res;
361 }
362
363 // Only pre-processing effects can be added dynamically as source defaults.
364 if ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC) {
365 ALOGE("addSourceDefaultEffect(): Desired effect cannot be attached "
366 "as a source default effect.");
367 return BAD_VALUE;
368 }
369
370 Mutex::Autolock _l(mLock);
371
372 // Find the EffectDescVector for the given source type, or create a new one if necessary.
373 ssize_t index = mInputSources.indexOfKey(source);
374 EffectDescVector *desc = NULL;
375 if (index < 0) {
376 // No effects for this source type yet.
377 desc = new EffectDescVector();
378 mInputSources.add(source, desc);
379 } else {
380 desc = mInputSources.valueAt(index);
381 }
382
383 // Create a new effect and add it to the vector.
384 res = AudioEffect::newEffectUniqueId(id);
385 if (res != OK) {
386 ALOGE("addSourceDefaultEffect(): failed to get new unique id.");
387 return res;
388 }
389 EffectDesc *effect = new EffectDesc(
390 descriptor.name, descriptor.type, opPackageName, descriptor.uuid, priority, *id);
391 desc->mEffects.add(effect);
392 // TODO(b/71813697): Support setting params as well.
393
394 // TODO(b/71814300): Retroactively attach to any existing sources of the given type.
395 // This requires tracking the source type of each session id in addition to what is
396 // already being tracked.
397
398 return NO_ERROR;
399 }
400
addStreamDefaultEffect(const effect_uuid_t * type,const String16 & opPackageName,const effect_uuid_t * uuid,int32_t priority,audio_usage_t usage,audio_unique_id_t * id)401 status_t AudioPolicyEffects::addStreamDefaultEffect(const effect_uuid_t *type,
402 const String16& opPackageName,
403 const effect_uuid_t *uuid,
404 int32_t priority,
405 audio_usage_t usage,
406 audio_unique_id_t* id)
407 {
408 if (uuid == NULL || type == NULL) {
409 ALOGE("addStreamDefaultEffect(): Null uuid or type uuid pointer");
410 return BAD_VALUE;
411 }
412 audio_stream_type_t stream = AudioSystem::attributesToStreamType(attributes_initializer(usage));
413
414 if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_PUBLIC_CNT) {
415 ALOGE("addStreamDefaultEffect(): Unsupported stream type %d", stream);
416 return BAD_VALUE;
417 }
418
419 // Check that |uuid| or |type| corresponds to an effect on the system.
420 effect_descriptor_t descriptor = {};
421 status_t res = AudioEffect::getEffectDescriptor(
422 uuid, type, EFFECT_FLAG_TYPE_INSERT, &descriptor);
423 if (res != OK) {
424 ALOGE("addStreamDefaultEffect(): Failed to find effect descriptor matching uuid/type.");
425 return res;
426 }
427
428 // Only insert effects can be added dynamically as stream defaults.
429 if ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_INSERT) {
430 ALOGE("addStreamDefaultEffect(): Desired effect cannot be attached "
431 "as a stream default effect.");
432 return BAD_VALUE;
433 }
434
435 Mutex::Autolock _l(mLock);
436
437 // Find the EffectDescVector for the given stream type, or create a new one if necessary.
438 ssize_t index = mOutputStreams.indexOfKey(stream);
439 EffectDescVector *desc = NULL;
440 if (index < 0) {
441 // No effects for this stream type yet.
442 desc = new EffectDescVector();
443 mOutputStreams.add(stream, desc);
444 } else {
445 desc = mOutputStreams.valueAt(index);
446 }
447
448 // Create a new effect and add it to the vector.
449 res = AudioEffect::newEffectUniqueId(id);
450 if (res != OK) {
451 ALOGE("addStreamDefaultEffect(): failed to get new unique id.");
452 return res;
453 }
454 EffectDesc *effect = new EffectDesc(
455 descriptor.name, descriptor.type, opPackageName, descriptor.uuid, priority, *id);
456 desc->mEffects.add(effect);
457 // TODO(b/71813697): Support setting params as well.
458
459 // TODO(b/71814300): Retroactively attach to any existing streams of the given type.
460 // This requires tracking the stream type of each session id in addition to what is
461 // already being tracked.
462
463 return NO_ERROR;
464 }
465
removeSourceDefaultEffect(audio_unique_id_t id)466 status_t AudioPolicyEffects::removeSourceDefaultEffect(audio_unique_id_t id)
467 {
468 if (id == AUDIO_UNIQUE_ID_ALLOCATE) {
469 // ALLOCATE is not a unique identifier, but rather a reserved value indicating
470 // a real id has not been assigned. For default effects, this value is only used
471 // by system-owned defaults from the loaded config, which cannot be removed.
472 return BAD_VALUE;
473 }
474
475 Mutex::Autolock _l(mLock);
476
477 // Check each source type.
478 size_t numSources = mInputSources.size();
479 for (size_t i = 0; i < numSources; ++i) {
480 // Check each effect for each source.
481 EffectDescVector* descVector = mInputSources[i];
482 for (auto desc = descVector->mEffects.begin(); desc != descVector->mEffects.end(); ++desc) {
483 if ((*desc)->mId == id) {
484 // Found it!
485 // TODO(b/71814300): Remove from any sources the effect was attached to.
486 descVector->mEffects.erase(desc);
487 // Handles are unique; there can only be one match, so return early.
488 return NO_ERROR;
489 }
490 }
491 }
492
493 // Effect wasn't found, so it's been trivially removed successfully.
494 return NO_ERROR;
495 }
496
removeStreamDefaultEffect(audio_unique_id_t id)497 status_t AudioPolicyEffects::removeStreamDefaultEffect(audio_unique_id_t id)
498 {
499 if (id == AUDIO_UNIQUE_ID_ALLOCATE) {
500 // ALLOCATE is not a unique identifier, but rather a reserved value indicating
501 // a real id has not been assigned. For default effects, this value is only used
502 // by system-owned defaults from the loaded config, which cannot be removed.
503 return BAD_VALUE;
504 }
505
506 Mutex::Autolock _l(mLock);
507
508 // Check each stream type.
509 size_t numStreams = mOutputStreams.size();
510 for (size_t i = 0; i < numStreams; ++i) {
511 // Check each effect for each stream.
512 EffectDescVector* descVector = mOutputStreams[i];
513 for (auto desc = descVector->mEffects.begin(); desc != descVector->mEffects.end(); ++desc) {
514 if ((*desc)->mId == id) {
515 // Found it!
516 // TODO(b/71814300): Remove from any streams the effect was attached to.
517 descVector->mEffects.erase(desc);
518 // Handles are unique; there can only be one match, so return early.
519 return NO_ERROR;
520 }
521 }
522 }
523
524 // Effect wasn't found, so it's been trivially removed successfully.
525 return NO_ERROR;
526 }
527
setProcessorEnabled(bool enabled)528 void AudioPolicyEffects::EffectVector::setProcessorEnabled(bool enabled)
529 {
530 for (size_t i = 0; i < mEffects.size(); i++) {
531 mEffects.itemAt(i)->setEnabled(enabled);
532 }
533 }
534
535
536 // ----------------------------------------------------------------------------
537 // Audio processing configuration
538 // ----------------------------------------------------------------------------
539
540 /*static*/ const char * const AudioPolicyEffects::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
541 MIC_SRC_TAG,
542 VOICE_UL_SRC_TAG,
543 VOICE_DL_SRC_TAG,
544 VOICE_CALL_SRC_TAG,
545 CAMCORDER_SRC_TAG,
546 VOICE_REC_SRC_TAG,
547 VOICE_COMM_SRC_TAG,
548 REMOTE_SUBMIX_SRC_TAG,
549 UNPROCESSED_SRC_TAG,
550 VOICE_PERFORMANCE_SRC_TAG
551 };
552
553 // returns the audio_source_t enum corresponding to the input source name or
554 // AUDIO_SOURCE_CNT is no match found
inputSourceNameToEnum(const char * name)555 /*static*/ audio_source_t AudioPolicyEffects::inputSourceNameToEnum(const char *name)
556 {
557 int i;
558 for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
559 if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
560 ALOGV("inputSourceNameToEnum found source %s %d", name, i);
561 break;
562 }
563 }
564 return (audio_source_t)i;
565 }
566
567 const char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1] = {
568 AUDIO_STREAM_DEFAULT_TAG,
569 AUDIO_STREAM_VOICE_CALL_TAG,
570 AUDIO_STREAM_SYSTEM_TAG,
571 AUDIO_STREAM_RING_TAG,
572 AUDIO_STREAM_MUSIC_TAG,
573 AUDIO_STREAM_ALARM_TAG,
574 AUDIO_STREAM_NOTIFICATION_TAG,
575 AUDIO_STREAM_BLUETOOTH_SCO_TAG,
576 AUDIO_STREAM_ENFORCED_AUDIBLE_TAG,
577 AUDIO_STREAM_DTMF_TAG,
578 AUDIO_STREAM_TTS_TAG,
579 AUDIO_STREAM_ASSISTANT_TAG
580 };
581
582 // returns the audio_stream_t enum corresponding to the output stream name or
583 // AUDIO_STREAM_PUBLIC_CNT is no match found
streamNameToEnum(const char * name)584 audio_stream_type_t AudioPolicyEffects::streamNameToEnum(const char *name)
585 {
586 int i;
587 for (i = AUDIO_STREAM_DEFAULT; i < AUDIO_STREAM_PUBLIC_CNT; i++) {
588 if (strcmp(name, kStreamNames[i - AUDIO_STREAM_DEFAULT]) == 0) {
589 ALOGV("streamNameToEnum found stream %s %d", name, i);
590 break;
591 }
592 }
593 return (audio_stream_type_t)i;
594 }
595
596 // ----------------------------------------------------------------------------
597 // Audio Effect Config parser
598 // ----------------------------------------------------------------------------
599
growParamSize(char ** param,size_t size,size_t * curSize,size_t * totSize)600 size_t AudioPolicyEffects::growParamSize(char **param,
601 size_t size,
602 size_t *curSize,
603 size_t *totSize)
604 {
605 // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
606 size_t pos = ((*curSize - 1 ) / size + 1) * size;
607
608 if (pos + size > *totSize) {
609 while (pos + size > *totSize) {
610 *totSize += ((*totSize + 7) / 8) * 4;
611 }
612 char *newParam = (char *)realloc(*param, *totSize);
613 if (newParam == NULL) {
614 ALOGE("%s realloc error for size %zu", __func__, *totSize);
615 return 0;
616 }
617 *param = newParam;
618 }
619 *curSize = pos + size;
620 return pos;
621 }
622
623
readParamValue(cnode * node,char ** param,size_t * curSize,size_t * totSize)624 size_t AudioPolicyEffects::readParamValue(cnode *node,
625 char **param,
626 size_t *curSize,
627 size_t *totSize)
628 {
629 size_t len = 0;
630 size_t pos;
631
632 if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
633 pos = growParamSize(param, sizeof(short), curSize, totSize);
634 if (pos == 0) {
635 goto exit;
636 }
637 *(short *)(*param + pos) = (short)atoi(node->value);
638 ALOGV("readParamValue() reading short %d", *(short *)(*param + pos));
639 len = sizeof(short);
640 } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
641 pos = growParamSize(param, sizeof(int), curSize, totSize);
642 if (pos == 0) {
643 goto exit;
644 }
645 *(int *)(*param + pos) = atoi(node->value);
646 ALOGV("readParamValue() reading int %d", *(int *)(*param + pos));
647 len = sizeof(int);
648 } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
649 pos = growParamSize(param, sizeof(float), curSize, totSize);
650 if (pos == 0) {
651 goto exit;
652 }
653 *(float *)(*param + pos) = (float)atof(node->value);
654 ALOGV("readParamValue() reading float %f",*(float *)(*param + pos));
655 len = sizeof(float);
656 } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
657 pos = growParamSize(param, sizeof(bool), curSize, totSize);
658 if (pos == 0) {
659 goto exit;
660 }
661 if (strncmp(node->value, "true", strlen("true") + 1) == 0) {
662 *(bool *)(*param + pos) = true;
663 } else {
664 *(bool *)(*param + pos) = false;
665 }
666 ALOGV("readParamValue() reading bool %s",
667 *(bool *)(*param + pos) ? "true" : "false");
668 len = sizeof(bool);
669 } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
670 len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
671 if (*curSize + len + 1 > *totSize) {
672 *totSize = *curSize + len + 1;
673 char *newParam = (char *)realloc(*param, *totSize);
674 if (newParam == NULL) {
675 len = 0;
676 ALOGE("%s realloc error for string len %zu", __func__, *totSize);
677 goto exit;
678 }
679 *param = newParam;
680 }
681 strncpy(*param + *curSize, node->value, len);
682 *curSize += len;
683 (*param)[*curSize] = '\0';
684 ALOGV("readParamValue() reading string %s", *param + *curSize - len);
685 } else {
686 ALOGW("readParamValue() unknown param type %s", node->name);
687 }
688 exit:
689 return len;
690 }
691
loadEffectParameter(cnode * root)692 effect_param_t *AudioPolicyEffects::loadEffectParameter(cnode *root)
693 {
694 cnode *param;
695 cnode *value;
696 size_t curSize = sizeof(effect_param_t);
697 size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
698 effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
699
700 if (fx_param == NULL) {
701 ALOGE("%s malloc error for effect structure of size %zu",
702 __func__, totSize);
703 return NULL;
704 }
705
706 param = config_find(root, PARAM_TAG);
707 value = config_find(root, VALUE_TAG);
708 if (param == NULL && value == NULL) {
709 // try to parse simple parameter form {int int}
710 param = root->first_child;
711 if (param != NULL) {
712 // Note: that a pair of random strings is read as 0 0
713 int *ptr = (int *)fx_param->data;
714 #if LOG_NDEBUG == 0
715 int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
716 ALOGV("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
717 #endif
718 *ptr++ = atoi(param->name);
719 *ptr = atoi(param->value);
720 fx_param->psize = sizeof(int);
721 fx_param->vsize = sizeof(int);
722 return fx_param;
723 }
724 }
725 if (param == NULL || value == NULL) {
726 ALOGW("loadEffectParameter() invalid parameter description %s",
727 root->name);
728 goto error;
729 }
730
731 fx_param->psize = 0;
732 param = param->first_child;
733 while (param) {
734 ALOGV("loadEffectParameter() reading param of type %s", param->name);
735 size_t size =
736 readParamValue(param, (char **)&fx_param, &curSize, &totSize);
737 if (size == 0) {
738 goto error;
739 }
740 fx_param->psize += size;
741 param = param->next;
742 }
743
744 // align start of value field on 32 bit boundary
745 curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
746
747 fx_param->vsize = 0;
748 value = value->first_child;
749 while (value) {
750 ALOGV("loadEffectParameter() reading value of type %s", value->name);
751 size_t size =
752 readParamValue(value, (char **)&fx_param, &curSize, &totSize);
753 if (size == 0) {
754 goto error;
755 }
756 fx_param->vsize += size;
757 value = value->next;
758 }
759
760 return fx_param;
761
762 error:
763 free(fx_param);
764 return NULL;
765 }
766
loadEffectParameters(cnode * root,Vector<effect_param_t * > & params)767 void AudioPolicyEffects::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
768 {
769 cnode *node = root->first_child;
770 while (node) {
771 ALOGV("loadEffectParameters() loading param %s", node->name);
772 effect_param_t *param = loadEffectParameter(node);
773 if (param != NULL) {
774 params.add(param);
775 }
776 node = node->next;
777 }
778 }
779
780
loadEffectConfig(cnode * root,const Vector<EffectDesc * > & effects)781 AudioPolicyEffects::EffectDescVector *AudioPolicyEffects::loadEffectConfig(
782 cnode *root,
783 const Vector <EffectDesc *>& effects)
784 {
785 cnode *node = root->first_child;
786 if (node == NULL) {
787 ALOGW("loadInputSource() empty element %s", root->name);
788 return NULL;
789 }
790 EffectDescVector *desc = new EffectDescVector();
791 while (node) {
792 size_t i;
793
794 for (i = 0; i < effects.size(); i++) {
795 if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
796 ALOGV("loadEffectConfig() found effect %s in list", node->name);
797 break;
798 }
799 }
800 if (i == effects.size()) {
801 ALOGV("loadEffectConfig() effect %s not in list", node->name);
802 node = node->next;
803 continue;
804 }
805 EffectDesc *effect = new EffectDesc(*effects[i]); // deep copy
806 loadEffectParameters(node, effect->mParams);
807 ALOGV("loadEffectConfig() adding effect %s uuid %08x",
808 effect->mName, effect->mUuid.timeLow);
809 desc->mEffects.add(effect);
810 node = node->next;
811 }
812 if (desc->mEffects.size() == 0) {
813 ALOGW("loadEffectConfig() no valid effects found in config %s", root->name);
814 delete desc;
815 return NULL;
816 }
817 return desc;
818 }
819
loadInputEffectConfigurations(cnode * root,const Vector<EffectDesc * > & effects)820 status_t AudioPolicyEffects::loadInputEffectConfigurations(cnode *root,
821 const Vector <EffectDesc *>& effects)
822 {
823 cnode *node = config_find(root, PREPROCESSING_TAG);
824 if (node == NULL) {
825 return -ENOENT;
826 }
827 node = node->first_child;
828 while (node) {
829 audio_source_t source = inputSourceNameToEnum(node->name);
830 if (source == AUDIO_SOURCE_CNT) {
831 ALOGW("loadInputSources() invalid input source %s", node->name);
832 node = node->next;
833 continue;
834 }
835 ALOGV("loadInputSources() loading input source %s", node->name);
836 EffectDescVector *desc = loadEffectConfig(node, effects);
837 if (desc == NULL) {
838 node = node->next;
839 continue;
840 }
841 mInputSources.add(source, desc);
842 node = node->next;
843 }
844 return NO_ERROR;
845 }
846
loadStreamEffectConfigurations(cnode * root,const Vector<EffectDesc * > & effects)847 status_t AudioPolicyEffects::loadStreamEffectConfigurations(cnode *root,
848 const Vector <EffectDesc *>& effects)
849 {
850 cnode *node = config_find(root, OUTPUT_SESSION_PROCESSING_TAG);
851 if (node == NULL) {
852 return -ENOENT;
853 }
854 node = node->first_child;
855 while (node) {
856 audio_stream_type_t stream = streamNameToEnum(node->name);
857 if (stream == AUDIO_STREAM_PUBLIC_CNT) {
858 ALOGW("loadStreamEffectConfigurations() invalid output stream %s", node->name);
859 node = node->next;
860 continue;
861 }
862 ALOGV("loadStreamEffectConfigurations() loading output stream %s", node->name);
863 EffectDescVector *desc = loadEffectConfig(node, effects);
864 if (desc == NULL) {
865 node = node->next;
866 continue;
867 }
868 mOutputStreams.add(stream, desc);
869 node = node->next;
870 }
871 return NO_ERROR;
872 }
873
loadEffect(cnode * root)874 AudioPolicyEffects::EffectDesc *AudioPolicyEffects::loadEffect(cnode *root)
875 {
876 cnode *node = config_find(root, UUID_TAG);
877 if (node == NULL) {
878 return NULL;
879 }
880 effect_uuid_t uuid;
881 if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
882 ALOGW("loadEffect() invalid uuid %s", node->value);
883 return NULL;
884 }
885 return new EffectDesc(root->name, uuid);
886 }
887
loadEffects(cnode * root,Vector<EffectDesc * > & effects)888 status_t AudioPolicyEffects::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
889 {
890 cnode *node = config_find(root, EFFECTS_TAG);
891 if (node == NULL) {
892 return -ENOENT;
893 }
894 node = node->first_child;
895 while (node) {
896 ALOGV("loadEffects() loading effect %s", node->name);
897 EffectDesc *effect = loadEffect(node);
898 if (effect == NULL) {
899 node = node->next;
900 continue;
901 }
902 effects.add(effect);
903 node = node->next;
904 }
905 return NO_ERROR;
906 }
907
loadAudioEffectXmlConfig()908 status_t AudioPolicyEffects::loadAudioEffectXmlConfig() {
909 auto result = effectsConfig::parse();
910 if (result.parsedConfig == nullptr) {
911 return -ENOENT;
912 }
913
914 auto loadProcessingChain = [](auto& processingChain, auto& streams) {
915 for (auto& stream : processingChain) {
916 auto effectDescs = std::make_unique<EffectDescVector>();
917 for (auto& effect : stream.effects) {
918 effectDescs->mEffects.add(
919 new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
920 }
921 streams.add(stream.type, effectDescs.release());
922 }
923 };
924
925 auto loadDeviceProcessingChain = [](auto &processingChain, auto& devicesEffects) {
926 for (auto& deviceProcess : processingChain) {
927
928 auto effectDescs = std::make_unique<EffectDescVector>();
929 for (auto& effect : deviceProcess.effects) {
930 effectDescs->mEffects.add(
931 new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
932 }
933 auto deviceEffects = std::make_unique<DeviceEffects>(
934 std::move(effectDescs), deviceProcess.type, deviceProcess.address);
935 devicesEffects.emplace(deviceProcess.address, std::move(deviceEffects));
936 }
937 };
938
939 loadProcessingChain(result.parsedConfig->preprocess, mInputSources);
940 loadProcessingChain(result.parsedConfig->postprocess, mOutputStreams);
941 {
942 Mutex::Autolock _l(mLock);
943 loadDeviceProcessingChain(result.parsedConfig->deviceprocess, mDeviceEffects);
944 }
945 // Casting from ssize_t to status_t is probably safe, there should not be more than 2^31 errors
946 return result.nbSkippedElement;
947 }
948
loadAudioEffectConfig(const char * path)949 status_t AudioPolicyEffects::loadAudioEffectConfig(const char *path)
950 {
951 cnode *root;
952 char *data;
953
954 data = (char *)load_file(path, NULL);
955 if (data == NULL) {
956 return -ENODEV;
957 }
958 root = config_node("", "");
959 config_load(root, data);
960
961 Vector <EffectDesc *> effects;
962 loadEffects(root, effects);
963 loadInputEffectConfigurations(root, effects);
964 loadStreamEffectConfigurations(root, effects);
965
966 for (size_t i = 0; i < effects.size(); i++) {
967 delete effects[i];
968 }
969
970 config_free(root);
971 free(root);
972 free(data);
973
974 return NO_ERROR;
975 }
976
initDefaultDeviceEffects()977 void AudioPolicyEffects::initDefaultDeviceEffects()
978 {
979 Mutex::Autolock _l(mLock);
980 for (const auto& deviceEffectsIter : mDeviceEffects) {
981 const auto& deviceEffects = deviceEffectsIter.second;
982 for (const auto& effectDesc : deviceEffects->mEffectDescriptors->mEffects) {
983 AttributionSourceState attributionSource;
984 attributionSource.packageName = "android";
985 attributionSource.token = sp<BBinder>::make();
986 sp<AudioEffect> fx = new AudioEffect(attributionSource);
987 fx->set(EFFECT_UUID_NULL, &effectDesc->mUuid, 0, nullptr,
988 nullptr, AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
989 AudioDeviceTypeAddr{deviceEffects->getDeviceType(),
990 deviceEffects->getDeviceAddress()});
991 status_t status = fx->initCheck();
992 if (status != NO_ERROR && status != ALREADY_EXISTS) {
993 ALOGE("%s(): failed to create Fx %s on port type=%d address=%s", __func__,
994 effectDesc->mName, deviceEffects->getDeviceType(),
995 deviceEffects->getDeviceAddress().c_str());
996 // fx goes out of scope and strong ref on AudioEffect is released
997 continue;
998 }
999 fx->setEnabled(true);
1000 ALOGV("%s(): create Fx %s added on port type=%d address=%s", __func__,
1001 effectDesc->mName, deviceEffects->getDeviceType(),
1002 deviceEffects->getDeviceAddress().c_str());
1003 deviceEffects->mEffects.push_back(fx);
1004 }
1005 }
1006 }
1007
1008 } // namespace android
1009