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