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