AudioPolicyService.cpp revision b52c152d553556b2d227ffc943489de0c60b4b02
1/* 2 * Copyright (C) 2009 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 "AudioPolicyService" 18//#define LOG_NDEBUG 0 19 20#include "Configuration.h" 21#undef __STRICT_ANSI__ 22#define __STDINT_LIMITS 23#define __STDC_LIMIT_MACROS 24#include <stdint.h> 25 26#include <sys/time.h> 27#include <binder/IServiceManager.h> 28#include <utils/Log.h> 29#include <cutils/properties.h> 30#include <binder/IPCThreadState.h> 31#include <utils/String16.h> 32#include <utils/threads.h> 33#include "AudioPolicyService.h" 34#include "ServiceUtilities.h" 35#include <hardware_legacy/power.h> 36#include <media/AudioEffect.h> 37#include <media/EffectsFactoryApi.h> 38 39#include <hardware/hardware.h> 40#include <system/audio.h> 41#include <system/audio_policy.h> 42#include <hardware/audio_policy.h> 43#include <audio_effects/audio_effects_conf.h> 44#include <media/AudioParameter.h> 45 46namespace android { 47 48static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n"; 49static const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n"; 50 51static const int kDumpLockRetries = 50; 52static const int kDumpLockSleepUs = 20000; 53 54static const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds 55 56namespace { 57 extern struct audio_policy_service_ops aps_ops; 58}; 59 60// ---------------------------------------------------------------------------- 61 62AudioPolicyService::AudioPolicyService() 63 : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL), 64 mAudioPolicyManager(NULL), mAudioPolicyClient(NULL) 65{ 66 char value[PROPERTY_VALUE_MAX]; 67 const struct hw_module_t *module; 68 int forced_val; 69 int rc; 70 71 Mutex::Autolock _l(mLock); 72 73 // start tone playback thread 74 mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this); 75 // start audio commands thread 76 mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this); 77 // start output activity command thread 78 mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this); 79 80#ifdef USE_LEGACY_AUDIO_POLICY 81 ALOGI("AudioPolicyService CSTOR in legacy mode"); 82 83 /* instantiate the audio policy manager */ 84 rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module); 85 if (rc) { 86 return; 87 } 88 rc = audio_policy_dev_open(module, &mpAudioPolicyDev); 89 ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc)); 90 if (rc) { 91 return; 92 } 93 94 rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this, 95 &mpAudioPolicy); 96 ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc)); 97 if (rc) { 98 return; 99 } 100 101 rc = mpAudioPolicy->init_check(mpAudioPolicy); 102 ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc)); 103 if (rc) { 104 return; 105 } 106 ALOGI("Loaded audio policy from %s (%s)", module->name, module->id); 107#else 108 ALOGI("AudioPolicyService CSTOR in new mode"); 109 110 mAudioPolicyClient = new AudioPolicyClient(this); 111 mAudioPolicyManager = new AudioPolicyManager(mAudioPolicyClient); 112#endif 113 114 // load audio pre processing modules 115 if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) { 116 loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE); 117 } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) { 118 loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE); 119 } 120} 121 122AudioPolicyService::~AudioPolicyService() 123{ 124 mTonePlaybackThread->exit(); 125 mAudioCommandThread->exit(); 126 mOutputCommandThread->exit(); 127 128 // release audio pre processing resources 129 for (size_t i = 0; i < mInputSources.size(); i++) { 130 delete mInputSources.valueAt(i); 131 } 132 mInputSources.clear(); 133 134 for (size_t i = 0; i < mInputs.size(); i++) { 135 mInputs.valueAt(i)->mEffects.clear(); 136 delete mInputs.valueAt(i); 137 } 138 mInputs.clear(); 139 140#ifdef USE_LEGACY_AUDIO_POLICY 141 if (mpAudioPolicy != NULL && mpAudioPolicyDev != NULL) { 142 mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy); 143 } 144 if (mpAudioPolicyDev != NULL) { 145 audio_policy_dev_close(mpAudioPolicyDev); 146 } 147#else 148 delete mAudioPolicyManager; 149 delete mAudioPolicyClient; 150#endif 151 152 mNotificationClients.clear(); 153} 154 155// A notification client is always registered by AudioSystem when the client process 156// connects to AudioPolicyService. 157void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client) 158{ 159 160 Mutex::Autolock _l(mLock); 161 162 uid_t uid = IPCThreadState::self()->getCallingUid(); 163 if (mNotificationClients.indexOfKey(uid) < 0) { 164 sp<NotificationClient> notificationClient = new NotificationClient(this, 165 client, 166 uid); 167 ALOGV("registerClient() client %p, uid %d", client.get(), uid); 168 169 mNotificationClients.add(uid, notificationClient); 170 171 sp<IBinder> binder = client->asBinder(); 172 binder->linkToDeath(notificationClient); 173 } 174} 175 176// removeNotificationClient() is called when the client process dies. 177void AudioPolicyService::removeNotificationClient(uid_t uid) 178{ 179 Mutex::Autolock _l(mLock); 180 181 mNotificationClients.removeItem(uid); 182 183#ifndef USE_LEGACY_AUDIO_POLICY 184 if (mAudioPolicyManager) { 185 mAudioPolicyManager->clearAudioPatches(uid); 186 } 187#endif 188} 189 190void AudioPolicyService::onAudioPortListUpdate() 191{ 192 mOutputCommandThread->updateAudioPortListCommand(); 193} 194 195void AudioPolicyService::doOnAudioPortListUpdate() 196{ 197 Mutex::Autolock _l(mLock); 198 for (size_t i = 0; i < mNotificationClients.size(); i++) { 199 mNotificationClients.valueAt(i)->onAudioPortListUpdate(); 200 } 201} 202 203void AudioPolicyService::onAudioPatchListUpdate() 204{ 205 mOutputCommandThread->updateAudioPatchListCommand(); 206} 207 208status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch, 209 audio_patch_handle_t *handle, 210 int delayMs) 211{ 212 return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs); 213} 214 215status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle, 216 int delayMs) 217{ 218 return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs); 219} 220 221void AudioPolicyService::doOnAudioPatchListUpdate() 222{ 223 Mutex::Autolock _l(mLock); 224 for (size_t i = 0; i < mNotificationClients.size(); i++) { 225 mNotificationClients.valueAt(i)->onAudioPatchListUpdate(); 226 } 227} 228 229AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service, 230 const sp<IAudioPolicyServiceClient>& client, 231 uid_t uid) 232 : mService(service), mUid(uid), mAudioPolicyServiceClient(client) 233{ 234} 235 236AudioPolicyService::NotificationClient::~NotificationClient() 237{ 238} 239 240void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused) 241{ 242 sp<NotificationClient> keep(this); 243 sp<AudioPolicyService> service = mService.promote(); 244 if (service != 0) { 245 service->removeNotificationClient(mUid); 246 } 247} 248 249void AudioPolicyService::NotificationClient::onAudioPortListUpdate() 250{ 251 if (mAudioPolicyServiceClient != 0) { 252 mAudioPolicyServiceClient->onAudioPortListUpdate(); 253 } 254} 255 256void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() 257{ 258 if (mAudioPolicyServiceClient != 0) { 259 mAudioPolicyServiceClient->onAudioPatchListUpdate(); 260 } 261} 262 263void AudioPolicyService::binderDied(const wp<IBinder>& who) { 264 ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), 265 IPCThreadState::self()->getCallingPid()); 266} 267 268static bool tryLock(Mutex& mutex) 269{ 270 bool locked = false; 271 for (int i = 0; i < kDumpLockRetries; ++i) { 272 if (mutex.tryLock() == NO_ERROR) { 273 locked = true; 274 break; 275 } 276 usleep(kDumpLockSleepUs); 277 } 278 return locked; 279} 280 281status_t AudioPolicyService::dumpInternals(int fd) 282{ 283 const size_t SIZE = 256; 284 char buffer[SIZE]; 285 String8 result; 286 287#ifdef USE_LEGACY_AUDIO_POLICY 288 snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy); 289#else 290 snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager); 291#endif 292 result.append(buffer); 293 snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); 294 result.append(buffer); 295 snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); 296 result.append(buffer); 297 298 write(fd, result.string(), result.size()); 299 return NO_ERROR; 300} 301 302status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused) 303{ 304 if (!dumpAllowed()) { 305 dumpPermissionDenial(fd); 306 } else { 307 bool locked = tryLock(mLock); 308 if (!locked) { 309 String8 result(kDeadlockedString); 310 write(fd, result.string(), result.size()); 311 } 312 313 dumpInternals(fd); 314 if (mAudioCommandThread != 0) { 315 mAudioCommandThread->dump(fd); 316 } 317 if (mTonePlaybackThread != 0) { 318 mTonePlaybackThread->dump(fd); 319 } 320 321#ifdef USE_LEGACY_AUDIO_POLICY 322 if (mpAudioPolicy) { 323 mpAudioPolicy->dump(mpAudioPolicy, fd); 324 } 325#else 326 if (mAudioPolicyManager) { 327 mAudioPolicyManager->dump(fd); 328 } 329#endif 330 331 if (locked) mLock.unlock(); 332 } 333 return NO_ERROR; 334} 335 336status_t AudioPolicyService::dumpPermissionDenial(int fd) 337{ 338 const size_t SIZE = 256; 339 char buffer[SIZE]; 340 String8 result; 341 snprintf(buffer, SIZE, "Permission Denial: " 342 "can't dump AudioPolicyService from pid=%d, uid=%d\n", 343 IPCThreadState::self()->getCallingPid(), 344 IPCThreadState::self()->getCallingUid()); 345 result.append(buffer); 346 write(fd, result.string(), result.size()); 347 return NO_ERROR; 348} 349 350void AudioPolicyService::setPreProcessorEnabled(const InputDesc *inputDesc, bool enabled) 351{ 352 const Vector<sp<AudioEffect> > &fxVector = inputDesc->mEffects; 353 for (size_t i = 0; i < fxVector.size(); i++) { 354 fxVector.itemAt(i)->setEnabled(enabled); 355 } 356} 357 358status_t AudioPolicyService::onTransact( 359 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 360{ 361 return BnAudioPolicyService::onTransact(code, data, reply, flags); 362} 363 364 365// ----------- AudioPolicyService::AudioCommandThread implementation ---------- 366 367AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name, 368 const wp<AudioPolicyService>& service) 369 : Thread(false), mName(name), mService(service) 370{ 371 mpToneGenerator = NULL; 372} 373 374 375AudioPolicyService::AudioCommandThread::~AudioCommandThread() 376{ 377 if (!mAudioCommands.isEmpty()) { 378 release_wake_lock(mName.string()); 379 } 380 mAudioCommands.clear(); 381 delete mpToneGenerator; 382} 383 384void AudioPolicyService::AudioCommandThread::onFirstRef() 385{ 386 run(mName.string(), ANDROID_PRIORITY_AUDIO); 387} 388 389bool AudioPolicyService::AudioCommandThread::threadLoop() 390{ 391 nsecs_t waitTime = INT64_MAX; 392 393 mLock.lock(); 394 while (!exitPending()) 395 { 396 while (!mAudioCommands.isEmpty()) { 397 nsecs_t curTime = systemTime(); 398 // commands are sorted by increasing time stamp: execute them from index 0 and up 399 if (mAudioCommands[0]->mTime <= curTime) { 400 sp<AudioCommand> command = mAudioCommands[0]; 401 mAudioCommands.removeAt(0); 402 mLastCommand = command; 403 404 switch (command->mCommand) { 405 case START_TONE: { 406 mLock.unlock(); 407 ToneData *data = (ToneData *)command->mParam.get(); 408 ALOGV("AudioCommandThread() processing start tone %d on stream %d", 409 data->mType, data->mStream); 410 delete mpToneGenerator; 411 mpToneGenerator = new ToneGenerator(data->mStream, 1.0); 412 mpToneGenerator->startTone(data->mType); 413 mLock.lock(); 414 }break; 415 case STOP_TONE: { 416 mLock.unlock(); 417 ALOGV("AudioCommandThread() processing stop tone"); 418 if (mpToneGenerator != NULL) { 419 mpToneGenerator->stopTone(); 420 delete mpToneGenerator; 421 mpToneGenerator = NULL; 422 } 423 mLock.lock(); 424 }break; 425 case SET_VOLUME: { 426 VolumeData *data = (VolumeData *)command->mParam.get(); 427 ALOGV("AudioCommandThread() processing set volume stream %d, \ 428 volume %f, output %d", data->mStream, data->mVolume, data->mIO); 429 command->mStatus = AudioSystem::setStreamVolume(data->mStream, 430 data->mVolume, 431 data->mIO); 432 }break; 433 case SET_PARAMETERS: { 434 ParametersData *data = (ParametersData *)command->mParam.get(); 435 ALOGV("AudioCommandThread() processing set parameters string %s, io %d", 436 data->mKeyValuePairs.string(), data->mIO); 437 command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); 438 }break; 439 case SET_VOICE_VOLUME: { 440 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 441 ALOGV("AudioCommandThread() processing set voice volume volume %f", 442 data->mVolume); 443 command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); 444 }break; 445 case STOP_OUTPUT: { 446 StopOutputData *data = (StopOutputData *)command->mParam.get(); 447 ALOGV("AudioCommandThread() processing stop output %d", 448 data->mIO); 449 sp<AudioPolicyService> svc = mService.promote(); 450 if (svc == 0) { 451 break; 452 } 453 mLock.unlock(); 454 svc->doStopOutput(data->mIO, data->mStream, data->mSession); 455 mLock.lock(); 456 }break; 457 case RELEASE_OUTPUT: { 458 ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get(); 459 ALOGV("AudioCommandThread() processing release output %d", 460 data->mIO); 461 sp<AudioPolicyService> svc = mService.promote(); 462 if (svc == 0) { 463 break; 464 } 465 mLock.unlock(); 466 svc->doReleaseOutput(data->mIO); 467 mLock.lock(); 468 }break; 469 case CREATE_AUDIO_PATCH: { 470 CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get(); 471 ALOGV("AudioCommandThread() processing create audio patch"); 472 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 473 if (af == 0) { 474 command->mStatus = PERMISSION_DENIED; 475 } else { 476 command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle); 477 } 478 } break; 479 case RELEASE_AUDIO_PATCH: { 480 ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get(); 481 ALOGV("AudioCommandThread() processing release audio patch"); 482 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 483 if (af == 0) { 484 command->mStatus = PERMISSION_DENIED; 485 } else { 486 command->mStatus = af->releaseAudioPatch(data->mHandle); 487 } 488 } break; 489 case UPDATE_AUDIOPORT_LIST: { 490 ALOGV("AudioCommandThread() processing update audio port list"); 491 sp<AudioPolicyService> svc = mService.promote(); 492 if (svc == 0) { 493 break; 494 } 495 mLock.unlock(); 496 svc->doOnAudioPortListUpdate(); 497 mLock.lock(); 498 }break; 499 case UPDATE_AUDIOPATCH_LIST: { 500 ALOGV("AudioCommandThread() processing update audio patch list"); 501 sp<AudioPolicyService> svc = mService.promote(); 502 if (svc == 0) { 503 break; 504 } 505 mLock.unlock(); 506 svc->doOnAudioPatchListUpdate(); 507 mLock.lock(); 508 }break; 509 default: 510 ALOGW("AudioCommandThread() unknown command %d", command->mCommand); 511 } 512 { 513 Mutex::Autolock _l(command->mLock); 514 if (command->mWaitStatus) { 515 command->mWaitStatus = false; 516 command->mCond.signal(); 517 } 518 } 519 waitTime = INT64_MAX; 520 } else { 521 waitTime = mAudioCommands[0]->mTime - curTime; 522 break; 523 } 524 } 525 // release delayed commands wake lock 526 if (mAudioCommands.isEmpty()) { 527 release_wake_lock(mName.string()); 528 } 529 ALOGV("AudioCommandThread() going to sleep"); 530 mWaitWorkCV.waitRelative(mLock, waitTime); 531 ALOGV("AudioCommandThread() waking up"); 532 } 533 mLock.unlock(); 534 return false; 535} 536 537status_t AudioPolicyService::AudioCommandThread::dump(int fd) 538{ 539 const size_t SIZE = 256; 540 char buffer[SIZE]; 541 String8 result; 542 543 snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 544 result.append(buffer); 545 write(fd, result.string(), result.size()); 546 547 bool locked = tryLock(mLock); 548 if (!locked) { 549 String8 result2(kCmdDeadlockedString); 550 write(fd, result2.string(), result2.size()); 551 } 552 553 snprintf(buffer, SIZE, "- Commands:\n"); 554 result = String8(buffer); 555 result.append(" Command Time Wait pParam\n"); 556 for (size_t i = 0; i < mAudioCommands.size(); i++) { 557 mAudioCommands[i]->dump(buffer, SIZE); 558 result.append(buffer); 559 } 560 result.append(" Last Command\n"); 561 if (mLastCommand != 0) { 562 mLastCommand->dump(buffer, SIZE); 563 result.append(buffer); 564 } else { 565 result.append(" none\n"); 566 } 567 568 write(fd, result.string(), result.size()); 569 570 if (locked) mLock.unlock(); 571 572 return NO_ERROR; 573} 574 575void AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type, 576 audio_stream_type_t stream) 577{ 578 sp<AudioCommand> command = new AudioCommand(); 579 command->mCommand = START_TONE; 580 sp<ToneData> data = new ToneData(); 581 data->mType = type; 582 data->mStream = stream; 583 command->mParam = data; 584 ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 585 sendCommand(command); 586} 587 588void AudioPolicyService::AudioCommandThread::stopToneCommand() 589{ 590 sp<AudioCommand> command = new AudioCommand(); 591 command->mCommand = STOP_TONE; 592 ALOGV("AudioCommandThread() adding tone stop"); 593 sendCommand(command); 594} 595 596status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream, 597 float volume, 598 audio_io_handle_t output, 599 int delayMs) 600{ 601 sp<AudioCommand> command = new AudioCommand(); 602 command->mCommand = SET_VOLUME; 603 sp<VolumeData> data = new VolumeData(); 604 data->mStream = stream; 605 data->mVolume = volume; 606 data->mIO = output; 607 command->mParam = data; 608 command->mWaitStatus = true; 609 ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 610 stream, volume, output); 611 return sendCommand(command, delayMs); 612} 613 614status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle, 615 const char *keyValuePairs, 616 int delayMs) 617{ 618 sp<AudioCommand> command = new AudioCommand(); 619 command->mCommand = SET_PARAMETERS; 620 sp<ParametersData> data = new ParametersData(); 621 data->mIO = ioHandle; 622 data->mKeyValuePairs = String8(keyValuePairs); 623 command->mParam = data; 624 command->mWaitStatus = true; 625 ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 626 keyValuePairs, ioHandle, delayMs); 627 return sendCommand(command, delayMs); 628} 629 630status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 631{ 632 sp<AudioCommand> command = new AudioCommand(); 633 command->mCommand = SET_VOICE_VOLUME; 634 sp<VoiceVolumeData> data = new VoiceVolumeData(); 635 data->mVolume = volume; 636 command->mParam = data; 637 command->mWaitStatus = true; 638 ALOGV("AudioCommandThread() adding set voice volume volume %f", volume); 639 return sendCommand(command, delayMs); 640} 641 642void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output, 643 audio_stream_type_t stream, 644 int session) 645{ 646 sp<AudioCommand> command = new AudioCommand(); 647 command->mCommand = STOP_OUTPUT; 648 sp<StopOutputData> data = new StopOutputData(); 649 data->mIO = output; 650 data->mStream = stream; 651 data->mSession = session; 652 command->mParam = data; 653 ALOGV("AudioCommandThread() adding stop output %d", output); 654 sendCommand(command); 655} 656 657void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output) 658{ 659 sp<AudioCommand> command = new AudioCommand(); 660 command->mCommand = RELEASE_OUTPUT; 661 sp<ReleaseOutputData> data = new ReleaseOutputData(); 662 data->mIO = output; 663 command->mParam = data; 664 ALOGV("AudioCommandThread() adding release output %d", output); 665 sendCommand(command); 666} 667 668status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand( 669 const struct audio_patch *patch, 670 audio_patch_handle_t *handle, 671 int delayMs) 672{ 673 status_t status = NO_ERROR; 674 675 sp<AudioCommand> command = new AudioCommand(); 676 command->mCommand = CREATE_AUDIO_PATCH; 677 CreateAudioPatchData *data = new CreateAudioPatchData(); 678 data->mPatch = *patch; 679 data->mHandle = *handle; 680 command->mParam = data; 681 command->mWaitStatus = true; 682 ALOGV("AudioCommandThread() adding create patch delay %d", delayMs); 683 status = sendCommand(command, delayMs); 684 if (status == NO_ERROR) { 685 *handle = data->mHandle; 686 } 687 return status; 688} 689 690status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle, 691 int delayMs) 692{ 693 sp<AudioCommand> command = new AudioCommand(); 694 command->mCommand = RELEASE_AUDIO_PATCH; 695 ReleaseAudioPatchData *data = new ReleaseAudioPatchData(); 696 data->mHandle = handle; 697 command->mParam = data; 698 command->mWaitStatus = true; 699 ALOGV("AudioCommandThread() adding release patch delay %d", delayMs); 700 return sendCommand(command, delayMs); 701} 702 703void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand() 704{ 705 sp<AudioCommand> command = new AudioCommand(); 706 command->mCommand = UPDATE_AUDIOPORT_LIST; 707 ALOGV("AudioCommandThread() adding update audio port list"); 708 sendCommand(command); 709} 710 711void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand() 712{ 713 sp<AudioCommand>command = new AudioCommand(); 714 command->mCommand = UPDATE_AUDIOPATCH_LIST; 715 ALOGV("AudioCommandThread() adding update audio patch list"); 716 sendCommand(command); 717} 718 719status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) 720{ 721 { 722 Mutex::Autolock _l(mLock); 723 insertCommand_l(command, delayMs); 724 mWaitWorkCV.signal(); 725 } 726 Mutex::Autolock _l(command->mLock); 727 while (command->mWaitStatus) { 728 nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs); 729 if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) { 730 command->mStatus = TIMED_OUT; 731 command->mWaitStatus = false; 732 } 733 } 734 return command->mStatus; 735} 736 737// insertCommand_l() must be called with mLock held 738void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs) 739{ 740 ssize_t i; // not size_t because i will count down to -1 741 Vector < sp<AudioCommand> > removedCommands; 742 command->mTime = systemTime() + milliseconds(delayMs); 743 744 // acquire wake lock to make sure delayed commands are processed 745 if (mAudioCommands.isEmpty()) { 746 acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 747 } 748 749 // check same pending commands with later time stamps and eliminate them 750 for (i = mAudioCommands.size()-1; i >= 0; i--) { 751 sp<AudioCommand> command2 = mAudioCommands[i]; 752 // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 753 if (command2->mTime <= command->mTime) break; 754 if (command2->mCommand != command->mCommand) continue; 755 756 switch (command->mCommand) { 757 case SET_PARAMETERS: { 758 ParametersData *data = (ParametersData *)command->mParam.get(); 759 ParametersData *data2 = (ParametersData *)command2->mParam.get(); 760 if (data->mIO != data2->mIO) break; 761 ALOGV("Comparing parameter command %s to new command %s", 762 data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 763 AudioParameter param = AudioParameter(data->mKeyValuePairs); 764 AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 765 for (size_t j = 0; j < param.size(); j++) { 766 String8 key; 767 String8 value; 768 param.getAt(j, key, value); 769 for (size_t k = 0; k < param2.size(); k++) { 770 String8 key2; 771 String8 value2; 772 param2.getAt(k, key2, value2); 773 if (key2 == key) { 774 param2.remove(key2); 775 ALOGV("Filtering out parameter %s", key2.string()); 776 break; 777 } 778 } 779 } 780 // if all keys have been filtered out, remove the command. 781 // otherwise, update the key value pairs 782 if (param2.size() == 0) { 783 removedCommands.add(command2); 784 } else { 785 data2->mKeyValuePairs = param2.toString(); 786 } 787 command->mTime = command2->mTime; 788 // force delayMs to non 0 so that code below does not request to wait for 789 // command status as the command is now delayed 790 delayMs = 1; 791 } break; 792 793 case SET_VOLUME: { 794 VolumeData *data = (VolumeData *)command->mParam.get(); 795 VolumeData *data2 = (VolumeData *)command2->mParam.get(); 796 if (data->mIO != data2->mIO) break; 797 if (data->mStream != data2->mStream) break; 798 ALOGV("Filtering out volume command on output %d for stream %d", 799 data->mIO, data->mStream); 800 removedCommands.add(command2); 801 command->mTime = command2->mTime; 802 // force delayMs to non 0 so that code below does not request to wait for 803 // command status as the command is now delayed 804 delayMs = 1; 805 } break; 806 case START_TONE: 807 case STOP_TONE: 808 default: 809 break; 810 } 811 } 812 813 // remove filtered commands 814 for (size_t j = 0; j < removedCommands.size(); j++) { 815 // removed commands always have time stamps greater than current command 816 for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 817 if (mAudioCommands[k].get() == removedCommands[j].get()) { 818 ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 819 mAudioCommands.removeAt(k); 820 break; 821 } 822 } 823 } 824 removedCommands.clear(); 825 826 // Disable wait for status if delay is not 0 827 if (delayMs != 0) { 828 command->mWaitStatus = false; 829 } 830 831 // insert command at the right place according to its time stamp 832 ALOGV("inserting command: %d at index %d, num commands %d", 833 command->mCommand, (int)i+1, mAudioCommands.size()); 834 mAudioCommands.insertAt(command, i + 1); 835} 836 837void AudioPolicyService::AudioCommandThread::exit() 838{ 839 ALOGV("AudioCommandThread::exit"); 840 { 841 AutoMutex _l(mLock); 842 requestExit(); 843 mWaitWorkCV.signal(); 844 } 845 requestExitAndWait(); 846} 847 848void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 849{ 850 snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 851 mCommand, 852 (int)ns2s(mTime), 853 (int)ns2ms(mTime)%1000, 854 mWaitStatus, 855 mParam.get()); 856} 857 858/******* helpers for the service_ops callbacks defined below *********/ 859void AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 860 const char *keyValuePairs, 861 int delayMs) 862{ 863 mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs, 864 delayMs); 865} 866 867int AudioPolicyService::setStreamVolume(audio_stream_type_t stream, 868 float volume, 869 audio_io_handle_t output, 870 int delayMs) 871{ 872 return (int)mAudioCommandThread->volumeCommand(stream, volume, 873 output, delayMs); 874} 875 876int AudioPolicyService::startTone(audio_policy_tone_t tone, 877 audio_stream_type_t stream) 878{ 879 if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) { 880 ALOGE("startTone: illegal tone requested (%d)", tone); 881 } 882 if (stream != AUDIO_STREAM_VOICE_CALL) { 883 ALOGE("startTone: illegal stream (%d) requested for tone %d", stream, 884 tone); 885 } 886 mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING, 887 AUDIO_STREAM_VOICE_CALL); 888 return 0; 889} 890 891int AudioPolicyService::stopTone() 892{ 893 mTonePlaybackThread->stopToneCommand(); 894 return 0; 895} 896 897int AudioPolicyService::setVoiceVolume(float volume, int delayMs) 898{ 899 return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 900} 901 902// ---------------------------------------------------------------------------- 903// Audio pre-processing configuration 904// ---------------------------------------------------------------------------- 905 906/*static*/ const char * const AudioPolicyService::kInputSourceNames[AUDIO_SOURCE_CNT -1] = { 907 MIC_SRC_TAG, 908 VOICE_UL_SRC_TAG, 909 VOICE_DL_SRC_TAG, 910 VOICE_CALL_SRC_TAG, 911 CAMCORDER_SRC_TAG, 912 VOICE_REC_SRC_TAG, 913 VOICE_COMM_SRC_TAG 914}; 915 916// returns the audio_source_t enum corresponding to the input source name or 917// AUDIO_SOURCE_CNT is no match found 918audio_source_t AudioPolicyService::inputSourceNameToEnum(const char *name) 919{ 920 int i; 921 for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) { 922 if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) { 923 ALOGV("inputSourceNameToEnum found source %s %d", name, i); 924 break; 925 } 926 } 927 return (audio_source_t)i; 928} 929 930size_t AudioPolicyService::growParamSize(char *param, 931 size_t size, 932 size_t *curSize, 933 size_t *totSize) 934{ 935 // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int) 936 size_t pos = ((*curSize - 1 ) / size + 1) * size; 937 938 if (pos + size > *totSize) { 939 while (pos + size > *totSize) { 940 *totSize += ((*totSize + 7) / 8) * 4; 941 } 942 param = (char *)realloc(param, *totSize); 943 } 944 *curSize = pos + size; 945 return pos; 946} 947 948size_t AudioPolicyService::readParamValue(cnode *node, 949 char *param, 950 size_t *curSize, 951 size_t *totSize) 952{ 953 if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) { 954 size_t pos = growParamSize(param, sizeof(short), curSize, totSize); 955 *(short *)((char *)param + pos) = (short)atoi(node->value); 956 ALOGV("readParamValue() reading short %d", *(short *)((char *)param + pos)); 957 return sizeof(short); 958 } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) { 959 size_t pos = growParamSize(param, sizeof(int), curSize, totSize); 960 *(int *)((char *)param + pos) = atoi(node->value); 961 ALOGV("readParamValue() reading int %d", *(int *)((char *)param + pos)); 962 return sizeof(int); 963 } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) { 964 size_t pos = growParamSize(param, sizeof(float), curSize, totSize); 965 *(float *)((char *)param + pos) = (float)atof(node->value); 966 ALOGV("readParamValue() reading float %f",*(float *)((char *)param + pos)); 967 return sizeof(float); 968 } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) { 969 size_t pos = growParamSize(param, sizeof(bool), curSize, totSize); 970 if (strncmp(node->value, "false", strlen("false") + 1) == 0) { 971 *(bool *)((char *)param + pos) = false; 972 } else { 973 *(bool *)((char *)param + pos) = true; 974 } 975 ALOGV("readParamValue() reading bool %s",*(bool *)((char *)param + pos) ? "true" : "false"); 976 return sizeof(bool); 977 } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) { 978 size_t len = strnlen(node->value, EFFECT_STRING_LEN_MAX); 979 if (*curSize + len + 1 > *totSize) { 980 *totSize = *curSize + len + 1; 981 param = (char *)realloc(param, *totSize); 982 } 983 strncpy(param + *curSize, node->value, len); 984 *curSize += len; 985 param[*curSize] = '\0'; 986 ALOGV("readParamValue() reading string %s", param + *curSize - len); 987 return len; 988 } 989 ALOGW("readParamValue() unknown param type %s", node->name); 990 return 0; 991} 992 993effect_param_t *AudioPolicyService::loadEffectParameter(cnode *root) 994{ 995 cnode *param; 996 cnode *value; 997 size_t curSize = sizeof(effect_param_t); 998 size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int); 999 effect_param_t *fx_param = (effect_param_t *)malloc(totSize); 1000 1001 param = config_find(root, PARAM_TAG); 1002 value = config_find(root, VALUE_TAG); 1003 if (param == NULL && value == NULL) { 1004 // try to parse simple parameter form {int int} 1005 param = root->first_child; 1006 if (param != NULL) { 1007 // Note: that a pair of random strings is read as 0 0 1008 int *ptr = (int *)fx_param->data; 1009 int *ptr2 = (int *)((char *)param + sizeof(effect_param_t)); 1010 ALOGW("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2); 1011 *ptr++ = atoi(param->name); 1012 *ptr = atoi(param->value); 1013 fx_param->psize = sizeof(int); 1014 fx_param->vsize = sizeof(int); 1015 return fx_param; 1016 } 1017 } 1018 if (param == NULL || value == NULL) { 1019 ALOGW("loadEffectParameter() invalid parameter description %s", root->name); 1020 goto error; 1021 } 1022 1023 fx_param->psize = 0; 1024 param = param->first_child; 1025 while (param) { 1026 ALOGV("loadEffectParameter() reading param of type %s", param->name); 1027 size_t size = readParamValue(param, (char *)fx_param, &curSize, &totSize); 1028 if (size == 0) { 1029 goto error; 1030 } 1031 fx_param->psize += size; 1032 param = param->next; 1033 } 1034 1035 // align start of value field on 32 bit boundary 1036 curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int); 1037 1038 fx_param->vsize = 0; 1039 value = value->first_child; 1040 while (value) { 1041 ALOGV("loadEffectParameter() reading value of type %s", value->name); 1042 size_t size = readParamValue(value, (char *)fx_param, &curSize, &totSize); 1043 if (size == 0) { 1044 goto error; 1045 } 1046 fx_param->vsize += size; 1047 value = value->next; 1048 } 1049 1050 return fx_param; 1051 1052error: 1053 free(fx_param); 1054 return NULL; 1055} 1056 1057void AudioPolicyService::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params) 1058{ 1059 cnode *node = root->first_child; 1060 while (node) { 1061 ALOGV("loadEffectParameters() loading param %s", node->name); 1062 effect_param_t *param = loadEffectParameter(node); 1063 if (param == NULL) { 1064 node = node->next; 1065 continue; 1066 } 1067 params.add(param); 1068 node = node->next; 1069 } 1070} 1071 1072AudioPolicyService::InputSourceDesc *AudioPolicyService::loadInputSource( 1073 cnode *root, 1074 const Vector <EffectDesc *>& effects) 1075{ 1076 cnode *node = root->first_child; 1077 if (node == NULL) { 1078 ALOGW("loadInputSource() empty element %s", root->name); 1079 return NULL; 1080 } 1081 InputSourceDesc *source = new InputSourceDesc(); 1082 while (node) { 1083 size_t i; 1084 for (i = 0; i < effects.size(); i++) { 1085 if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) { 1086 ALOGV("loadInputSource() found effect %s in list", node->name); 1087 break; 1088 } 1089 } 1090 if (i == effects.size()) { 1091 ALOGV("loadInputSource() effect %s not in list", node->name); 1092 node = node->next; 1093 continue; 1094 } 1095 EffectDesc *effect = new EffectDesc(*effects[i]); // deep copy 1096 loadEffectParameters(node, effect->mParams); 1097 ALOGV("loadInputSource() adding effect %s uuid %08x", effect->mName, effect->mUuid.timeLow); 1098 source->mEffects.add(effect); 1099 node = node->next; 1100 } 1101 if (source->mEffects.size() == 0) { 1102 ALOGW("loadInputSource() no valid effects found in source %s", root->name); 1103 delete source; 1104 return NULL; 1105 } 1106 return source; 1107} 1108 1109status_t AudioPolicyService::loadInputSources(cnode *root, const Vector <EffectDesc *>& effects) 1110{ 1111 cnode *node = config_find(root, PREPROCESSING_TAG); 1112 if (node == NULL) { 1113 return -ENOENT; 1114 } 1115 node = node->first_child; 1116 while (node) { 1117 audio_source_t source = inputSourceNameToEnum(node->name); 1118 if (source == AUDIO_SOURCE_CNT) { 1119 ALOGW("loadInputSources() invalid input source %s", node->name); 1120 node = node->next; 1121 continue; 1122 } 1123 ALOGV("loadInputSources() loading input source %s", node->name); 1124 InputSourceDesc *desc = loadInputSource(node, effects); 1125 if (desc == NULL) { 1126 node = node->next; 1127 continue; 1128 } 1129 mInputSources.add(source, desc); 1130 node = node->next; 1131 } 1132 return NO_ERROR; 1133} 1134 1135AudioPolicyService::EffectDesc *AudioPolicyService::loadEffect(cnode *root) 1136{ 1137 cnode *node = config_find(root, UUID_TAG); 1138 if (node == NULL) { 1139 return NULL; 1140 } 1141 effect_uuid_t uuid; 1142 if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) { 1143 ALOGW("loadEffect() invalid uuid %s", node->value); 1144 return NULL; 1145 } 1146 return new EffectDesc(root->name, uuid); 1147} 1148 1149status_t AudioPolicyService::loadEffects(cnode *root, Vector <EffectDesc *>& effects) 1150{ 1151 cnode *node = config_find(root, EFFECTS_TAG); 1152 if (node == NULL) { 1153 return -ENOENT; 1154 } 1155 node = node->first_child; 1156 while (node) { 1157 ALOGV("loadEffects() loading effect %s", node->name); 1158 EffectDesc *effect = loadEffect(node); 1159 if (effect == NULL) { 1160 node = node->next; 1161 continue; 1162 } 1163 effects.add(effect); 1164 node = node->next; 1165 } 1166 return NO_ERROR; 1167} 1168 1169status_t AudioPolicyService::loadPreProcessorConfig(const char *path) 1170{ 1171 cnode *root; 1172 char *data; 1173 1174 data = (char *)load_file(path, NULL); 1175 if (data == NULL) { 1176 return -ENODEV; 1177 } 1178 root = config_node("", ""); 1179 config_load(root, data); 1180 1181 Vector <EffectDesc *> effects; 1182 loadEffects(root, effects); 1183 loadInputSources(root, effects); 1184 1185 // delete effects to fix memory leak. 1186 // as effects is local var and valgrind would treat this as memory leak 1187 // and although it only did in mediaserver init, but free it in case mediaserver reboot 1188 size_t i; 1189 for (i = 0; i < effects.size(); i++) { 1190 delete effects[i]; 1191 } 1192 1193 config_free(root); 1194 free(root); 1195 free(data); 1196 1197 return NO_ERROR; 1198} 1199 1200extern "C" { 1201audio_module_handle_t aps_load_hw_module(void *service __unused, 1202 const char *name); 1203audio_io_handle_t aps_open_output(void *service __unused, 1204 audio_devices_t *pDevices, 1205 uint32_t *pSamplingRate, 1206 audio_format_t *pFormat, 1207 audio_channel_mask_t *pChannelMask, 1208 uint32_t *pLatencyMs, 1209 audio_output_flags_t flags); 1210 1211audio_io_handle_t aps_open_output_on_module(void *service __unused, 1212 audio_module_handle_t module, 1213 audio_devices_t *pDevices, 1214 uint32_t *pSamplingRate, 1215 audio_format_t *pFormat, 1216 audio_channel_mask_t *pChannelMask, 1217 uint32_t *pLatencyMs, 1218 audio_output_flags_t flags, 1219 const audio_offload_info_t *offloadInfo); 1220audio_io_handle_t aps_open_dup_output(void *service __unused, 1221 audio_io_handle_t output1, 1222 audio_io_handle_t output2); 1223int aps_close_output(void *service __unused, audio_io_handle_t output); 1224int aps_suspend_output(void *service __unused, audio_io_handle_t output); 1225int aps_restore_output(void *service __unused, audio_io_handle_t output); 1226audio_io_handle_t aps_open_input(void *service __unused, 1227 audio_devices_t *pDevices, 1228 uint32_t *pSamplingRate, 1229 audio_format_t *pFormat, 1230 audio_channel_mask_t *pChannelMask, 1231 audio_in_acoustics_t acoustics __unused); 1232audio_io_handle_t aps_open_input_on_module(void *service __unused, 1233 audio_module_handle_t module, 1234 audio_devices_t *pDevices, 1235 uint32_t *pSamplingRate, 1236 audio_format_t *pFormat, 1237 audio_channel_mask_t *pChannelMask); 1238int aps_close_input(void *service __unused, audio_io_handle_t input); 1239int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream); 1240int aps_move_effects(void *service __unused, int session, 1241 audio_io_handle_t src_output, 1242 audio_io_handle_t dst_output); 1243char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle, 1244 const char *keys); 1245void aps_set_parameters(void *service, audio_io_handle_t io_handle, 1246 const char *kv_pairs, int delay_ms); 1247int aps_set_stream_volume(void *service, audio_stream_type_t stream, 1248 float volume, audio_io_handle_t output, 1249 int delay_ms); 1250int aps_start_tone(void *service, audio_policy_tone_t tone, 1251 audio_stream_type_t stream); 1252int aps_stop_tone(void *service); 1253int aps_set_voice_volume(void *service, float volume, int delay_ms); 1254}; 1255 1256namespace { 1257 struct audio_policy_service_ops aps_ops = { 1258 .open_output = aps_open_output, 1259 .open_duplicate_output = aps_open_dup_output, 1260 .close_output = aps_close_output, 1261 .suspend_output = aps_suspend_output, 1262 .restore_output = aps_restore_output, 1263 .open_input = aps_open_input, 1264 .close_input = aps_close_input, 1265 .set_stream_volume = aps_set_stream_volume, 1266 .invalidate_stream = aps_invalidate_stream, 1267 .set_parameters = aps_set_parameters, 1268 .get_parameters = aps_get_parameters, 1269 .start_tone = aps_start_tone, 1270 .stop_tone = aps_stop_tone, 1271 .set_voice_volume = aps_set_voice_volume, 1272 .move_effects = aps_move_effects, 1273 .load_hw_module = aps_load_hw_module, 1274 .open_output_on_module = aps_open_output_on_module, 1275 .open_input_on_module = aps_open_input_on_module, 1276 }; 1277}; // namespace <unnamed> 1278 1279}; // namespace android 1280