blob: 4ea375184ecc3ee9250d3de1b276d7b48ffd32c5 [file] [log] [blame]
bryant_liuba2b4392014-06-11 16:49:30 +08001/*
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"
Eric Laurent897a4082014-07-11 16:51:53 -070018//#define LOG_NDEBUG 0
bryant_liuba2b4392014-06-11 16:49:30 +080019
20#include <stdlib.h>
21#include <stdio.h>
22#include <string.h>
Kevin Rocard4fb615c2017-06-26 10:28:13 -070023#include <memory>
bryant_liuba2b4392014-06-11 16:49:30 +080024#include <cutils/misc.h>
25#include <media/AudioEffect.h>
Kevin Rocard4fb615c2017-06-26 10:28:13 -070026#include <media/EffectsConfig.h>
Andy Hungab7ef302018-05-15 19:35:29 -070027#include <mediautils/ServiceUtilities.h>
bryant_liuba2b4392014-06-11 16:49:30 +080028#include <system/audio.h>
Mikhail Naganovc2f710f2016-10-17 18:05:36 -070029#include <system/audio_effects/audio_effects_conf.h>
bryant_liuba2b4392014-06-11 16:49:30 +080030#include <utils/Vector.h>
31#include <utils/SortedVector.h>
32#include <cutils/config_utils.h>
Eric Laurentb6436272016-12-07 19:24:50 -080033#include <binder/IPCThreadState.h>
bryant_liuba2b4392014-06-11 16:49:30 +080034#include "AudioPolicyEffects.h"
bryant_liuba2b4392014-06-11 16:49:30 +080035
36namespace android {
37
Svet Ganov3e5f14f2021-05-13 22:51:08 +000038using content::AttributionSourceState;
Philip P. Moltmannbda45752020-07-17 16:41:18 -070039
bryant_liuba2b4392014-06-11 16:49:30 +080040// ----------------------------------------------------------------------------
41// AudioPolicyEffects Implementation
42// ----------------------------------------------------------------------------
43
Shunkai Yao8d6489a2023-04-18 23:14:25 +000044AudioPolicyEffects::AudioPolicyEffects(const sp<EffectsFactoryHalInterface>& effectsFactoryHal) {
45 // load xml config with effectsFactoryHal
46 status_t loadResult = loadAudioEffectConfig(effectsFactoryHal);
François Gaffie06182982020-01-07 15:16:14 +010047 if (loadResult == NO_ERROR) {
Shunkai Yao8d6489a2023-04-18 23:14:25 +000048 mDefaultDeviceEffectFuture =
49 std::async(std::launch::async, &AudioPolicyEffects::initDefaultDeviceEffects, this);
François Gaffie06182982020-01-07 15:16:14 +010050 } else if (loadResult < 0) {
Shunkai Yaoc11621e2023-04-28 01:55:57 +000051 ALOGE("Failed to query effect configuration with status %d", loadResult);
Kevin Rocard4fb615c2017-06-26 10:28:13 -070052 } else if (loadResult > 0) {
53 ALOGE("Effect config is partially invalid, skipped %d elements", loadResult);
bryant_liuba2b4392014-06-11 16:49:30 +080054 }
55}
56
bryant_liuba2b4392014-06-11 16:49:30 +080057AudioPolicyEffects::~AudioPolicyEffects()
58{
59 size_t i = 0;
60 // release audio input processing resources
61 for (i = 0; i < mInputSources.size(); i++) {
62 delete mInputSources.valueAt(i);
63 }
64 mInputSources.clear();
65
Eric Laurentfb66dd92016-01-28 18:32:03 -080066 for (i = 0; i < mInputSessions.size(); i++) {
67 mInputSessions.valueAt(i)->mEffects.clear();
68 delete mInputSessions.valueAt(i);
bryant_liuba2b4392014-06-11 16:49:30 +080069 }
Eric Laurentfb66dd92016-01-28 18:32:03 -080070 mInputSessions.clear();
bryant_liuba2b4392014-06-11 16:49:30 +080071
72 // release audio output processing resources
73 for (i = 0; i < mOutputStreams.size(); i++) {
74 delete mOutputStreams.valueAt(i);
75 }
76 mOutputStreams.clear();
77
78 for (i = 0; i < mOutputSessions.size(); i++) {
79 mOutputSessions.valueAt(i)->mEffects.clear();
80 delete mOutputSessions.valueAt(i);
81 }
82 mOutputSessions.clear();
83}
84
85
86status_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input,
87 audio_source_t inputSource,
Eric Laurentfb66dd92016-01-28 18:32:03 -080088 audio_session_t audioSession)
bryant_liuba2b4392014-06-11 16:49:30 +080089{
90 status_t status = NO_ERROR;
91
92 // create audio pre processors according to input source
93 audio_source_t aliasSource = (inputSource == AUDIO_SOURCE_HOTWORD) ?
94 AUDIO_SOURCE_VOICE_RECOGNITION : inputSource;
95
Eric Laurent8b1e80b2014-10-07 09:08:47 -070096 Mutex::Autolock _l(mLock);
bryant_liuba2b4392014-06-11 16:49:30 +080097 ssize_t index = mInputSources.indexOfKey(aliasSource);
98 if (index < 0) {
99 ALOGV("addInputEffects(): no processing needs to be attached to this source");
100 return status;
101 }
Eric Laurentfb66dd92016-01-28 18:32:03 -0800102 ssize_t idx = mInputSessions.indexOfKey(audioSession);
103 EffectVector *sessionDesc;
bryant_liuba2b4392014-06-11 16:49:30 +0800104 if (idx < 0) {
Eric Laurentfb66dd92016-01-28 18:32:03 -0800105 sessionDesc = new EffectVector(audioSession);
106 mInputSessions.add(audioSession, sessionDesc);
bryant_liuba2b4392014-06-11 16:49:30 +0800107 } else {
bryant_liu890a5632014-08-20 18:06:13 +0800108 // EffectVector is existing and we just need to increase ref count
Eric Laurentfb66dd92016-01-28 18:32:03 -0800109 sessionDesc = mInputSessions.valueAt(idx);
bryant_liuba2b4392014-06-11 16:49:30 +0800110 }
Eric Laurentfb66dd92016-01-28 18:32:03 -0800111 sessionDesc->mRefCount++;
bryant_liu890a5632014-08-20 18:06:13 +0800112
Eric Laurentfb66dd92016-01-28 18:32:03 -0800113 ALOGV("addInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
114 if (sessionDesc->mRefCount == 1) {
Eric Laurentb6436272016-12-07 19:24:50 -0800115 int64_t token = IPCThreadState::self()->clearCallingIdentity();
Eric Laurent7de5ac12014-10-21 09:07:11 -0700116 Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
117 for (size_t i = 0; i < effects.size(); i++) {
118 EffectDesc *effect = effects[i];
Svet Ganov3e5f14f2021-05-13 22:51:08 +0000119 AttributionSourceState attributionSource;
120 attributionSource.packageName = "android";
121 attributionSource.token = sp<BBinder>::make();
122 sp<AudioEffect> fx = new AudioEffect(attributionSource);
Atneya Nair884f7992022-05-17 19:22:42 -0400123 fx->set(nullptr /*type */, &effect->mUuid, -1 /* priority */, nullptr /* callback */,
124 audioSession, input);
Eric Laurent7de5ac12014-10-21 09:07:11 -0700125 status_t status = fx->initCheck();
126 if (status != NO_ERROR && status != ALREADY_EXISTS) {
127 ALOGW("addInputEffects(): failed to create Fx %s on source %d",
128 effect->mName, (int32_t)aliasSource);
129 // fx goes out of scope and strong ref on AudioEffect is released
130 continue;
131 }
132 for (size_t j = 0; j < effect->mParams.size(); j++) {
133 fx->setParameter(effect->mParams[j]);
134 }
135 ALOGV("addInputEffects(): added Fx %s on source: %d",
bryant_liuba2b4392014-06-11 16:49:30 +0800136 effect->mName, (int32_t)aliasSource);
Eric Laurentfb66dd92016-01-28 18:32:03 -0800137 sessionDesc->mEffects.add(fx);
bryant_liuba2b4392014-06-11 16:49:30 +0800138 }
Eric Laurentfb66dd92016-01-28 18:32:03 -0800139 sessionDesc->setProcessorEnabled(true);
Eric Laurentb6436272016-12-07 19:24:50 -0800140 IPCThreadState::self()->restoreCallingIdentity(token);
bryant_liuba2b4392014-06-11 16:49:30 +0800141 }
bryant_liuba2b4392014-06-11 16:49:30 +0800142 return status;
143}
144
145
Eric Laurentfb66dd92016-01-28 18:32:03 -0800146status_t AudioPolicyEffects::releaseInputEffects(audio_io_handle_t input,
147 audio_session_t audioSession)
bryant_liuba2b4392014-06-11 16:49:30 +0800148{
149 status_t status = NO_ERROR;
150
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700151 Mutex::Autolock _l(mLock);
Eric Laurentfb66dd92016-01-28 18:32:03 -0800152 ssize_t index = mInputSessions.indexOfKey(audioSession);
bryant_liuba2b4392014-06-11 16:49:30 +0800153 if (index < 0) {
154 return status;
155 }
Eric Laurentfb66dd92016-01-28 18:32:03 -0800156 EffectVector *sessionDesc = mInputSessions.valueAt(index);
157 sessionDesc->mRefCount--;
158 ALOGV("releaseInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
159 if (sessionDesc->mRefCount == 0) {
160 sessionDesc->setProcessorEnabled(false);
161 delete sessionDesc;
162 mInputSessions.removeItemsAt(index);
bryant_liu890a5632014-08-20 18:06:13 +0800163 ALOGV("releaseInputEffects(): all effects released");
164 }
bryant_liuba2b4392014-06-11 16:49:30 +0800165 return status;
166}
167
Eric Laurentfb66dd92016-01-28 18:32:03 -0800168status_t AudioPolicyEffects::queryDefaultInputEffects(audio_session_t audioSession,
bryant_liuba2b4392014-06-11 16:49:30 +0800169 effect_descriptor_t *descriptors,
170 uint32_t *count)
171{
172 status_t status = NO_ERROR;
173
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700174 Mutex::Autolock _l(mLock);
bryant_liuba2b4392014-06-11 16:49:30 +0800175 size_t index;
Eric Laurentfb66dd92016-01-28 18:32:03 -0800176 for (index = 0; index < mInputSessions.size(); index++) {
177 if (mInputSessions.valueAt(index)->mSessionId == audioSession) {
bryant_liuba2b4392014-06-11 16:49:30 +0800178 break;
179 }
180 }
Eric Laurentfb66dd92016-01-28 18:32:03 -0800181 if (index == mInputSessions.size()) {
bryant_liuba2b4392014-06-11 16:49:30 +0800182 *count = 0;
183 return BAD_VALUE;
184 }
Eric Laurentfb66dd92016-01-28 18:32:03 -0800185 Vector< sp<AudioEffect> > effects = mInputSessions.valueAt(index)->mEffects;
bryant_liuba2b4392014-06-11 16:49:30 +0800186
187 for (size_t i = 0; i < effects.size(); i++) {
188 effect_descriptor_t desc = effects[i]->descriptor();
189 if (i < *count) {
190 descriptors[i] = desc;
191 }
192 }
193 if (effects.size() > *count) {
194 status = NO_MEMORY;
195 }
196 *count = effects.size();
197 return status;
198}
199
200
Eric Laurentfb66dd92016-01-28 18:32:03 -0800201status_t AudioPolicyEffects::queryDefaultOutputSessionEffects(audio_session_t audioSession,
bryant_liuba2b4392014-06-11 16:49:30 +0800202 effect_descriptor_t *descriptors,
203 uint32_t *count)
204{
205 status_t status = NO_ERROR;
206
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700207 Mutex::Autolock _l(mLock);
bryant_liuba2b4392014-06-11 16:49:30 +0800208 size_t index;
209 for (index = 0; index < mOutputSessions.size(); index++) {
210 if (mOutputSessions.valueAt(index)->mSessionId == audioSession) {
211 break;
212 }
213 }
214 if (index == mOutputSessions.size()) {
215 *count = 0;
216 return BAD_VALUE;
217 }
218 Vector< sp<AudioEffect> > effects = mOutputSessions.valueAt(index)->mEffects;
219
220 for (size_t i = 0; i < effects.size(); i++) {
221 effect_descriptor_t desc = effects[i]->descriptor();
222 if (i < *count) {
223 descriptors[i] = desc;
224 }
225 }
226 if (effects.size() > *count) {
227 status = NO_MEMORY;
228 }
229 *count = effects.size();
230 return status;
231}
232
233
234status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
235 audio_stream_type_t stream,
Eric Laurentfb66dd92016-01-28 18:32:03 -0800236 audio_session_t audioSession)
bryant_liuba2b4392014-06-11 16:49:30 +0800237{
238 status_t status = NO_ERROR;
239
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700240 Mutex::Autolock _l(mLock);
bryant_liuba2b4392014-06-11 16:49:30 +0800241 // create audio processors according to stream
Eric Laurent223fd5c2014-11-11 13:43:36 -0800242 // FIXME: should we have specific post processing settings for internal streams?
243 // default to media for now.
244 if (stream >= AUDIO_STREAM_PUBLIC_CNT) {
245 stream = AUDIO_STREAM_MUSIC;
246 }
bryant_liuba2b4392014-06-11 16:49:30 +0800247 ssize_t index = mOutputStreams.indexOfKey(stream);
248 if (index < 0) {
249 ALOGV("addOutputSessionEffects(): no output processing needed for this stream");
250 return NO_ERROR;
251 }
252
253 ssize_t idx = mOutputSessions.indexOfKey(audioSession);
254 EffectVector *procDesc;
255 if (idx < 0) {
256 procDesc = new EffectVector(audioSession);
257 mOutputSessions.add(audioSession, procDesc);
258 } else {
bryant_liu890a5632014-08-20 18:06:13 +0800259 // EffectVector is existing and we just need to increase ref count
bryant_liuba2b4392014-06-11 16:49:30 +0800260 procDesc = mOutputSessions.valueAt(idx);
261 }
bryant_liu890a5632014-08-20 18:06:13 +0800262 procDesc->mRefCount++;
263
Eric Laurent7de5ac12014-10-21 09:07:11 -0700264 ALOGV("addOutputSessionEffects(): session: %d, refCount: %d",
265 audioSession, procDesc->mRefCount);
266 if (procDesc->mRefCount == 1) {
Eric Laurentb6436272016-12-07 19:24:50 -0800267 // make sure effects are associated to audio server even if we are executing a binder call
268 int64_t token = IPCThreadState::self()->clearCallingIdentity();
Eric Laurent7de5ac12014-10-21 09:07:11 -0700269 Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects;
270 for (size_t i = 0; i < effects.size(); i++) {
271 EffectDesc *effect = effects[i];
Svet Ganov3e5f14f2021-05-13 22:51:08 +0000272 AttributionSourceState attributionSource;
273 attributionSource.packageName = "android";
274 attributionSource.token = sp<BBinder>::make();
275 sp<AudioEffect> fx = new AudioEffect(attributionSource);
Atneya Nair884f7992022-05-17 19:22:42 -0400276 fx->set(nullptr /* type */, &effect->mUuid, 0 /* priority */, nullptr /* callback */,
277 audioSession, output);
Eric Laurent7de5ac12014-10-21 09:07:11 -0700278 status_t status = fx->initCheck();
279 if (status != NO_ERROR && status != ALREADY_EXISTS) {
280 ALOGE("addOutputSessionEffects(): failed to create Fx %s on session %d",
281 effect->mName, audioSession);
282 // fx goes out of scope and strong ref on AudioEffect is released
283 continue;
284 }
285 ALOGV("addOutputSessionEffects(): added Fx %s on session: %d for stream: %d",
286 effect->mName, audioSession, (int32_t)stream);
287 procDesc->mEffects.add(fx);
bryant_liuba2b4392014-06-11 16:49:30 +0800288 }
Eric Laurent7de5ac12014-10-21 09:07:11 -0700289
290 procDesc->setProcessorEnabled(true);
Eric Laurentb6436272016-12-07 19:24:50 -0800291 IPCThreadState::self()->restoreCallingIdentity(token);
bryant_liuba2b4392014-06-11 16:49:30 +0800292 }
bryant_liuba2b4392014-06-11 16:49:30 +0800293 return status;
294}
295
296status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output,
297 audio_stream_type_t stream,
Eric Laurentfb66dd92016-01-28 18:32:03 -0800298 audio_session_t audioSession)
bryant_liuba2b4392014-06-11 16:49:30 +0800299{
300 status_t status = NO_ERROR;
301 (void) output; // argument not used for now
302 (void) stream; // argument not used for now
303
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700304 Mutex::Autolock _l(mLock);
bryant_liuba2b4392014-06-11 16:49:30 +0800305 ssize_t index = mOutputSessions.indexOfKey(audioSession);
306 if (index < 0) {
307 ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream");
308 return NO_ERROR;
309 }
310
311 EffectVector *procDesc = mOutputSessions.valueAt(index);
bryant_liu890a5632014-08-20 18:06:13 +0800312 procDesc->mRefCount--;
Eric Laurent7de5ac12014-10-21 09:07:11 -0700313 ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d",
314 audioSession, procDesc->mRefCount);
bryant_liu890a5632014-08-20 18:06:13 +0800315 if (procDesc->mRefCount == 0) {
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700316 procDesc->setProcessorEnabled(false);
bryant_liu890a5632014-08-20 18:06:13 +0800317 procDesc->mEffects.clear();
318 delete procDesc;
319 mOutputSessions.removeItemsAt(index);
320 ALOGV("releaseOutputSessionEffects(): output processing released from session: %d",
321 audioSession);
322 }
bryant_liuba2b4392014-06-11 16:49:30 +0800323 return status;
324}
325
Ari Hausman-Cohen24628312018-08-13 15:01:09 -0700326status_t AudioPolicyEffects::addSourceDefaultEffect(const effect_uuid_t *type,
327 const String16& opPackageName,
328 const effect_uuid_t *uuid,
329 int32_t priority,
330 audio_source_t source,
331 audio_unique_id_t* id)
332{
333 if (uuid == NULL || type == NULL) {
334 ALOGE("addSourceDefaultEffect(): Null uuid or type uuid pointer");
335 return BAD_VALUE;
336 }
337
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800338 // HOTWORD, FM_TUNER and ECHO_REFERENCE are special case sources > MAX.
Ari Hausman-Cohen24628312018-08-13 15:01:09 -0700339 if (source < AUDIO_SOURCE_DEFAULT ||
340 (source > AUDIO_SOURCE_MAX &&
341 source != AUDIO_SOURCE_HOTWORD &&
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800342 source != AUDIO_SOURCE_FM_TUNER &&
Carter Hsua3abb402021-10-26 11:11:20 +0800343 source != AUDIO_SOURCE_ECHO_REFERENCE &&
344 source != AUDIO_SOURCE_ULTRASOUND)) {
Ari Hausman-Cohen24628312018-08-13 15:01:09 -0700345 ALOGE("addSourceDefaultEffect(): Unsupported source type %d", source);
346 return BAD_VALUE;
347 }
348
349 // Check that |uuid| or |type| corresponds to an effect on the system.
350 effect_descriptor_t descriptor = {};
351 status_t res = AudioEffect::getEffectDescriptor(
352 uuid, type, EFFECT_FLAG_TYPE_PRE_PROC, &descriptor);
353 if (res != OK) {
354 ALOGE("addSourceDefaultEffect(): Failed to find effect descriptor matching uuid/type.");
355 return res;
356 }
357
358 // Only pre-processing effects can be added dynamically as source defaults.
359 if ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC) {
360 ALOGE("addSourceDefaultEffect(): Desired effect cannot be attached "
361 "as a source default effect.");
362 return BAD_VALUE;
363 }
364
365 Mutex::Autolock _l(mLock);
366
367 // Find the EffectDescVector for the given source type, or create a new one if necessary.
368 ssize_t index = mInputSources.indexOfKey(source);
369 EffectDescVector *desc = NULL;
370 if (index < 0) {
371 // No effects for this source type yet.
372 desc = new EffectDescVector();
373 mInputSources.add(source, desc);
374 } else {
375 desc = mInputSources.valueAt(index);
376 }
377
378 // Create a new effect and add it to the vector.
379 res = AudioEffect::newEffectUniqueId(id);
380 if (res != OK) {
381 ALOGE("addSourceDefaultEffect(): failed to get new unique id.");
382 return res;
383 }
384 EffectDesc *effect = new EffectDesc(
Eric Laurent2685aa02022-02-01 14:26:38 +0100385 descriptor.name, descriptor.type, opPackageName, descriptor.uuid, priority, *id);
Ari Hausman-Cohen24628312018-08-13 15:01:09 -0700386 desc->mEffects.add(effect);
387 // TODO(b/71813697): Support setting params as well.
388
389 // TODO(b/71814300): Retroactively attach to any existing sources of the given type.
390 // This requires tracking the source type of each session id in addition to what is
391 // already being tracked.
392
393 return NO_ERROR;
394}
395
Ari Hausman-Cohen433722e2018-04-24 14:25:22 -0700396status_t AudioPolicyEffects::addStreamDefaultEffect(const effect_uuid_t *type,
397 const String16& opPackageName,
398 const effect_uuid_t *uuid,
399 int32_t priority,
400 audio_usage_t usage,
401 audio_unique_id_t* id)
402{
403 if (uuid == NULL || type == NULL) {
404 ALOGE("addStreamDefaultEffect(): Null uuid or type uuid pointer");
405 return BAD_VALUE;
406 }
François Gaffie58d4be52018-11-06 15:30:12 +0100407 audio_stream_type_t stream = AudioSystem::attributesToStreamType(attributes_initializer(usage));
Ari Hausman-Cohen433722e2018-04-24 14:25:22 -0700408
409 if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_PUBLIC_CNT) {
410 ALOGE("addStreamDefaultEffect(): Unsupported stream type %d", stream);
411 return BAD_VALUE;
412 }
413
414 // Check that |uuid| or |type| corresponds to an effect on the system.
415 effect_descriptor_t descriptor = {};
416 status_t res = AudioEffect::getEffectDescriptor(
417 uuid, type, EFFECT_FLAG_TYPE_INSERT, &descriptor);
418 if (res != OK) {
419 ALOGE("addStreamDefaultEffect(): Failed to find effect descriptor matching uuid/type.");
420 return res;
421 }
422
423 // Only insert effects can be added dynamically as stream defaults.
424 if ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_INSERT) {
425 ALOGE("addStreamDefaultEffect(): Desired effect cannot be attached "
426 "as a stream default effect.");
427 return BAD_VALUE;
428 }
429
430 Mutex::Autolock _l(mLock);
431
432 // Find the EffectDescVector for the given stream type, or create a new one if necessary.
433 ssize_t index = mOutputStreams.indexOfKey(stream);
434 EffectDescVector *desc = NULL;
435 if (index < 0) {
436 // No effects for this stream type yet.
437 desc = new EffectDescVector();
438 mOutputStreams.add(stream, desc);
439 } else {
440 desc = mOutputStreams.valueAt(index);
441 }
442
443 // Create a new effect and add it to the vector.
444 res = AudioEffect::newEffectUniqueId(id);
445 if (res != OK) {
446 ALOGE("addStreamDefaultEffect(): failed to get new unique id.");
447 return res;
448 }
449 EffectDesc *effect = new EffectDesc(
Eric Laurent2685aa02022-02-01 14:26:38 +0100450 descriptor.name, descriptor.type, opPackageName, descriptor.uuid, priority, *id);
Ari Hausman-Cohen433722e2018-04-24 14:25:22 -0700451 desc->mEffects.add(effect);
452 // TODO(b/71813697): Support setting params as well.
453
454 // TODO(b/71814300): Retroactively attach to any existing streams of the given type.
455 // This requires tracking the stream type of each session id in addition to what is
456 // already being tracked.
457
458 return NO_ERROR;
459}
460
Ari Hausman-Cohen24628312018-08-13 15:01:09 -0700461status_t AudioPolicyEffects::removeSourceDefaultEffect(audio_unique_id_t id)
462{
463 if (id == AUDIO_UNIQUE_ID_ALLOCATE) {
464 // ALLOCATE is not a unique identifier, but rather a reserved value indicating
465 // a real id has not been assigned. For default effects, this value is only used
466 // by system-owned defaults from the loaded config, which cannot be removed.
467 return BAD_VALUE;
468 }
469
470 Mutex::Autolock _l(mLock);
471
472 // Check each source type.
473 size_t numSources = mInputSources.size();
474 for (size_t i = 0; i < numSources; ++i) {
475 // Check each effect for each source.
476 EffectDescVector* descVector = mInputSources[i];
477 for (auto desc = descVector->mEffects.begin(); desc != descVector->mEffects.end(); ++desc) {
478 if ((*desc)->mId == id) {
479 // Found it!
480 // TODO(b/71814300): Remove from any sources the effect was attached to.
481 descVector->mEffects.erase(desc);
482 // Handles are unique; there can only be one match, so return early.
483 return NO_ERROR;
484 }
485 }
486 }
487
488 // Effect wasn't found, so it's been trivially removed successfully.
489 return NO_ERROR;
490}
491
Ari Hausman-Cohen433722e2018-04-24 14:25:22 -0700492status_t AudioPolicyEffects::removeStreamDefaultEffect(audio_unique_id_t id)
493{
494 if (id == AUDIO_UNIQUE_ID_ALLOCATE) {
495 // ALLOCATE is not a unique identifier, but rather a reserved value indicating
496 // a real id has not been assigned. For default effects, this value is only used
497 // by system-owned defaults from the loaded config, which cannot be removed.
498 return BAD_VALUE;
499 }
500
501 Mutex::Autolock _l(mLock);
502
503 // Check each stream type.
504 size_t numStreams = mOutputStreams.size();
505 for (size_t i = 0; i < numStreams; ++i) {
506 // Check each effect for each stream.
507 EffectDescVector* descVector = mOutputStreams[i];
508 for (auto desc = descVector->mEffects.begin(); desc != descVector->mEffects.end(); ++desc) {
509 if ((*desc)->mId == id) {
510 // Found it!
511 // TODO(b/71814300): Remove from any streams the effect was attached to.
512 descVector->mEffects.erase(desc);
513 // Handles are unique; there can only be one match, so return early.
514 return NO_ERROR;
515 }
516 }
517 }
518
519 // Effect wasn't found, so it's been trivially removed successfully.
520 return NO_ERROR;
521}
bryant_liuba2b4392014-06-11 16:49:30 +0800522
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700523void AudioPolicyEffects::EffectVector::setProcessorEnabled(bool enabled)
bryant_liuba2b4392014-06-11 16:49:30 +0800524{
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700525 for (size_t i = 0; i < mEffects.size(); i++) {
526 mEffects.itemAt(i)->setEnabled(enabled);
bryant_liuba2b4392014-06-11 16:49:30 +0800527 }
528}
529
530
531// ----------------------------------------------------------------------------
532// Audio processing configuration
533// ----------------------------------------------------------------------------
534
535/*static*/ const char * const AudioPolicyEffects::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
536 MIC_SRC_TAG,
537 VOICE_UL_SRC_TAG,
538 VOICE_DL_SRC_TAG,
539 VOICE_CALL_SRC_TAG,
540 CAMCORDER_SRC_TAG,
541 VOICE_REC_SRC_TAG,
rago8a397d52015-12-02 11:27:57 -0800542 VOICE_COMM_SRC_TAG,
Carter Hsua3abb402021-10-26 11:11:20 +0800543 REMOTE_SUBMIX_SRC_TAG,
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800544 UNPROCESSED_SRC_TAG,
545 VOICE_PERFORMANCE_SRC_TAG
bryant_liuba2b4392014-06-11 16:49:30 +0800546};
547
548// returns the audio_source_t enum corresponding to the input source name or
549// AUDIO_SOURCE_CNT is no match found
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700550/*static*/ audio_source_t AudioPolicyEffects::inputSourceNameToEnum(const char *name)
bryant_liuba2b4392014-06-11 16:49:30 +0800551{
552 int i;
553 for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
554 if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
555 ALOGV("inputSourceNameToEnum found source %s %d", name, i);
556 break;
557 }
558 }
559 return (audio_source_t)i;
560}
561
Eric Laurent223fd5c2014-11-11 13:43:36 -0800562const char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1] = {
bryant_liuba2b4392014-06-11 16:49:30 +0800563 AUDIO_STREAM_DEFAULT_TAG,
564 AUDIO_STREAM_VOICE_CALL_TAG,
565 AUDIO_STREAM_SYSTEM_TAG,
566 AUDIO_STREAM_RING_TAG,
567 AUDIO_STREAM_MUSIC_TAG,
568 AUDIO_STREAM_ALARM_TAG,
569 AUDIO_STREAM_NOTIFICATION_TAG,
570 AUDIO_STREAM_BLUETOOTH_SCO_TAG,
571 AUDIO_STREAM_ENFORCED_AUDIBLE_TAG,
572 AUDIO_STREAM_DTMF_TAG,
Baekgyeong Kim3a26bb22019-10-30 20:29:41 +0900573 AUDIO_STREAM_TTS_TAG,
574 AUDIO_STREAM_ASSISTANT_TAG
bryant_liuba2b4392014-06-11 16:49:30 +0800575};
576
577// returns the audio_stream_t enum corresponding to the output stream name or
Eric Laurent223fd5c2014-11-11 13:43:36 -0800578// AUDIO_STREAM_PUBLIC_CNT is no match found
bryant_liuba2b4392014-06-11 16:49:30 +0800579audio_stream_type_t AudioPolicyEffects::streamNameToEnum(const char *name)
580{
581 int i;
Eric Laurent223fd5c2014-11-11 13:43:36 -0800582 for (i = AUDIO_STREAM_DEFAULT; i < AUDIO_STREAM_PUBLIC_CNT; i++) {
bryant_liuba2b4392014-06-11 16:49:30 +0800583 if (strcmp(name, kStreamNames[i - AUDIO_STREAM_DEFAULT]) == 0) {
584 ALOGV("streamNameToEnum found stream %s %d", name, i);
585 break;
586 }
587 }
588 return (audio_stream_type_t)i;
589}
590
591// ----------------------------------------------------------------------------
592// Audio Effect Config parser
593// ----------------------------------------------------------------------------
594
Eric Laurent138ed172016-02-10 10:40:44 -0800595size_t AudioPolicyEffects::growParamSize(char **param,
bryant_liuba2b4392014-06-11 16:49:30 +0800596 size_t size,
597 size_t *curSize,
598 size_t *totSize)
599{
600 // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
601 size_t pos = ((*curSize - 1 ) / size + 1) * size;
602
603 if (pos + size > *totSize) {
604 while (pos + size > *totSize) {
605 *totSize += ((*totSize + 7) / 8) * 4;
606 }
George Burgess IV31225682018-02-12 11:08:38 -0800607 char *newParam = (char *)realloc(*param, *totSize);
608 if (newParam == NULL) {
Eric Laurent138ed172016-02-10 10:40:44 -0800609 ALOGE("%s realloc error for size %zu", __func__, *totSize);
610 return 0;
611 }
George Burgess IV31225682018-02-12 11:08:38 -0800612 *param = newParam;
bryant_liuba2b4392014-06-11 16:49:30 +0800613 }
614 *curSize = pos + size;
615 return pos;
616}
617
Eric Laurent138ed172016-02-10 10:40:44 -0800618
bryant_liuba2b4392014-06-11 16:49:30 +0800619size_t AudioPolicyEffects::readParamValue(cnode *node,
Eric Laurent138ed172016-02-10 10:40:44 -0800620 char **param,
bryant_liuba2b4392014-06-11 16:49:30 +0800621 size_t *curSize,
622 size_t *totSize)
623{
Eric Laurent138ed172016-02-10 10:40:44 -0800624 size_t len = 0;
625 size_t pos;
626
bryant_liuba2b4392014-06-11 16:49:30 +0800627 if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
Eric Laurent138ed172016-02-10 10:40:44 -0800628 pos = growParamSize(param, sizeof(short), curSize, totSize);
629 if (pos == 0) {
630 goto exit;
bryant_liuba2b4392014-06-11 16:49:30 +0800631 }
Eric Laurent138ed172016-02-10 10:40:44 -0800632 *(short *)(*param + pos) = (short)atoi(node->value);
633 ALOGV("readParamValue() reading short %d", *(short *)(*param + pos));
634 len = sizeof(short);
635 } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
636 pos = growParamSize(param, sizeof(int), curSize, totSize);
637 if (pos == 0) {
638 goto exit;
639 }
640 *(int *)(*param + pos) = atoi(node->value);
641 ALOGV("readParamValue() reading int %d", *(int *)(*param + pos));
642 len = sizeof(int);
643 } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
644 pos = growParamSize(param, sizeof(float), curSize, totSize);
645 if (pos == 0) {
646 goto exit;
647 }
648 *(float *)(*param + pos) = (float)atof(node->value);
649 ALOGV("readParamValue() reading float %f",*(float *)(*param + pos));
650 len = sizeof(float);
651 } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
652 pos = growParamSize(param, sizeof(bool), curSize, totSize);
653 if (pos == 0) {
654 goto exit;
655 }
656 if (strncmp(node->value, "true", strlen("true") + 1) == 0) {
657 *(bool *)(*param + pos) = true;
658 } else {
659 *(bool *)(*param + pos) = false;
660 }
661 ALOGV("readParamValue() reading bool %s",
662 *(bool *)(*param + pos) ? "true" : "false");
663 len = sizeof(bool);
bryant_liuba2b4392014-06-11 16:49:30 +0800664 } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
Eric Laurent138ed172016-02-10 10:40:44 -0800665 len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
bryant_liuba2b4392014-06-11 16:49:30 +0800666 if (*curSize + len + 1 > *totSize) {
667 *totSize = *curSize + len + 1;
Chih-Hung Hsieh03077682018-08-30 14:11:00 -0700668 char *newParam = (char *)realloc(*param, *totSize);
669 if (newParam == NULL) {
Eric Laurent138ed172016-02-10 10:40:44 -0800670 len = 0;
671 ALOGE("%s realloc error for string len %zu", __func__, *totSize);
672 goto exit;
673 }
Chih-Hung Hsieh03077682018-08-30 14:11:00 -0700674 *param = newParam;
bryant_liuba2b4392014-06-11 16:49:30 +0800675 }
Eric Laurent138ed172016-02-10 10:40:44 -0800676 strncpy(*param + *curSize, node->value, len);
bryant_liuba2b4392014-06-11 16:49:30 +0800677 *curSize += len;
Eric Laurent138ed172016-02-10 10:40:44 -0800678 (*param)[*curSize] = '\0';
679 ALOGV("readParamValue() reading string %s", *param + *curSize - len);
680 } else {
681 ALOGW("readParamValue() unknown param type %s", node->name);
bryant_liuba2b4392014-06-11 16:49:30 +0800682 }
Eric Laurent138ed172016-02-10 10:40:44 -0800683exit:
684 return len;
bryant_liuba2b4392014-06-11 16:49:30 +0800685}
686
687effect_param_t *AudioPolicyEffects::loadEffectParameter(cnode *root)
688{
689 cnode *param;
690 cnode *value;
691 size_t curSize = sizeof(effect_param_t);
692 size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
693 effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
694
Eric Laurent138ed172016-02-10 10:40:44 -0800695 if (fx_param == NULL) {
696 ALOGE("%s malloc error for effect structure of size %zu",
697 __func__, totSize);
698 return NULL;
699 }
700
bryant_liuba2b4392014-06-11 16:49:30 +0800701 param = config_find(root, PARAM_TAG);
702 value = config_find(root, VALUE_TAG);
703 if (param == NULL && value == NULL) {
704 // try to parse simple parameter form {int int}
705 param = root->first_child;
706 if (param != NULL) {
707 // Note: that a pair of random strings is read as 0 0
708 int *ptr = (int *)fx_param->data;
Eric Laurent138ed172016-02-10 10:40:44 -0800709#if LOG_NDEBUG == 0
bryant_liuba2b4392014-06-11 16:49:30 +0800710 int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
Eric Laurent138ed172016-02-10 10:40:44 -0800711 ALOGV("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
712#endif
bryant_liuba2b4392014-06-11 16:49:30 +0800713 *ptr++ = atoi(param->name);
714 *ptr = atoi(param->value);
715 fx_param->psize = sizeof(int);
716 fx_param->vsize = sizeof(int);
717 return fx_param;
718 }
719 }
720 if (param == NULL || value == NULL) {
Eric Laurent138ed172016-02-10 10:40:44 -0800721 ALOGW("loadEffectParameter() invalid parameter description %s",
722 root->name);
bryant_liuba2b4392014-06-11 16:49:30 +0800723 goto error;
724 }
725
726 fx_param->psize = 0;
727 param = param->first_child;
728 while (param) {
729 ALOGV("loadEffectParameter() reading param of type %s", param->name);
Eric Laurent138ed172016-02-10 10:40:44 -0800730 size_t size =
731 readParamValue(param, (char **)&fx_param, &curSize, &totSize);
bryant_liuba2b4392014-06-11 16:49:30 +0800732 if (size == 0) {
733 goto error;
734 }
735 fx_param->psize += size;
736 param = param->next;
737 }
738
739 // align start of value field on 32 bit boundary
740 curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
741
742 fx_param->vsize = 0;
743 value = value->first_child;
744 while (value) {
745 ALOGV("loadEffectParameter() reading value of type %s", value->name);
Eric Laurent138ed172016-02-10 10:40:44 -0800746 size_t size =
747 readParamValue(value, (char **)&fx_param, &curSize, &totSize);
bryant_liuba2b4392014-06-11 16:49:30 +0800748 if (size == 0) {
749 goto error;
750 }
751 fx_param->vsize += size;
752 value = value->next;
753 }
754
755 return fx_param;
756
757error:
Eric Laurent138ed172016-02-10 10:40:44 -0800758 free(fx_param);
bryant_liuba2b4392014-06-11 16:49:30 +0800759 return NULL;
760}
761
762void AudioPolicyEffects::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
763{
764 cnode *node = root->first_child;
765 while (node) {
766 ALOGV("loadEffectParameters() loading param %s", node->name);
767 effect_param_t *param = loadEffectParameter(node);
Eric Laurent138ed172016-02-10 10:40:44 -0800768 if (param != NULL) {
769 params.add(param);
bryant_liuba2b4392014-06-11 16:49:30 +0800770 }
bryant_liuba2b4392014-06-11 16:49:30 +0800771 node = node->next;
772 }
773}
774
775
776AudioPolicyEffects::EffectDescVector *AudioPolicyEffects::loadEffectConfig(
777 cnode *root,
778 const Vector <EffectDesc *>& effects)
779{
780 cnode *node = root->first_child;
781 if (node == NULL) {
782 ALOGW("loadInputSource() empty element %s", root->name);
783 return NULL;
784 }
785 EffectDescVector *desc = new EffectDescVector();
786 while (node) {
787 size_t i;
Eric Laurent138ed172016-02-10 10:40:44 -0800788
bryant_liuba2b4392014-06-11 16:49:30 +0800789 for (i = 0; i < effects.size(); i++) {
790 if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
791 ALOGV("loadEffectConfig() found effect %s in list", node->name);
792 break;
793 }
794 }
795 if (i == effects.size()) {
796 ALOGV("loadEffectConfig() effect %s not in list", node->name);
797 node = node->next;
798 continue;
799 }
800 EffectDesc *effect = new EffectDesc(*effects[i]); // deep copy
801 loadEffectParameters(node, effect->mParams);
802 ALOGV("loadEffectConfig() adding effect %s uuid %08x",
803 effect->mName, effect->mUuid.timeLow);
804 desc->mEffects.add(effect);
805 node = node->next;
806 }
807 if (desc->mEffects.size() == 0) {
808 ALOGW("loadEffectConfig() no valid effects found in config %s", root->name);
809 delete desc;
810 return NULL;
811 }
812 return desc;
813}
814
815status_t AudioPolicyEffects::loadInputEffectConfigurations(cnode *root,
816 const Vector <EffectDesc *>& effects)
817{
818 cnode *node = config_find(root, PREPROCESSING_TAG);
819 if (node == NULL) {
820 return -ENOENT;
821 }
822 node = node->first_child;
823 while (node) {
824 audio_source_t source = inputSourceNameToEnum(node->name);
825 if (source == AUDIO_SOURCE_CNT) {
826 ALOGW("loadInputSources() invalid input source %s", node->name);
827 node = node->next;
828 continue;
829 }
830 ALOGV("loadInputSources() loading input source %s", node->name);
831 EffectDescVector *desc = loadEffectConfig(node, effects);
832 if (desc == NULL) {
833 node = node->next;
834 continue;
835 }
836 mInputSources.add(source, desc);
837 node = node->next;
838 }
839 return NO_ERROR;
840}
841
842status_t AudioPolicyEffects::loadStreamEffectConfigurations(cnode *root,
843 const Vector <EffectDesc *>& effects)
844{
845 cnode *node = config_find(root, OUTPUT_SESSION_PROCESSING_TAG);
846 if (node == NULL) {
847 return -ENOENT;
848 }
849 node = node->first_child;
850 while (node) {
851 audio_stream_type_t stream = streamNameToEnum(node->name);
Eric Laurent223fd5c2014-11-11 13:43:36 -0800852 if (stream == AUDIO_STREAM_PUBLIC_CNT) {
bryant_liuba2b4392014-06-11 16:49:30 +0800853 ALOGW("loadStreamEffectConfigurations() invalid output stream %s", node->name);
854 node = node->next;
855 continue;
856 }
857 ALOGV("loadStreamEffectConfigurations() loading output stream %s", node->name);
858 EffectDescVector *desc = loadEffectConfig(node, effects);
859 if (desc == NULL) {
860 node = node->next;
861 continue;
862 }
863 mOutputStreams.add(stream, desc);
864 node = node->next;
865 }
866 return NO_ERROR;
867}
868
869AudioPolicyEffects::EffectDesc *AudioPolicyEffects::loadEffect(cnode *root)
870{
871 cnode *node = config_find(root, UUID_TAG);
872 if (node == NULL) {
873 return NULL;
874 }
875 effect_uuid_t uuid;
876 if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
877 ALOGW("loadEffect() invalid uuid %s", node->value);
878 return NULL;
879 }
880 return new EffectDesc(root->name, uuid);
881}
882
883status_t AudioPolicyEffects::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
884{
885 cnode *node = config_find(root, EFFECTS_TAG);
886 if (node == NULL) {
887 return -ENOENT;
888 }
889 node = node->first_child;
890 while (node) {
891 ALOGV("loadEffects() loading effect %s", node->name);
892 EffectDesc *effect = loadEffect(node);
893 if (effect == NULL) {
894 node = node->next;
895 continue;
896 }
897 effects.add(effect);
898 node = node->next;
899 }
900 return NO_ERROR;
901}
902
Shunkai Yao8d6489a2023-04-18 23:14:25 +0000903status_t AudioPolicyEffects::loadAudioEffectConfig(
904 const sp<EffectsFactoryHalInterface>& effectsFactoryHal) {
905 if (!effectsFactoryHal) {
906 ALOGE("%s Null EffectsFactoryHalInterface", __func__);
907 return UNEXPECTED_NULL;
908 }
909
910 const auto skippedElements = VALUE_OR_RETURN_STATUS(effectsFactoryHal->getSkippedElements());
911 const auto processings = effectsFactoryHal->getProcessings();
912 if (!processings) {
913 ALOGE("%s Null processings with %zu skipped elements", __func__, skippedElements);
914 return UNEXPECTED_NULL;
Kevin Rocard4fb615c2017-06-26 10:28:13 -0700915 }
916
917 auto loadProcessingChain = [](auto& processingChain, auto& streams) {
918 for (auto& stream : processingChain) {
919 auto effectDescs = std::make_unique<EffectDescVector>();
920 for (auto& effect : stream.effects) {
921 effectDescs->mEffects.add(
922 new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
923 }
924 streams.add(stream.type, effectDescs.release());
925 }
926 };
François Gaffie06182982020-01-07 15:16:14 +0100927
Shunkai Yao8d6489a2023-04-18 23:14:25 +0000928 auto loadDeviceProcessingChain = [](auto& processingChain, auto& devicesEffects) {
François Gaffie06182982020-01-07 15:16:14 +0100929 for (auto& deviceProcess : processingChain) {
François Gaffie06182982020-01-07 15:16:14 +0100930 auto effectDescs = std::make_unique<EffectDescVector>();
931 for (auto& effect : deviceProcess.effects) {
932 effectDescs->mEffects.add(
933 new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
934 }
935 auto deviceEffects = std::make_unique<DeviceEffects>(
936 std::move(effectDescs), deviceProcess.type, deviceProcess.address);
937 devicesEffects.emplace(deviceProcess.address, std::move(deviceEffects));
938 }
939 };
940
Shunkai Yao8d6489a2023-04-18 23:14:25 +0000941 loadProcessingChain(processings->preprocess, mInputSources);
942 loadProcessingChain(processings->postprocess, mOutputStreams);
943
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000944 {
945 Mutex::Autolock _l(mLock);
Shunkai Yao8d6489a2023-04-18 23:14:25 +0000946 loadDeviceProcessingChain(processings->deviceprocess, mDeviceEffects);
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000947 }
Shunkai Yao8d6489a2023-04-18 23:14:25 +0000948
949 return skippedElements;
Kevin Rocard4fb615c2017-06-26 10:28:13 -0700950}
951
François Gaffie06182982020-01-07 15:16:14 +0100952void AudioPolicyEffects::initDefaultDeviceEffects()
953{
954 Mutex::Autolock _l(mLock);
955 for (const auto& deviceEffectsIter : mDeviceEffects) {
956 const auto& deviceEffects = deviceEffectsIter.second;
957 for (const auto& effectDesc : deviceEffects->mEffectDescriptors->mEffects) {
Svet Ganov3e5f14f2021-05-13 22:51:08 +0000958 AttributionSourceState attributionSource;
959 attributionSource.packageName = "android";
960 attributionSource.token = sp<BBinder>::make();
961 sp<AudioEffect> fx = new AudioEffect(attributionSource);
Atneya Nair884f7992022-05-17 19:22:42 -0400962 fx->set(EFFECT_UUID_NULL, &effectDesc->mUuid, 0 /* priority */, nullptr /* callback */,
963 AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
Mikhail Naganov69d41cc2020-07-31 17:36:08 -0700964 AudioDeviceTypeAddr{deviceEffects->getDeviceType(),
965 deviceEffects->getDeviceAddress()});
François Gaffie06182982020-01-07 15:16:14 +0100966 status_t status = fx->initCheck();
967 if (status != NO_ERROR && status != ALREADY_EXISTS) {
968 ALOGE("%s(): failed to create Fx %s on port type=%d address=%s", __func__,
969 effectDesc->mName, deviceEffects->getDeviceType(),
970 deviceEffects->getDeviceAddress().c_str());
971 // fx goes out of scope and strong ref on AudioEffect is released
972 continue;
973 }
974 fx->setEnabled(true);
975 ALOGV("%s(): create Fx %s added on port type=%d address=%s", __func__,
976 effectDesc->mName, deviceEffects->getDeviceType(),
977 deviceEffects->getDeviceAddress().c_str());
Jintao Zhu230397e2021-03-07 14:15:10 +0800978 deviceEffects->mEffects.push_back(fx);
François Gaffie06182982020-01-07 15:16:14 +0100979 }
980 }
981}
bryant_liuba2b4392014-06-11 16:49:30 +0800982
Mikhail Naganov1b2a7942017-12-08 10:18:09 -0800983} // namespace android