AudioPolicyService.cpp revision 0a712e0c7f292821ac7a997a75dbe2388378bed4
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 // release mLock before releasing strong reference on the service as 584 // AudioPolicyService destructor calls AudioCommandThread::exit() which 585 // acquires mLock. 586 mLock.unlock(); 587 svc.clear(); 588 mLock.lock(); 589 } else { 590 waitTime = mAudioCommands[0]->mTime - curTime; 591 break; 592 } 593 } 594 595 // release delayed commands wake lock if the queue is empty 596 if (mAudioCommands.isEmpty()) { 597 release_wake_lock(mName.string()); 598 } 599 600 // At this stage we have either an empty command queue or the first command in the queue 601 // has a finite delay. So unless we are exiting it is safe to wait. 602 if (!exitPending()) { 603 ALOGV("AudioCommandThread() going to sleep"); 604 mWaitWorkCV.waitRelative(mLock, waitTime); 605 } 606 } 607 // release delayed commands wake lock before quitting 608 if (!mAudioCommands.isEmpty()) { 609 release_wake_lock(mName.string()); 610 } 611 mLock.unlock(); 612 return false; 613} 614 615status_t AudioPolicyService::AudioCommandThread::dump(int fd) 616{ 617 const size_t SIZE = 256; 618 char buffer[SIZE]; 619 String8 result; 620 621 snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 622 result.append(buffer); 623 write(fd, result.string(), result.size()); 624 625 bool locked = tryLock(mLock); 626 if (!locked) { 627 String8 result2(kCmdDeadlockedString); 628 write(fd, result2.string(), result2.size()); 629 } 630 631 snprintf(buffer, SIZE, "- Commands:\n"); 632 result = String8(buffer); 633 result.append(" Command Time Wait pParam\n"); 634 for (size_t i = 0; i < mAudioCommands.size(); i++) { 635 mAudioCommands[i]->dump(buffer, SIZE); 636 result.append(buffer); 637 } 638 result.append(" Last Command\n"); 639 if (mLastCommand != 0) { 640 mLastCommand->dump(buffer, SIZE); 641 result.append(buffer); 642 } else { 643 result.append(" none\n"); 644 } 645 646 write(fd, result.string(), result.size()); 647 648 if (locked) mLock.unlock(); 649 650 return NO_ERROR; 651} 652 653void AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type, 654 audio_stream_type_t stream) 655{ 656 sp<AudioCommand> command = new AudioCommand(); 657 command->mCommand = START_TONE; 658 sp<ToneData> data = new ToneData(); 659 data->mType = type; 660 data->mStream = stream; 661 command->mParam = data; 662 ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 663 sendCommand(command); 664} 665 666void AudioPolicyService::AudioCommandThread::stopToneCommand() 667{ 668 sp<AudioCommand> command = new AudioCommand(); 669 command->mCommand = STOP_TONE; 670 ALOGV("AudioCommandThread() adding tone stop"); 671 sendCommand(command); 672} 673 674status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream, 675 float volume, 676 audio_io_handle_t output, 677 int delayMs) 678{ 679 sp<AudioCommand> command = new AudioCommand(); 680 command->mCommand = SET_VOLUME; 681 sp<VolumeData> data = new VolumeData(); 682 data->mStream = stream; 683 data->mVolume = volume; 684 data->mIO = output; 685 command->mParam = data; 686 command->mWaitStatus = true; 687 ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 688 stream, volume, output); 689 return sendCommand(command, delayMs); 690} 691 692status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle, 693 const char *keyValuePairs, 694 int delayMs) 695{ 696 sp<AudioCommand> command = new AudioCommand(); 697 command->mCommand = SET_PARAMETERS; 698 sp<ParametersData> data = new ParametersData(); 699 data->mIO = ioHandle; 700 data->mKeyValuePairs = String8(keyValuePairs); 701 command->mParam = data; 702 command->mWaitStatus = true; 703 ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 704 keyValuePairs, ioHandle, delayMs); 705 return sendCommand(command, delayMs); 706} 707 708status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 709{ 710 sp<AudioCommand> command = new AudioCommand(); 711 command->mCommand = SET_VOICE_VOLUME; 712 sp<VoiceVolumeData> data = new VoiceVolumeData(); 713 data->mVolume = volume; 714 command->mParam = data; 715 command->mWaitStatus = true; 716 ALOGV("AudioCommandThread() adding set voice volume volume %f", volume); 717 return sendCommand(command, delayMs); 718} 719 720void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output, 721 audio_stream_type_t stream, 722 audio_session_t session) 723{ 724 sp<AudioCommand> command = new AudioCommand(); 725 command->mCommand = STOP_OUTPUT; 726 sp<StopOutputData> data = new StopOutputData(); 727 data->mIO = output; 728 data->mStream = stream; 729 data->mSession = session; 730 command->mParam = data; 731 ALOGV("AudioCommandThread() adding stop output %d", output); 732 sendCommand(command); 733} 734 735void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output, 736 audio_stream_type_t stream, 737 audio_session_t session) 738{ 739 sp<AudioCommand> command = new AudioCommand(); 740 command->mCommand = RELEASE_OUTPUT; 741 sp<ReleaseOutputData> data = new ReleaseOutputData(); 742 data->mIO = output; 743 data->mStream = stream; 744 data->mSession = session; 745 command->mParam = data; 746 ALOGV("AudioCommandThread() adding release output %d", output); 747 sendCommand(command); 748} 749 750status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand( 751 const struct audio_patch *patch, 752 audio_patch_handle_t *handle, 753 int delayMs) 754{ 755 status_t status = NO_ERROR; 756 757 sp<AudioCommand> command = new AudioCommand(); 758 command->mCommand = CREATE_AUDIO_PATCH; 759 CreateAudioPatchData *data = new CreateAudioPatchData(); 760 data->mPatch = *patch; 761 data->mHandle = *handle; 762 command->mParam = data; 763 command->mWaitStatus = true; 764 ALOGV("AudioCommandThread() adding create patch delay %d", delayMs); 765 status = sendCommand(command, delayMs); 766 if (status == NO_ERROR) { 767 *handle = data->mHandle; 768 } 769 return status; 770} 771 772status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle, 773 int delayMs) 774{ 775 sp<AudioCommand> command = new AudioCommand(); 776 command->mCommand = RELEASE_AUDIO_PATCH; 777 ReleaseAudioPatchData *data = new ReleaseAudioPatchData(); 778 data->mHandle = handle; 779 command->mParam = data; 780 command->mWaitStatus = true; 781 ALOGV("AudioCommandThread() adding release patch delay %d", delayMs); 782 return sendCommand(command, delayMs); 783} 784 785void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand() 786{ 787 sp<AudioCommand> command = new AudioCommand(); 788 command->mCommand = UPDATE_AUDIOPORT_LIST; 789 ALOGV("AudioCommandThread() adding update audio port list"); 790 sendCommand(command); 791} 792 793void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand() 794{ 795 sp<AudioCommand>command = new AudioCommand(); 796 command->mCommand = UPDATE_AUDIOPATCH_LIST; 797 ALOGV("AudioCommandThread() adding update audio patch list"); 798 sendCommand(command); 799} 800 801status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand( 802 const struct audio_port_config *config, int delayMs) 803{ 804 sp<AudioCommand> command = new AudioCommand(); 805 command->mCommand = SET_AUDIOPORT_CONFIG; 806 SetAudioPortConfigData *data = new SetAudioPortConfigData(); 807 data->mConfig = *config; 808 command->mParam = data; 809 command->mWaitStatus = true; 810 ALOGV("AudioCommandThread() adding set port config delay %d", delayMs); 811 return sendCommand(command, delayMs); 812} 813 814void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( 815 String8 regId, int32_t state) 816{ 817 sp<AudioCommand> command = new AudioCommand(); 818 command->mCommand = DYN_POLICY_MIX_STATE_UPDATE; 819 DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData(); 820 data->mRegId = regId; 821 data->mState = state; 822 command->mParam = data; 823 ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d", 824 regId.string(), state); 825 sendCommand(command); 826} 827 828status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) 829{ 830 { 831 Mutex::Autolock _l(mLock); 832 insertCommand_l(command, delayMs); 833 mWaitWorkCV.signal(); 834 } 835 Mutex::Autolock _l(command->mLock); 836 while (command->mWaitStatus) { 837 nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs); 838 if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) { 839 command->mStatus = TIMED_OUT; 840 command->mWaitStatus = false; 841 } 842 } 843 return command->mStatus; 844} 845 846// insertCommand_l() must be called with mLock held 847void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs) 848{ 849 ssize_t i; // not size_t because i will count down to -1 850 Vector < sp<AudioCommand> > removedCommands; 851 command->mTime = systemTime() + milliseconds(delayMs); 852 853 // acquire wake lock to make sure delayed commands are processed 854 if (mAudioCommands.isEmpty()) { 855 acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 856 } 857 858 // check same pending commands with later time stamps and eliminate them 859 for (i = mAudioCommands.size()-1; i >= 0; i--) { 860 sp<AudioCommand> command2 = mAudioCommands[i]; 861 // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 862 if (command2->mTime <= command->mTime) break; 863 864 // create audio patch or release audio patch commands are equivalent 865 // with regard to filtering 866 if ((command->mCommand == CREATE_AUDIO_PATCH) || 867 (command->mCommand == RELEASE_AUDIO_PATCH)) { 868 if ((command2->mCommand != CREATE_AUDIO_PATCH) && 869 (command2->mCommand != RELEASE_AUDIO_PATCH)) { 870 continue; 871 } 872 } else if (command2->mCommand != command->mCommand) continue; 873 874 switch (command->mCommand) { 875 case SET_PARAMETERS: { 876 ParametersData *data = (ParametersData *)command->mParam.get(); 877 ParametersData *data2 = (ParametersData *)command2->mParam.get(); 878 if (data->mIO != data2->mIO) break; 879 ALOGV("Comparing parameter command %s to new command %s", 880 data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 881 AudioParameter param = AudioParameter(data->mKeyValuePairs); 882 AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 883 for (size_t j = 0; j < param.size(); j++) { 884 String8 key; 885 String8 value; 886 param.getAt(j, key, value); 887 for (size_t k = 0; k < param2.size(); k++) { 888 String8 key2; 889 String8 value2; 890 param2.getAt(k, key2, value2); 891 if (key2 == key) { 892 param2.remove(key2); 893 ALOGV("Filtering out parameter %s", key2.string()); 894 break; 895 } 896 } 897 } 898 // if all keys have been filtered out, remove the command. 899 // otherwise, update the key value pairs 900 if (param2.size() == 0) { 901 removedCommands.add(command2); 902 } else { 903 data2->mKeyValuePairs = param2.toString(); 904 } 905 command->mTime = command2->mTime; 906 // force delayMs to non 0 so that code below does not request to wait for 907 // command status as the command is now delayed 908 delayMs = 1; 909 } break; 910 911 case SET_VOLUME: { 912 VolumeData *data = (VolumeData *)command->mParam.get(); 913 VolumeData *data2 = (VolumeData *)command2->mParam.get(); 914 if (data->mIO != data2->mIO) break; 915 if (data->mStream != data2->mStream) break; 916 ALOGV("Filtering out volume command on output %d for stream %d", 917 data->mIO, data->mStream); 918 removedCommands.add(command2); 919 command->mTime = command2->mTime; 920 // force delayMs to non 0 so that code below does not request to wait for 921 // command status as the command is now delayed 922 delayMs = 1; 923 } break; 924 925 case CREATE_AUDIO_PATCH: 926 case RELEASE_AUDIO_PATCH: { 927 audio_patch_handle_t handle; 928 struct audio_patch patch; 929 if (command->mCommand == CREATE_AUDIO_PATCH) { 930 handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle; 931 patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch; 932 } else { 933 handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle; 934 } 935 audio_patch_handle_t handle2; 936 struct audio_patch patch2; 937 if (command2->mCommand == CREATE_AUDIO_PATCH) { 938 handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle; 939 patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch; 940 } else { 941 handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle; 942 memset(&patch2, 0, sizeof(patch2)); 943 } 944 if (handle != handle2) break; 945 /* Filter CREATE_AUDIO_PATCH commands only when they are issued for 946 same output. */ 947 if( (command->mCommand == CREATE_AUDIO_PATCH) && 948 (command2->mCommand == CREATE_AUDIO_PATCH) ) { 949 bool isOutputDiff = false; 950 if (patch.num_sources == patch2.num_sources) { 951 for (unsigned count = 0; count < patch.num_sources; count++) { 952 if (patch.sources[count].id != patch2.sources[count].id) { 953 isOutputDiff = true; 954 break; 955 } 956 } 957 if (isOutputDiff) 958 break; 959 } 960 } 961 ALOGV("Filtering out %s audio patch command for handle %d", 962 (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle); 963 removedCommands.add(command2); 964 command->mTime = command2->mTime; 965 // force delayMs to non 0 so that code below does not request to wait for 966 // command status as the command is now delayed 967 delayMs = 1; 968 } break; 969 970 case DYN_POLICY_MIX_STATE_UPDATE: { 971 972 } break; 973 974 case START_TONE: 975 case STOP_TONE: 976 default: 977 break; 978 } 979 } 980 981 // remove filtered commands 982 for (size_t j = 0; j < removedCommands.size(); j++) { 983 // removed commands always have time stamps greater than current command 984 for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 985 if (mAudioCommands[k].get() == removedCommands[j].get()) { 986 ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 987 mAudioCommands.removeAt(k); 988 break; 989 } 990 } 991 } 992 removedCommands.clear(); 993 994 // Disable wait for status if delay is not 0. 995 // Except for create audio patch command because the returned patch handle 996 // is needed by audio policy manager 997 if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) { 998 command->mWaitStatus = false; 999 } 1000 1001 // insert command at the right place according to its time stamp 1002 ALOGV("inserting command: %d at index %zd, num commands %zu", 1003 command->mCommand, i+1, mAudioCommands.size()); 1004 mAudioCommands.insertAt(command, i + 1); 1005} 1006 1007void AudioPolicyService::AudioCommandThread::exit() 1008{ 1009 ALOGV("AudioCommandThread::exit"); 1010 { 1011 AutoMutex _l(mLock); 1012 requestExit(); 1013 mWaitWorkCV.signal(); 1014 } 1015 // Note that we can call it from the thread loop if all other references have been released 1016 // but it will safely return WOULD_BLOCK in this case 1017 requestExitAndWait(); 1018} 1019 1020void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 1021{ 1022 snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 1023 mCommand, 1024 (int)ns2s(mTime), 1025 (int)ns2ms(mTime)%1000, 1026 mWaitStatus, 1027 mParam.get()); 1028} 1029 1030/******* helpers for the service_ops callbacks defined below *********/ 1031void AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 1032 const char *keyValuePairs, 1033 int delayMs) 1034{ 1035 mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs, 1036 delayMs); 1037} 1038 1039int AudioPolicyService::setStreamVolume(audio_stream_type_t stream, 1040 float volume, 1041 audio_io_handle_t output, 1042 int delayMs) 1043{ 1044 return (int)mAudioCommandThread->volumeCommand(stream, volume, 1045 output, delayMs); 1046} 1047 1048int AudioPolicyService::startTone(audio_policy_tone_t tone, 1049 audio_stream_type_t stream) 1050{ 1051 if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) { 1052 ALOGE("startTone: illegal tone requested (%d)", tone); 1053 } 1054 if (stream != AUDIO_STREAM_VOICE_CALL) { 1055 ALOGE("startTone: illegal stream (%d) requested for tone %d", stream, 1056 tone); 1057 } 1058 mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING, 1059 AUDIO_STREAM_VOICE_CALL); 1060 return 0; 1061} 1062 1063int AudioPolicyService::stopTone() 1064{ 1065 mTonePlaybackThread->stopToneCommand(); 1066 return 0; 1067} 1068 1069int AudioPolicyService::setVoiceVolume(float volume, int delayMs) 1070{ 1071 return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 1072} 1073 1074extern "C" { 1075audio_module_handle_t aps_load_hw_module(void *service __unused, 1076 const char *name); 1077audio_io_handle_t aps_open_output(void *service __unused, 1078 audio_devices_t *pDevices, 1079 uint32_t *pSamplingRate, 1080 audio_format_t *pFormat, 1081 audio_channel_mask_t *pChannelMask, 1082 uint32_t *pLatencyMs, 1083 audio_output_flags_t flags); 1084 1085audio_io_handle_t aps_open_output_on_module(void *service __unused, 1086 audio_module_handle_t module, 1087 audio_devices_t *pDevices, 1088 uint32_t *pSamplingRate, 1089 audio_format_t *pFormat, 1090 audio_channel_mask_t *pChannelMask, 1091 uint32_t *pLatencyMs, 1092 audio_output_flags_t flags, 1093 const audio_offload_info_t *offloadInfo); 1094audio_io_handle_t aps_open_dup_output(void *service __unused, 1095 audio_io_handle_t output1, 1096 audio_io_handle_t output2); 1097int aps_close_output(void *service __unused, audio_io_handle_t output); 1098int aps_suspend_output(void *service __unused, audio_io_handle_t output); 1099int aps_restore_output(void *service __unused, audio_io_handle_t output); 1100audio_io_handle_t aps_open_input(void *service __unused, 1101 audio_devices_t *pDevices, 1102 uint32_t *pSamplingRate, 1103 audio_format_t *pFormat, 1104 audio_channel_mask_t *pChannelMask, 1105 audio_in_acoustics_t acoustics __unused); 1106audio_io_handle_t aps_open_input_on_module(void *service __unused, 1107 audio_module_handle_t module, 1108 audio_devices_t *pDevices, 1109 uint32_t *pSamplingRate, 1110 audio_format_t *pFormat, 1111 audio_channel_mask_t *pChannelMask); 1112int aps_close_input(void *service __unused, audio_io_handle_t input); 1113int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream); 1114int aps_move_effects(void *service __unused, int session, 1115 audio_io_handle_t src_output, 1116 audio_io_handle_t dst_output); 1117char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle, 1118 const char *keys); 1119void aps_set_parameters(void *service, audio_io_handle_t io_handle, 1120 const char *kv_pairs, int delay_ms); 1121int aps_set_stream_volume(void *service, audio_stream_type_t stream, 1122 float volume, audio_io_handle_t output, 1123 int delay_ms); 1124int aps_start_tone(void *service, audio_policy_tone_t tone, 1125 audio_stream_type_t stream); 1126int aps_stop_tone(void *service); 1127int aps_set_voice_volume(void *service, float volume, int delay_ms); 1128}; 1129 1130namespace { 1131 struct audio_policy_service_ops aps_ops = { 1132 .open_output = aps_open_output, 1133 .open_duplicate_output = aps_open_dup_output, 1134 .close_output = aps_close_output, 1135 .suspend_output = aps_suspend_output, 1136 .restore_output = aps_restore_output, 1137 .open_input = aps_open_input, 1138 .close_input = aps_close_input, 1139 .set_stream_volume = aps_set_stream_volume, 1140 .invalidate_stream = aps_invalidate_stream, 1141 .set_parameters = aps_set_parameters, 1142 .get_parameters = aps_get_parameters, 1143 .start_tone = aps_start_tone, 1144 .stop_tone = aps_stop_tone, 1145 .set_voice_volume = aps_set_voice_volume, 1146 .move_effects = aps_move_effects, 1147 .load_hw_module = aps_load_hw_module, 1148 .open_output_on_module = aps_open_output_on_module, 1149 .open_input_on_module = aps_open_input_on_module, 1150 }; 1151}; // namespace <unnamed> 1152 1153}; // namespace android 1154