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