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