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