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 #undef __STRICT_ANSI__ 21 #define __STDINT_LIMITS 22 #define __STDC_LIMIT_MACROS 23 #include <stdint.h> 24 25 #include <sys/time.h> 26 #include <binder/IServiceManager.h> 27 #include <utils/Log.h> 28 #include <cutils/properties.h> 29 #include <binder/IPCThreadState.h> 30 #include <utils/String16.h> 31 #include <utils/threads.h> 32 #include "AudioPolicyService.h" 33 #include <hardware_legacy/AudioPolicyManagerBase.h> 34 #include <cutils/properties.h> 35 #include <dlfcn.h> 36 #include <hardware_legacy/power.h> 37 38 // ---------------------------------------------------------------------------- 39 // the sim build doesn't have gettid 40 41 #ifndef HAVE_GETTID 42 # define gettid getpid 43 #endif 44 45 namespace android { 46 47 48 static const char *kDeadlockedString = "AudioPolicyService may be deadlocked\n"; 49 static const char *kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n"; 50 51 static const int kDumpLockRetries = 50; 52 static const int kDumpLockSleep = 20000; 53 54 static bool checkPermission() { 55 #ifndef HAVE_ANDROID_OS 56 return true; 57 #endif 58 if (getpid() == IPCThreadState::self()->getCallingPid()) return true; 59 bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")); 60 if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS"); 61 return ok; 62 } 63 64 // ---------------------------------------------------------------------------- 65 66 AudioPolicyService::AudioPolicyService() 67 : BnAudioPolicyService() , mpPolicyManager(NULL) 68 { 69 char value[PROPERTY_VALUE_MAX]; 70 71 // start tone playback thread 72 mTonePlaybackThread = new AudioCommandThread(String8("")); 73 // start audio commands thread 74 mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread")); 75 76 #if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST) 77 mpPolicyManager = new AudioPolicyManagerBase(this); 78 LOGV("build for GENERIC_AUDIO - using generic audio policy"); 79 #else 80 // if running in emulation - use the emulator driver 81 if (property_get("ro.kernel.qemu", value, 0)) { 82 LOGV("Running in emulation - using generic audio policy"); 83 mpPolicyManager = new AudioPolicyManagerBase(this); 84 } 85 else { 86 LOGV("Using hardware specific audio policy"); 87 mpPolicyManager = createAudioPolicyManager(this); 88 } 89 #endif 90 91 // load properties 92 property_get("ro.camera.sound.forced", value, "0"); 93 mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value); 94 } 95 96 AudioPolicyService::~AudioPolicyService() 97 { 98 mTonePlaybackThread->exit(); 99 mTonePlaybackThread.clear(); 100 mAudioCommandThread->exit(); 101 mAudioCommandThread.clear(); 102 103 if (mpPolicyManager) { 104 delete mpPolicyManager; 105 } 106 } 107 108 109 status_t AudioPolicyService::setDeviceConnectionState(AudioSystem::audio_devices device, 110 AudioSystem::device_connection_state state, 111 const char *device_address) 112 { 113 if (mpPolicyManager == NULL) { 114 return NO_INIT; 115 } 116 if (!checkPermission()) { 117 return PERMISSION_DENIED; 118 } 119 if (!AudioSystem::isOutputDevice(device) && !AudioSystem::isInputDevice(device)) { 120 return BAD_VALUE; 121 } 122 if (state != AudioSystem::DEVICE_STATE_AVAILABLE && 123 state != AudioSystem::DEVICE_STATE_UNAVAILABLE) { 124 return BAD_VALUE; 125 } 126 127 LOGV("setDeviceConnectionState() tid %d", gettid()); 128 Mutex::Autolock _l(mLock); 129 return mpPolicyManager->setDeviceConnectionState(device, state, device_address); 130 } 131 132 AudioSystem::device_connection_state AudioPolicyService::getDeviceConnectionState( 133 AudioSystem::audio_devices device, 134 const char *device_address) 135 { 136 if (mpPolicyManager == NULL) { 137 return AudioSystem::DEVICE_STATE_UNAVAILABLE; 138 } 139 if (!checkPermission()) { 140 return AudioSystem::DEVICE_STATE_UNAVAILABLE; 141 } 142 return mpPolicyManager->getDeviceConnectionState(device, device_address); 143 } 144 145 status_t AudioPolicyService::setPhoneState(int state) 146 { 147 if (mpPolicyManager == NULL) { 148 return NO_INIT; 149 } 150 if (!checkPermission()) { 151 return PERMISSION_DENIED; 152 } 153 if (state < 0 || state >= AudioSystem::NUM_MODES) { 154 return BAD_VALUE; 155 } 156 157 LOGV("setPhoneState() tid %d", gettid()); 158 159 // TODO: check if it is more appropriate to do it in platform specific policy manager 160 AudioSystem::setMode(state); 161 162 Mutex::Autolock _l(mLock); 163 mpPolicyManager->setPhoneState(state); 164 return NO_ERROR; 165 } 166 167 status_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask) 168 { 169 if (mpPolicyManager == NULL) { 170 return NO_INIT; 171 } 172 if (!checkPermission()) { 173 return PERMISSION_DENIED; 174 } 175 176 mpPolicyManager->setRingerMode(mode, mask); 177 return NO_ERROR; 178 } 179 180 status_t AudioPolicyService::setForceUse(AudioSystem::force_use usage, 181 AudioSystem::forced_config config) 182 { 183 if (mpPolicyManager == NULL) { 184 return NO_INIT; 185 } 186 if (!checkPermission()) { 187 return PERMISSION_DENIED; 188 } 189 if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) { 190 return BAD_VALUE; 191 } 192 if (config < 0 || config >= AudioSystem::NUM_FORCE_CONFIG) { 193 return BAD_VALUE; 194 } 195 LOGV("setForceUse() tid %d", gettid()); 196 Mutex::Autolock _l(mLock); 197 mpPolicyManager->setForceUse(usage, config); 198 return NO_ERROR; 199 } 200 201 AudioSystem::forced_config AudioPolicyService::getForceUse(AudioSystem::force_use usage) 202 { 203 if (mpPolicyManager == NULL) { 204 return AudioSystem::FORCE_NONE; 205 } 206 if (!checkPermission()) { 207 return AudioSystem::FORCE_NONE; 208 } 209 if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) { 210 return AudioSystem::FORCE_NONE; 211 } 212 return mpPolicyManager->getForceUse(usage); 213 } 214 215 audio_io_handle_t AudioPolicyService::getOutput(AudioSystem::stream_type stream, 216 uint32_t samplingRate, 217 uint32_t format, 218 uint32_t channels, 219 AudioSystem::output_flags flags) 220 { 221 if (mpPolicyManager == NULL) { 222 return 0; 223 } 224 LOGV("getOutput() tid %d", gettid()); 225 Mutex::Autolock _l(mLock); 226 return mpPolicyManager->getOutput(stream, samplingRate, format, channels, flags); 227 } 228 229 status_t AudioPolicyService::startOutput(audio_io_handle_t output, 230 AudioSystem::stream_type stream, 231 int session) 232 { 233 if (mpPolicyManager == NULL) { 234 return NO_INIT; 235 } 236 LOGV("startOutput() tid %d", gettid()); 237 Mutex::Autolock _l(mLock); 238 return mpPolicyManager->startOutput(output, stream, session); 239 } 240 241 status_t AudioPolicyService::stopOutput(audio_io_handle_t output, 242 AudioSystem::stream_type stream, 243 int session) 244 { 245 if (mpPolicyManager == NULL) { 246 return NO_INIT; 247 } 248 LOGV("stopOutput() tid %d", gettid()); 249 Mutex::Autolock _l(mLock); 250 return mpPolicyManager->stopOutput(output, stream, session); 251 } 252 253 void AudioPolicyService::releaseOutput(audio_io_handle_t output) 254 { 255 if (mpPolicyManager == NULL) { 256 return; 257 } 258 LOGV("releaseOutput() tid %d", gettid()); 259 Mutex::Autolock _l(mLock); 260 mpPolicyManager->releaseOutput(output); 261 } 262 263 audio_io_handle_t AudioPolicyService::getInput(int inputSource, 264 uint32_t samplingRate, 265 uint32_t format, 266 uint32_t channels, 267 AudioSystem::audio_in_acoustics acoustics) 268 { 269 if (mpPolicyManager == NULL) { 270 return 0; 271 } 272 Mutex::Autolock _l(mLock); 273 return mpPolicyManager->getInput(inputSource, samplingRate, format, channels, acoustics); 274 } 275 276 status_t AudioPolicyService::startInput(audio_io_handle_t input) 277 { 278 if (mpPolicyManager == NULL) { 279 return NO_INIT; 280 } 281 Mutex::Autolock _l(mLock); 282 return mpPolicyManager->startInput(input); 283 } 284 285 status_t AudioPolicyService::stopInput(audio_io_handle_t input) 286 { 287 if (mpPolicyManager == NULL) { 288 return NO_INIT; 289 } 290 Mutex::Autolock _l(mLock); 291 return mpPolicyManager->stopInput(input); 292 } 293 294 void AudioPolicyService::releaseInput(audio_io_handle_t input) 295 { 296 if (mpPolicyManager == NULL) { 297 return; 298 } 299 Mutex::Autolock _l(mLock); 300 mpPolicyManager->releaseInput(input); 301 } 302 303 status_t AudioPolicyService::initStreamVolume(AudioSystem::stream_type stream, 304 int indexMin, 305 int indexMax) 306 { 307 if (mpPolicyManager == NULL) { 308 return NO_INIT; 309 } 310 if (!checkPermission()) { 311 return PERMISSION_DENIED; 312 } 313 if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 314 return BAD_VALUE; 315 } 316 mpPolicyManager->initStreamVolume(stream, indexMin, indexMax); 317 return NO_ERROR; 318 } 319 320 status_t AudioPolicyService::setStreamVolumeIndex(AudioSystem::stream_type stream, int index) 321 { 322 if (mpPolicyManager == NULL) { 323 return NO_INIT; 324 } 325 if (!checkPermission()) { 326 return PERMISSION_DENIED; 327 } 328 if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 329 return BAD_VALUE; 330 } 331 332 return mpPolicyManager->setStreamVolumeIndex(stream, index); 333 } 334 335 status_t AudioPolicyService::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index) 336 { 337 if (mpPolicyManager == NULL) { 338 return NO_INIT; 339 } 340 if (!checkPermission()) { 341 return PERMISSION_DENIED; 342 } 343 if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 344 return BAD_VALUE; 345 } 346 return mpPolicyManager->getStreamVolumeIndex(stream, index); 347 } 348 349 uint32_t AudioPolicyService::getStrategyForStream(AudioSystem::stream_type stream) 350 { 351 if (mpPolicyManager == NULL) { 352 return 0; 353 } 354 return mpPolicyManager->getStrategyForStream(stream); 355 } 356 357 audio_io_handle_t AudioPolicyService::getOutputForEffect(effect_descriptor_t *desc) 358 { 359 if (mpPolicyManager == NULL) { 360 return NO_INIT; 361 } 362 Mutex::Autolock _l(mLock); 363 return mpPolicyManager->getOutputForEffect(desc); 364 } 365 366 status_t AudioPolicyService::registerEffect(effect_descriptor_t *desc, 367 audio_io_handle_t output, 368 uint32_t strategy, 369 int session, 370 int id) 371 { 372 if (mpPolicyManager == NULL) { 373 return NO_INIT; 374 } 375 return mpPolicyManager->registerEffect(desc, output, strategy, session, id); 376 } 377 378 status_t AudioPolicyService::unregisterEffect(int id) 379 { 380 if (mpPolicyManager == NULL) { 381 return NO_INIT; 382 } 383 return mpPolicyManager->unregisterEffect(id); 384 } 385 386 void AudioPolicyService::binderDied(const wp<IBinder>& who) { 387 LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), 388 IPCThreadState::self()->getCallingPid()); 389 } 390 391 static bool tryLock(Mutex& mutex) 392 { 393 bool locked = false; 394 for (int i = 0; i < kDumpLockRetries; ++i) { 395 if (mutex.tryLock() == NO_ERROR) { 396 locked = true; 397 break; 398 } 399 usleep(kDumpLockSleep); 400 } 401 return locked; 402 } 403 404 status_t AudioPolicyService::dumpInternals(int fd) 405 { 406 const size_t SIZE = 256; 407 char buffer[SIZE]; 408 String8 result; 409 410 snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager); 411 result.append(buffer); 412 snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); 413 result.append(buffer); 414 snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); 415 result.append(buffer); 416 417 write(fd, result.string(), result.size()); 418 return NO_ERROR; 419 } 420 421 status_t AudioPolicyService::dump(int fd, const Vector<String16>& args) 422 { 423 if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 424 dumpPermissionDenial(fd); 425 } else { 426 bool locked = tryLock(mLock); 427 if (!locked) { 428 String8 result(kDeadlockedString); 429 write(fd, result.string(), result.size()); 430 } 431 432 dumpInternals(fd); 433 if (mAudioCommandThread != NULL) { 434 mAudioCommandThread->dump(fd); 435 } 436 if (mTonePlaybackThread != NULL) { 437 mTonePlaybackThread->dump(fd); 438 } 439 440 if (mpPolicyManager) { 441 mpPolicyManager->dump(fd); 442 } 443 444 if (locked) mLock.unlock(); 445 } 446 return NO_ERROR; 447 } 448 449 status_t AudioPolicyService::dumpPermissionDenial(int fd) 450 { 451 const size_t SIZE = 256; 452 char buffer[SIZE]; 453 String8 result; 454 snprintf(buffer, SIZE, "Permission Denial: " 455 "can't dump AudioPolicyService from pid=%d, uid=%d\n", 456 IPCThreadState::self()->getCallingPid(), 457 IPCThreadState::self()->getCallingUid()); 458 result.append(buffer); 459 write(fd, result.string(), result.size()); 460 return NO_ERROR; 461 } 462 463 status_t AudioPolicyService::onTransact( 464 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 465 { 466 return BnAudioPolicyService::onTransact(code, data, reply, flags); 467 } 468 469 470 // ---------------------------------------------------------------------------- 471 void AudioPolicyService::instantiate() { 472 defaultServiceManager()->addService( 473 String16("media.audio_policy"), new AudioPolicyService()); 474 } 475 476 477 // ---------------------------------------------------------------------------- 478 // AudioPolicyClientInterface implementation 479 // ---------------------------------------------------------------------------- 480 481 482 audio_io_handle_t AudioPolicyService::openOutput(uint32_t *pDevices, 483 uint32_t *pSamplingRate, 484 uint32_t *pFormat, 485 uint32_t *pChannels, 486 uint32_t *pLatencyMs, 487 AudioSystem::output_flags flags) 488 { 489 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 490 if (af == 0) { 491 LOGW("openOutput() could not get AudioFlinger"); 492 return 0; 493 } 494 495 return af->openOutput(pDevices, 496 pSamplingRate, 497 (uint32_t *)pFormat, 498 pChannels, 499 pLatencyMs, 500 flags); 501 } 502 503 audio_io_handle_t AudioPolicyService::openDuplicateOutput(audio_io_handle_t output1, 504 audio_io_handle_t output2) 505 { 506 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 507 if (af == 0) { 508 LOGW("openDuplicateOutput() could not get AudioFlinger"); 509 return 0; 510 } 511 return af->openDuplicateOutput(output1, output2); 512 } 513 514 status_t AudioPolicyService::closeOutput(audio_io_handle_t output) 515 { 516 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 517 if (af == 0) return PERMISSION_DENIED; 518 519 return af->closeOutput(output); 520 } 521 522 523 status_t AudioPolicyService::suspendOutput(audio_io_handle_t output) 524 { 525 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 526 if (af == 0) { 527 LOGW("suspendOutput() could not get AudioFlinger"); 528 return PERMISSION_DENIED; 529 } 530 531 return af->suspendOutput(output); 532 } 533 534 status_t AudioPolicyService::restoreOutput(audio_io_handle_t output) 535 { 536 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 537 if (af == 0) { 538 LOGW("restoreOutput() could not get AudioFlinger"); 539 return PERMISSION_DENIED; 540 } 541 542 return af->restoreOutput(output); 543 } 544 545 audio_io_handle_t AudioPolicyService::openInput(uint32_t *pDevices, 546 uint32_t *pSamplingRate, 547 uint32_t *pFormat, 548 uint32_t *pChannels, 549 uint32_t acoustics) 550 { 551 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 552 if (af == 0) { 553 LOGW("openInput() could not get AudioFlinger"); 554 return 0; 555 } 556 557 return af->openInput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, acoustics); 558 } 559 560 status_t AudioPolicyService::closeInput(audio_io_handle_t input) 561 { 562 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 563 if (af == 0) return PERMISSION_DENIED; 564 565 return af->closeInput(input); 566 } 567 568 status_t AudioPolicyService::setStreamVolume(AudioSystem::stream_type stream, 569 float volume, 570 audio_io_handle_t output, 571 int delayMs) 572 { 573 return mAudioCommandThread->volumeCommand((int)stream, volume, (int)output, delayMs); 574 } 575 576 status_t AudioPolicyService::setStreamOutput(AudioSystem::stream_type stream, 577 audio_io_handle_t output) 578 { 579 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 580 if (af == 0) return PERMISSION_DENIED; 581 582 return af->setStreamOutput(stream, output); 583 } 584 585 status_t AudioPolicyService::moveEffects(int session, audio_io_handle_t srcOutput, 586 audio_io_handle_t dstOutput) 587 { 588 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 589 if (af == 0) return PERMISSION_DENIED; 590 591 return af->moveEffects(session, (int)srcOutput, (int)dstOutput); 592 } 593 594 void AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 595 const String8& keyValuePairs, 596 int delayMs) 597 { 598 mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs, delayMs); 599 } 600 601 String8 AudioPolicyService::getParameters(audio_io_handle_t ioHandle, const String8& keys) 602 { 603 String8 result = AudioSystem::getParameters(ioHandle, keys); 604 return result; 605 } 606 607 status_t AudioPolicyService::startTone(ToneGenerator::tone_type tone, 608 AudioSystem::stream_type stream) 609 { 610 mTonePlaybackThread->startToneCommand(tone, stream); 611 return NO_ERROR; 612 } 613 614 status_t AudioPolicyService::stopTone() 615 { 616 mTonePlaybackThread->stopToneCommand(); 617 return NO_ERROR; 618 } 619 620 status_t AudioPolicyService::setVoiceVolume(float volume, int delayMs) 621 { 622 return mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 623 } 624 625 // ----------- AudioPolicyService::AudioCommandThread implementation ---------- 626 627 AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name) 628 : Thread(false), mName(name) 629 { 630 mpToneGenerator = NULL; 631 } 632 633 634 AudioPolicyService::AudioCommandThread::~AudioCommandThread() 635 { 636 if (mName != "" && !mAudioCommands.isEmpty()) { 637 release_wake_lock(mName.string()); 638 } 639 mAudioCommands.clear(); 640 if (mpToneGenerator != NULL) delete mpToneGenerator; 641 } 642 643 void AudioPolicyService::AudioCommandThread::onFirstRef() 644 { 645 if (mName != "") { 646 run(mName.string(), ANDROID_PRIORITY_AUDIO); 647 } else { 648 run("AudioCommandThread", ANDROID_PRIORITY_AUDIO); 649 } 650 } 651 652 bool AudioPolicyService::AudioCommandThread::threadLoop() 653 { 654 nsecs_t waitTime = INT64_MAX; 655 656 mLock.lock(); 657 while (!exitPending()) 658 { 659 while(!mAudioCommands.isEmpty()) { 660 nsecs_t curTime = systemTime(); 661 // commands are sorted by increasing time stamp: execute them from index 0 and up 662 if (mAudioCommands[0]->mTime <= curTime) { 663 AudioCommand *command = mAudioCommands[0]; 664 mAudioCommands.removeAt(0); 665 mLastCommand = *command; 666 667 switch (command->mCommand) { 668 case START_TONE: { 669 mLock.unlock(); 670 ToneData *data = (ToneData *)command->mParam; 671 LOGV("AudioCommandThread() processing start tone %d on stream %d", 672 data->mType, data->mStream); 673 if (mpToneGenerator != NULL) 674 delete mpToneGenerator; 675 mpToneGenerator = new ToneGenerator(data->mStream, 1.0); 676 mpToneGenerator->startTone(data->mType); 677 delete data; 678 mLock.lock(); 679 }break; 680 case STOP_TONE: { 681 mLock.unlock(); 682 LOGV("AudioCommandThread() processing stop tone"); 683 if (mpToneGenerator != NULL) { 684 mpToneGenerator->stopTone(); 685 delete mpToneGenerator; 686 mpToneGenerator = NULL; 687 } 688 mLock.lock(); 689 }break; 690 case SET_VOLUME: { 691 VolumeData *data = (VolumeData *)command->mParam; 692 LOGV("AudioCommandThread() processing set volume stream %d, \ 693 volume %f, output %d", data->mStream, data->mVolume, data->mIO); 694 command->mStatus = AudioSystem::setStreamVolume(data->mStream, 695 data->mVolume, 696 data->mIO); 697 if (command->mWaitStatus) { 698 command->mCond.signal(); 699 mWaitWorkCV.wait(mLock); 700 } 701 delete data; 702 }break; 703 case SET_PARAMETERS: { 704 ParametersData *data = (ParametersData *)command->mParam; 705 LOGV("AudioCommandThread() processing set parameters string %s, io %d", 706 data->mKeyValuePairs.string(), data->mIO); 707 command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); 708 if (command->mWaitStatus) { 709 command->mCond.signal(); 710 mWaitWorkCV.wait(mLock); 711 } 712 delete data; 713 }break; 714 case SET_VOICE_VOLUME: { 715 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam; 716 LOGV("AudioCommandThread() processing set voice volume volume %f", 717 data->mVolume); 718 command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); 719 if (command->mWaitStatus) { 720 command->mCond.signal(); 721 mWaitWorkCV.wait(mLock); 722 } 723 delete data; 724 }break; 725 default: 726 LOGW("AudioCommandThread() unknown command %d", command->mCommand); 727 } 728 delete command; 729 waitTime = INT64_MAX; 730 } else { 731 waitTime = mAudioCommands[0]->mTime - curTime; 732 break; 733 } 734 } 735 // release delayed commands wake lock 736 if (mName != "" && mAudioCommands.isEmpty()) { 737 release_wake_lock(mName.string()); 738 } 739 LOGV("AudioCommandThread() going to sleep"); 740 mWaitWorkCV.waitRelative(mLock, waitTime); 741 LOGV("AudioCommandThread() waking up"); 742 } 743 mLock.unlock(); 744 return false; 745 } 746 747 status_t AudioPolicyService::AudioCommandThread::dump(int fd) 748 { 749 const size_t SIZE = 256; 750 char buffer[SIZE]; 751 String8 result; 752 753 snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 754 result.append(buffer); 755 write(fd, result.string(), result.size()); 756 757 bool locked = tryLock(mLock); 758 if (!locked) { 759 String8 result2(kCmdDeadlockedString); 760 write(fd, result2.string(), result2.size()); 761 } 762 763 snprintf(buffer, SIZE, "- Commands:\n"); 764 result = String8(buffer); 765 result.append(" Command Time Wait pParam\n"); 766 for (int i = 0; i < (int)mAudioCommands.size(); i++) { 767 mAudioCommands[i]->dump(buffer, SIZE); 768 result.append(buffer); 769 } 770 result.append(" Last Command\n"); 771 mLastCommand.dump(buffer, SIZE); 772 result.append(buffer); 773 774 write(fd, result.string(), result.size()); 775 776 if (locked) mLock.unlock(); 777 778 return NO_ERROR; 779 } 780 781 void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream) 782 { 783 AudioCommand *command = new AudioCommand(); 784 command->mCommand = START_TONE; 785 ToneData *data = new ToneData(); 786 data->mType = type; 787 data->mStream = stream; 788 command->mParam = (void *)data; 789 command->mWaitStatus = false; 790 Mutex::Autolock _l(mLock); 791 insertCommand_l(command); 792 LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 793 mWaitWorkCV.signal(); 794 } 795 796 void AudioPolicyService::AudioCommandThread::stopToneCommand() 797 { 798 AudioCommand *command = new AudioCommand(); 799 command->mCommand = STOP_TONE; 800 command->mParam = NULL; 801 command->mWaitStatus = false; 802 Mutex::Autolock _l(mLock); 803 insertCommand_l(command); 804 LOGV("AudioCommandThread() adding tone stop"); 805 mWaitWorkCV.signal(); 806 } 807 808 status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, 809 float volume, 810 int output, 811 int delayMs) 812 { 813 status_t status = NO_ERROR; 814 815 AudioCommand *command = new AudioCommand(); 816 command->mCommand = SET_VOLUME; 817 VolumeData *data = new VolumeData(); 818 data->mStream = stream; 819 data->mVolume = volume; 820 data->mIO = output; 821 command->mParam = data; 822 if (delayMs == 0) { 823 command->mWaitStatus = true; 824 } else { 825 command->mWaitStatus = false; 826 } 827 Mutex::Autolock _l(mLock); 828 insertCommand_l(command, delayMs); 829 LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 830 stream, volume, output); 831 mWaitWorkCV.signal(); 832 if (command->mWaitStatus) { 833 command->mCond.wait(mLock); 834 status = command->mStatus; 835 mWaitWorkCV.signal(); 836 } 837 return status; 838 } 839 840 status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, 841 const String8& keyValuePairs, 842 int delayMs) 843 { 844 status_t status = NO_ERROR; 845 846 AudioCommand *command = new AudioCommand(); 847 command->mCommand = SET_PARAMETERS; 848 ParametersData *data = new ParametersData(); 849 data->mIO = ioHandle; 850 data->mKeyValuePairs = keyValuePairs; 851 command->mParam = data; 852 if (delayMs == 0) { 853 command->mWaitStatus = true; 854 } else { 855 command->mWaitStatus = false; 856 } 857 Mutex::Autolock _l(mLock); 858 insertCommand_l(command, delayMs); 859 LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 860 keyValuePairs.string(), ioHandle, delayMs); 861 mWaitWorkCV.signal(); 862 if (command->mWaitStatus) { 863 command->mCond.wait(mLock); 864 status = command->mStatus; 865 mWaitWorkCV.signal(); 866 } 867 return status; 868 } 869 870 status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 871 { 872 status_t status = NO_ERROR; 873 874 AudioCommand *command = new AudioCommand(); 875 command->mCommand = SET_VOICE_VOLUME; 876 VoiceVolumeData *data = new VoiceVolumeData(); 877 data->mVolume = volume; 878 command->mParam = data; 879 if (delayMs == 0) { 880 command->mWaitStatus = true; 881 } else { 882 command->mWaitStatus = false; 883 } 884 Mutex::Autolock _l(mLock); 885 insertCommand_l(command, delayMs); 886 LOGV("AudioCommandThread() adding set voice volume volume %f", volume); 887 mWaitWorkCV.signal(); 888 if (command->mWaitStatus) { 889 command->mCond.wait(mLock); 890 status = command->mStatus; 891 mWaitWorkCV.signal(); 892 } 893 return status; 894 } 895 896 // insertCommand_l() must be called with mLock held 897 void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs) 898 { 899 ssize_t i; 900 Vector <AudioCommand *> removedCommands; 901 902 command->mTime = systemTime() + milliseconds(delayMs); 903 904 // acquire wake lock to make sure delayed commands are processed 905 if (mName != "" && mAudioCommands.isEmpty()) { 906 acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 907 } 908 909 // check same pending commands with later time stamps and eliminate them 910 for (i = mAudioCommands.size()-1; i >= 0; i--) { 911 AudioCommand *command2 = mAudioCommands[i]; 912 // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 913 if (command2->mTime <= command->mTime) break; 914 if (command2->mCommand != command->mCommand) continue; 915 916 switch (command->mCommand) { 917 case SET_PARAMETERS: { 918 ParametersData *data = (ParametersData *)command->mParam; 919 ParametersData *data2 = (ParametersData *)command2->mParam; 920 if (data->mIO != data2->mIO) break; 921 LOGV("Comparing parameter command %s to new command %s", 922 data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 923 AudioParameter param = AudioParameter(data->mKeyValuePairs); 924 AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 925 for (size_t j = 0; j < param.size(); j++) { 926 String8 key; 927 String8 value; 928 param.getAt(j, key, value); 929 for (size_t k = 0; k < param2.size(); k++) { 930 String8 key2; 931 String8 value2; 932 param2.getAt(k, key2, value2); 933 if (key2 == key) { 934 param2.remove(key2); 935 LOGV("Filtering out parameter %s", key2.string()); 936 break; 937 } 938 } 939 } 940 // if all keys have been filtered out, remove the command. 941 // otherwise, update the key value pairs 942 if (param2.size() == 0) { 943 removedCommands.add(command2); 944 } else { 945 data2->mKeyValuePairs = param2.toString(); 946 } 947 } break; 948 949 case SET_VOLUME: { 950 VolumeData *data = (VolumeData *)command->mParam; 951 VolumeData *data2 = (VolumeData *)command2->mParam; 952 if (data->mIO != data2->mIO) break; 953 if (data->mStream != data2->mStream) break; 954 LOGV("Filtering out volume command on output %d for stream %d", 955 data->mIO, data->mStream); 956 removedCommands.add(command2); 957 } break; 958 case START_TONE: 959 case STOP_TONE: 960 default: 961 break; 962 } 963 } 964 965 // remove filtered commands 966 for (size_t j = 0; j < removedCommands.size(); j++) { 967 // removed commands always have time stamps greater than current command 968 for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 969 if (mAudioCommands[k] == removedCommands[j]) { 970 LOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 971 mAudioCommands.removeAt(k); 972 break; 973 } 974 } 975 } 976 removedCommands.clear(); 977 978 // insert command at the right place according to its time stamp 979 LOGV("inserting command: %d at index %d, num commands %d", 980 command->mCommand, (int)i+1, mAudioCommands.size()); 981 mAudioCommands.insertAt(command, i + 1); 982 } 983 984 void AudioPolicyService::AudioCommandThread::exit() 985 { 986 LOGV("AudioCommandThread::exit"); 987 { 988 AutoMutex _l(mLock); 989 requestExit(); 990 mWaitWorkCV.signal(); 991 } 992 requestExitAndWait(); 993 } 994 995 void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 996 { 997 snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 998 mCommand, 999 (int)ns2s(mTime), 1000 (int)ns2ms(mTime)%1000, 1001 mWaitStatus, 1002 mParam); 1003 } 1004 1005 }; // namespace android 1006