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