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