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