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