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