AudioPolicyService.cpp revision a5cc7cce9b8aee73b08f6532710e186c02fdd1c0
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#include <media/AudioEffect.h> 37#include <media/EffectsFactoryApi.h> 38 39#include <hardware/hardware.h> 40#include <system/audio.h> 41#include <system/audio_policy.h> 42#include <hardware/audio_policy.h> 43#include <audio_effects/audio_effects_conf.h> 44 45namespace android { 46 47static const char *kDeadlockedString = "AudioPolicyService may be deadlocked\n"; 48static const char *kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n"; 49 50static const int kDumpLockRetries = 50; 51static const int kDumpLockSleep = 20000; 52 53static bool checkPermission() { 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 // load audio pre processing modules 109 if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) { 110 loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE); 111 } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) { 112 loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE); 113 } 114} 115 116AudioPolicyService::~AudioPolicyService() 117{ 118 mTonePlaybackThread->exit(); 119 mTonePlaybackThread.clear(); 120 mAudioCommandThread->exit(); 121 mAudioCommandThread.clear(); 122 123 124 // release audio pre processing resources 125 for (size_t i = 0; i < mInputSources.size(); i++) { 126 InputSourceDesc *source = mInputSources.valueAt(i); 127 Vector <EffectDesc *> effects = source->mEffects; 128 for (size_t j = 0; j < effects.size(); j++) { 129 delete effects[j]->mName; 130 Vector <effect_param_t *> params = effects[j]->mParams; 131 for (size_t k = 0; k < params.size(); k++) { 132 delete params[k]; 133 } 134 params.clear(); 135 delete effects[j]; 136 } 137 effects.clear(); 138 delete source; 139 } 140 mInputSources.clear(); 141 142 for (size_t i = 0; i < mInputs.size(); i++) { 143 mInputs.valueAt(i)->mEffects.clear(); 144 delete mInputs.valueAt(i); 145 } 146 mInputs.clear(); 147 148 if (mpAudioPolicy && mpAudioPolicyDev) 149 mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy); 150 if (mpAudioPolicyDev) 151 audio_policy_dev_close(mpAudioPolicyDev); 152} 153 154status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device, 155 audio_policy_dev_state_t state, 156 const char *device_address) 157{ 158 if (mpAudioPolicy == NULL) { 159 return NO_INIT; 160 } 161 if (!checkPermission()) { 162 return PERMISSION_DENIED; 163 } 164 if (!audio_is_output_device(device) && !audio_is_input_device(device)) { 165 return BAD_VALUE; 166 } 167 if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE && 168 state != AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) { 169 return BAD_VALUE; 170 } 171 172 LOGV("setDeviceConnectionState() tid %d", gettid()); 173 Mutex::Autolock _l(mLock); 174 return mpAudioPolicy->set_device_connection_state(mpAudioPolicy, device, 175 state, device_address); 176} 177 178audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState( 179 audio_devices_t device, 180 const char *device_address) 181{ 182 if (mpAudioPolicy == NULL) { 183 return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 184 } 185 return mpAudioPolicy->get_device_connection_state(mpAudioPolicy, device, 186 device_address); 187} 188 189status_t AudioPolicyService::setPhoneState(int state) 190{ 191 if (mpAudioPolicy == NULL) { 192 return NO_INIT; 193 } 194 if (!checkPermission()) { 195 return PERMISSION_DENIED; 196 } 197 if (state < 0 || state >= AUDIO_MODE_CNT) { 198 return BAD_VALUE; 199 } 200 201 LOGV("setPhoneState() tid %d", gettid()); 202 203 // TODO: check if it is more appropriate to do it in platform specific policy manager 204 AudioSystem::setMode(state); 205 206 Mutex::Autolock _l(mLock); 207 mpAudioPolicy->set_phone_state(mpAudioPolicy, state); 208 return NO_ERROR; 209} 210 211status_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask) 212{ 213 if (mpAudioPolicy == NULL) { 214 return NO_INIT; 215 } 216 if (!checkPermission()) { 217 return PERMISSION_DENIED; 218 } 219 220 mpAudioPolicy->set_ringer_mode(mpAudioPolicy, mode, mask); 221 return NO_ERROR; 222} 223 224status_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage, 225 audio_policy_forced_cfg_t config) 226{ 227 if (mpAudioPolicy == NULL) { 228 return NO_INIT; 229 } 230 if (!checkPermission()) { 231 return PERMISSION_DENIED; 232 } 233 if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) { 234 return BAD_VALUE; 235 } 236 if (config < 0 || config >= AUDIO_POLICY_FORCE_CFG_CNT) { 237 return BAD_VALUE; 238 } 239 LOGV("setForceUse() tid %d", gettid()); 240 Mutex::Autolock _l(mLock); 241 mpAudioPolicy->set_force_use(mpAudioPolicy, usage, config); 242 return NO_ERROR; 243} 244 245audio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage) 246{ 247 if (mpAudioPolicy == NULL) { 248 return AUDIO_POLICY_FORCE_NONE; 249 } 250 if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) { 251 return AUDIO_POLICY_FORCE_NONE; 252 } 253 return mpAudioPolicy->get_force_use(mpAudioPolicy, usage); 254} 255 256audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream, 257 uint32_t samplingRate, 258 uint32_t format, 259 uint32_t channels, 260 audio_policy_output_flags_t flags) 261{ 262 if (mpAudioPolicy == NULL) { 263 return 0; 264 } 265 LOGV("getOutput() tid %d", gettid()); 266 Mutex::Autolock _l(mLock); 267 return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate, format, channels, flags); 268} 269 270status_t AudioPolicyService::startOutput(audio_io_handle_t output, 271 audio_stream_type_t stream, 272 int session) 273{ 274 if (mpAudioPolicy == NULL) { 275 return NO_INIT; 276 } 277 LOGV("startOutput() tid %d", gettid()); 278 Mutex::Autolock _l(mLock); 279 return mpAudioPolicy->start_output(mpAudioPolicy, output, stream, session); 280} 281 282status_t AudioPolicyService::stopOutput(audio_io_handle_t output, 283 audio_stream_type_t stream, 284 int session) 285{ 286 if (mpAudioPolicy == NULL) { 287 return NO_INIT; 288 } 289 LOGV("stopOutput() tid %d", gettid()); 290 Mutex::Autolock _l(mLock); 291 return mpAudioPolicy->stop_output(mpAudioPolicy, output, stream, session); 292} 293 294void AudioPolicyService::releaseOutput(audio_io_handle_t output) 295{ 296 if (mpAudioPolicy == NULL) { 297 return; 298 } 299 LOGV("releaseOutput() tid %d", gettid()); 300 Mutex::Autolock _l(mLock); 301 mpAudioPolicy->release_output(mpAudioPolicy, output); 302} 303 304audio_io_handle_t AudioPolicyService::getInput(int inputSource, 305 uint32_t samplingRate, 306 uint32_t format, 307 uint32_t channels, 308 audio_in_acoustics_t acoustics, 309 int audioSession) 310{ 311 if (mpAudioPolicy == NULL) { 312 return 0; 313 } 314 Mutex::Autolock _l(mLock); 315 audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate, 316 format, channels, acoustics); 317 318 if (input == 0) { 319 return input; 320 } 321 // create audio pre processors according to input source 322 ssize_t index = mInputSources.indexOfKey((audio_source_t)inputSource); 323 if (index < 0) { 324 return input; 325 } 326 ssize_t idx = mInputs.indexOfKey(input); 327 InputDesc *inputDesc; 328 if (idx < 0) { 329 inputDesc = new InputDesc(); 330 inputDesc->mSessionId = audioSession; 331 mInputs.add(input, inputDesc); 332 } else { 333 inputDesc = mInputs.valueAt(idx); 334 } 335 336 Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects; 337 for (size_t i = 0; i < effects.size(); i++) { 338 EffectDesc *effect = effects[i]; 339 sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input); 340 status_t status = fx->initCheck(); 341 if (status != NO_ERROR && status != ALREADY_EXISTS) { 342 LOGW("Failed to create Fx %s on input %d", effect->mName, input); 343 // fx goes out of scope and strong ref on AudioEffect is released 344 continue; 345 } 346 for (size_t j = 0; j < effect->mParams.size(); j++) { 347 fx->setParameter(effect->mParams[j]); 348 } 349 inputDesc->mEffects.add(fx); 350 } 351 setPreProcessorEnabled(inputDesc, true); 352 return input; 353} 354 355status_t AudioPolicyService::startInput(audio_io_handle_t input) 356{ 357 if (mpAudioPolicy == NULL) { 358 return NO_INIT; 359 } 360 Mutex::Autolock _l(mLock); 361 362 return mpAudioPolicy->start_input(mpAudioPolicy, input); 363} 364 365status_t AudioPolicyService::stopInput(audio_io_handle_t input) 366{ 367 if (mpAudioPolicy == NULL) { 368 return NO_INIT; 369 } 370 Mutex::Autolock _l(mLock); 371 372 return mpAudioPolicy->stop_input(mpAudioPolicy, input); 373} 374 375void AudioPolicyService::releaseInput(audio_io_handle_t input) 376{ 377 if (mpAudioPolicy == NULL) { 378 return; 379 } 380 Mutex::Autolock _l(mLock); 381 mpAudioPolicy->release_input(mpAudioPolicy, input); 382 383 ssize_t index = mInputs.indexOfKey(input); 384 if (index < 0) { 385 return; 386 } 387 InputDesc *inputDesc = mInputs.valueAt(index); 388 setPreProcessorEnabled(inputDesc, false); 389 inputDesc->mEffects.clear(); 390 delete inputDesc; 391 mInputs.removeItemsAt(index); 392} 393 394status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream, 395 int indexMin, 396 int indexMax) 397{ 398 if (mpAudioPolicy == NULL) { 399 return NO_INIT; 400 } 401 if (!checkPermission()) { 402 return PERMISSION_DENIED; 403 } 404 if (stream < 0 || stream >= AUDIO_STREAM_CNT) { 405 return BAD_VALUE; 406 } 407 mpAudioPolicy->init_stream_volume(mpAudioPolicy, stream, indexMin, indexMax); 408 return NO_ERROR; 409} 410 411status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream, int index) 412{ 413 if (mpAudioPolicy == NULL) { 414 return NO_INIT; 415 } 416 if (!checkPermission()) { 417 return PERMISSION_DENIED; 418 } 419 if (stream < 0 || stream >= AUDIO_STREAM_CNT) { 420 return BAD_VALUE; 421 } 422 423 return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index); 424} 425 426status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream, int *index) 427{ 428 if (mpAudioPolicy == NULL) { 429 return NO_INIT; 430 } 431 if (stream < 0 || stream >= AUDIO_STREAM_CNT) { 432 return BAD_VALUE; 433 } 434 return mpAudioPolicy->get_stream_volume_index(mpAudioPolicy, stream, index); 435} 436 437uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream) 438{ 439 if (mpAudioPolicy == NULL) { 440 return 0; 441 } 442 return mpAudioPolicy->get_strategy_for_stream(mpAudioPolicy, stream); 443} 444 445uint32_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream) 446{ 447 if (mpAudioPolicy == NULL) { 448 return 0; 449 } 450 return mpAudioPolicy->get_devices_for_stream(mpAudioPolicy, stream); 451} 452 453audio_io_handle_t AudioPolicyService::getOutputForEffect(effect_descriptor_t *desc) 454{ 455 if (mpAudioPolicy == NULL) { 456 return NO_INIT; 457 } 458 Mutex::Autolock _l(mLock); 459 return mpAudioPolicy->get_output_for_effect(mpAudioPolicy, desc); 460} 461 462status_t AudioPolicyService::registerEffect(effect_descriptor_t *desc, 463 audio_io_handle_t io, 464 uint32_t strategy, 465 int session, 466 int id) 467{ 468 if (mpAudioPolicy == NULL) { 469 return NO_INIT; 470 } 471 return mpAudioPolicy->register_effect(mpAudioPolicy, desc, io, strategy, session, id); 472} 473 474status_t AudioPolicyService::unregisterEffect(int id) 475{ 476 if (mpAudioPolicy == NULL) { 477 return NO_INIT; 478 } 479 return mpAudioPolicy->unregister_effect(mpAudioPolicy, id); 480} 481 482status_t AudioPolicyService::setEffectEnabled(int id, bool enabled) 483{ 484 if (mpAudioPolicy == NULL) { 485 return NO_INIT; 486 } 487 return mpAudioPolicy->set_effect_enabled(mpAudioPolicy, id, enabled); 488} 489 490bool AudioPolicyService::isStreamActive(int stream, uint32_t inPastMs) const 491{ 492 if (mpAudioPolicy == NULL) { 493 return 0; 494 } 495 Mutex::Autolock _l(mLock); 496 return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs); 497} 498 499status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession, 500 effect_descriptor_t *descriptors, 501 uint32_t *count) 502{ 503 504 if (mpAudioPolicy == NULL) { 505 *count = 0; 506 return NO_INIT; 507 } 508 Mutex::Autolock _l(mLock); 509 status_t status = NO_ERROR; 510 511 size_t index; 512 for (index = 0; index < mInputs.size(); index++) { 513 if (mInputs.valueAt(index)->mSessionId == audioSession) { 514 break; 515 } 516 } 517 if (index == mInputs.size()) { 518 *count = 0; 519 return BAD_VALUE; 520 } 521 Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects; 522 523 for (size_t i = 0; i < effects.size(); i++) { 524 effect_descriptor_t desc = effects[i]->descriptor(); 525 if (i < *count) { 526 memcpy(descriptors + i, &desc, sizeof(effect_descriptor_t)); 527 } 528 } 529 if (effects.size() > *count) { 530 status = NO_MEMORY; 531 } 532 *count = effects.size(); 533 return status; 534} 535 536void AudioPolicyService::binderDied(const wp<IBinder>& who) { 537 LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), 538 IPCThreadState::self()->getCallingPid()); 539} 540 541static bool tryLock(Mutex& mutex) 542{ 543 bool locked = false; 544 for (int i = 0; i < kDumpLockRetries; ++i) { 545 if (mutex.tryLock() == NO_ERROR) { 546 locked = true; 547 break; 548 } 549 usleep(kDumpLockSleep); 550 } 551 return locked; 552} 553 554status_t AudioPolicyService::dumpInternals(int fd) 555{ 556 const size_t SIZE = 256; 557 char buffer[SIZE]; 558 String8 result; 559 560 snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy); 561 result.append(buffer); 562 snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); 563 result.append(buffer); 564 snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); 565 result.append(buffer); 566 567 write(fd, result.string(), result.size()); 568 return NO_ERROR; 569} 570 571status_t AudioPolicyService::dump(int fd, const Vector<String16>& args) 572{ 573 if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 574 dumpPermissionDenial(fd); 575 } else { 576 bool locked = tryLock(mLock); 577 if (!locked) { 578 String8 result(kDeadlockedString); 579 write(fd, result.string(), result.size()); 580 } 581 582 dumpInternals(fd); 583 if (mAudioCommandThread != NULL) { 584 mAudioCommandThread->dump(fd); 585 } 586 if (mTonePlaybackThread != NULL) { 587 mTonePlaybackThread->dump(fd); 588 } 589 590 if (mpAudioPolicy) { 591 mpAudioPolicy->dump(mpAudioPolicy, fd); 592 } 593 594 if (locked) mLock.unlock(); 595 } 596 return NO_ERROR; 597} 598 599status_t AudioPolicyService::dumpPermissionDenial(int fd) 600{ 601 const size_t SIZE = 256; 602 char buffer[SIZE]; 603 String8 result; 604 snprintf(buffer, SIZE, "Permission Denial: " 605 "can't dump AudioPolicyService from pid=%d, uid=%d\n", 606 IPCThreadState::self()->getCallingPid(), 607 IPCThreadState::self()->getCallingUid()); 608 result.append(buffer); 609 write(fd, result.string(), result.size()); 610 return NO_ERROR; 611} 612 613void AudioPolicyService::setPreProcessorEnabled(InputDesc *inputDesc, bool enabled) 614{ 615 Vector<sp<AudioEffect> > fxVector = inputDesc->mEffects; 616 for (size_t i = 0; i < fxVector.size(); i++) { 617 sp<AudioEffect> fx = fxVector.itemAt(i); 618 fx->setEnabled(enabled); 619 } 620} 621 622status_t AudioPolicyService::onTransact( 623 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 624{ 625 return BnAudioPolicyService::onTransact(code, data, reply, flags); 626} 627 628 629// ----------- AudioPolicyService::AudioCommandThread implementation ---------- 630 631AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name) 632 : Thread(false), mName(name) 633{ 634 mpToneGenerator = NULL; 635} 636 637 638AudioPolicyService::AudioCommandThread::~AudioCommandThread() 639{ 640 if (mName != "" && !mAudioCommands.isEmpty()) { 641 release_wake_lock(mName.string()); 642 } 643 mAudioCommands.clear(); 644 if (mpToneGenerator != NULL) delete mpToneGenerator; 645} 646 647void AudioPolicyService::AudioCommandThread::onFirstRef() 648{ 649 if (mName != "") { 650 run(mName.string(), ANDROID_PRIORITY_AUDIO); 651 } else { 652 run("AudioCommandThread", ANDROID_PRIORITY_AUDIO); 653 } 654} 655 656bool AudioPolicyService::AudioCommandThread::threadLoop() 657{ 658 nsecs_t waitTime = INT64_MAX; 659 660 mLock.lock(); 661 while (!exitPending()) 662 { 663 while(!mAudioCommands.isEmpty()) { 664 nsecs_t curTime = systemTime(); 665 // commands are sorted by increasing time stamp: execute them from index 0 and up 666 if (mAudioCommands[0]->mTime <= curTime) { 667 AudioCommand *command = mAudioCommands[0]; 668 mAudioCommands.removeAt(0); 669 mLastCommand = *command; 670 671 switch (command->mCommand) { 672 case START_TONE: { 673 mLock.unlock(); 674 ToneData *data = (ToneData *)command->mParam; 675 LOGV("AudioCommandThread() processing start tone %d on stream %d", 676 data->mType, data->mStream); 677 if (mpToneGenerator != NULL) 678 delete mpToneGenerator; 679 mpToneGenerator = new ToneGenerator(data->mStream, 1.0); 680 mpToneGenerator->startTone(data->mType); 681 delete data; 682 mLock.lock(); 683 }break; 684 case STOP_TONE: { 685 mLock.unlock(); 686 LOGV("AudioCommandThread() processing stop tone"); 687 if (mpToneGenerator != NULL) { 688 mpToneGenerator->stopTone(); 689 delete mpToneGenerator; 690 mpToneGenerator = NULL; 691 } 692 mLock.lock(); 693 }break; 694 case SET_VOLUME: { 695 VolumeData *data = (VolumeData *)command->mParam; 696 LOGV("AudioCommandThread() processing set volume stream %d, \ 697 volume %f, output %d", data->mStream, data->mVolume, data->mIO); 698 command->mStatus = AudioSystem::setStreamVolume(data->mStream, 699 data->mVolume, 700 data->mIO); 701 if (command->mWaitStatus) { 702 command->mCond.signal(); 703 mWaitWorkCV.wait(mLock); 704 } 705 delete data; 706 }break; 707 case SET_PARAMETERS: { 708 ParametersData *data = (ParametersData *)command->mParam; 709 LOGV("AudioCommandThread() processing set parameters string %s, io %d", 710 data->mKeyValuePairs.string(), data->mIO); 711 command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); 712 if (command->mWaitStatus) { 713 command->mCond.signal(); 714 mWaitWorkCV.wait(mLock); 715 } 716 delete data; 717 }break; 718 case SET_VOICE_VOLUME: { 719 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam; 720 LOGV("AudioCommandThread() processing set voice volume volume %f", 721 data->mVolume); 722 command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); 723 if (command->mWaitStatus) { 724 command->mCond.signal(); 725 mWaitWorkCV.wait(mLock); 726 } 727 delete data; 728 }break; 729 default: 730 LOGW("AudioCommandThread() unknown command %d", command->mCommand); 731 } 732 delete command; 733 waitTime = INT64_MAX; 734 } else { 735 waitTime = mAudioCommands[0]->mTime - curTime; 736 break; 737 } 738 } 739 // release delayed commands wake lock 740 if (mName != "" && mAudioCommands.isEmpty()) { 741 release_wake_lock(mName.string()); 742 } 743 LOGV("AudioCommandThread() going to sleep"); 744 mWaitWorkCV.waitRelative(mLock, waitTime); 745 LOGV("AudioCommandThread() waking up"); 746 } 747 mLock.unlock(); 748 return false; 749} 750 751status_t AudioPolicyService::AudioCommandThread::dump(int fd) 752{ 753 const size_t SIZE = 256; 754 char buffer[SIZE]; 755 String8 result; 756 757 snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 758 result.append(buffer); 759 write(fd, result.string(), result.size()); 760 761 bool locked = tryLock(mLock); 762 if (!locked) { 763 String8 result2(kCmdDeadlockedString); 764 write(fd, result2.string(), result2.size()); 765 } 766 767 snprintf(buffer, SIZE, "- Commands:\n"); 768 result = String8(buffer); 769 result.append(" Command Time Wait pParam\n"); 770 for (int i = 0; i < (int)mAudioCommands.size(); i++) { 771 mAudioCommands[i]->dump(buffer, SIZE); 772 result.append(buffer); 773 } 774 result.append(" Last Command\n"); 775 mLastCommand.dump(buffer, SIZE); 776 result.append(buffer); 777 778 write(fd, result.string(), result.size()); 779 780 if (locked) mLock.unlock(); 781 782 return NO_ERROR; 783} 784 785void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream) 786{ 787 AudioCommand *command = new AudioCommand(); 788 command->mCommand = START_TONE; 789 ToneData *data = new ToneData(); 790 data->mType = type; 791 data->mStream = stream; 792 command->mParam = (void *)data; 793 command->mWaitStatus = false; 794 Mutex::Autolock _l(mLock); 795 insertCommand_l(command); 796 LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 797 mWaitWorkCV.signal(); 798} 799 800void AudioPolicyService::AudioCommandThread::stopToneCommand() 801{ 802 AudioCommand *command = new AudioCommand(); 803 command->mCommand = STOP_TONE; 804 command->mParam = NULL; 805 command->mWaitStatus = false; 806 Mutex::Autolock _l(mLock); 807 insertCommand_l(command); 808 LOGV("AudioCommandThread() adding tone stop"); 809 mWaitWorkCV.signal(); 810} 811 812status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, 813 float volume, 814 int output, 815 int delayMs) 816{ 817 status_t status = NO_ERROR; 818 819 AudioCommand *command = new AudioCommand(); 820 command->mCommand = SET_VOLUME; 821 VolumeData *data = new VolumeData(); 822 data->mStream = stream; 823 data->mVolume = volume; 824 data->mIO = output; 825 command->mParam = data; 826 if (delayMs == 0) { 827 command->mWaitStatus = true; 828 } else { 829 command->mWaitStatus = false; 830 } 831 Mutex::Autolock _l(mLock); 832 insertCommand_l(command, delayMs); 833 LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 834 stream, volume, output); 835 mWaitWorkCV.signal(); 836 if (command->mWaitStatus) { 837 command->mCond.wait(mLock); 838 status = command->mStatus; 839 mWaitWorkCV.signal(); 840 } 841 return status; 842} 843 844status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, 845 const char *keyValuePairs, 846 int delayMs) 847{ 848 status_t status = NO_ERROR; 849 850 AudioCommand *command = new AudioCommand(); 851 command->mCommand = SET_PARAMETERS; 852 ParametersData *data = new ParametersData(); 853 data->mIO = ioHandle; 854 data->mKeyValuePairs = String8(keyValuePairs); 855 command->mParam = data; 856 if (delayMs == 0) { 857 command->mWaitStatus = true; 858 } else { 859 command->mWaitStatus = false; 860 } 861 Mutex::Autolock _l(mLock); 862 insertCommand_l(command, delayMs); 863 LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 864 keyValuePairs, ioHandle, delayMs); 865 mWaitWorkCV.signal(); 866 if (command->mWaitStatus) { 867 command->mCond.wait(mLock); 868 status = command->mStatus; 869 mWaitWorkCV.signal(); 870 } 871 return status; 872} 873 874status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 875{ 876 status_t status = NO_ERROR; 877 878 AudioCommand *command = new AudioCommand(); 879 command->mCommand = SET_VOICE_VOLUME; 880 VoiceVolumeData *data = new VoiceVolumeData(); 881 data->mVolume = volume; 882 command->mParam = data; 883 if (delayMs == 0) { 884 command->mWaitStatus = true; 885 } else { 886 command->mWaitStatus = false; 887 } 888 Mutex::Autolock _l(mLock); 889 insertCommand_l(command, delayMs); 890 LOGV("AudioCommandThread() adding set voice volume volume %f", volume); 891 mWaitWorkCV.signal(); 892 if (command->mWaitStatus) { 893 command->mCond.wait(mLock); 894 status = command->mStatus; 895 mWaitWorkCV.signal(); 896 } 897 return status; 898} 899 900// insertCommand_l() must be called with mLock held 901void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs) 902{ 903 ssize_t i; 904 Vector <AudioCommand *> removedCommands; 905 906 command->mTime = systemTime() + milliseconds(delayMs); 907 908 // acquire wake lock to make sure delayed commands are processed 909 if (mName != "" && mAudioCommands.isEmpty()) { 910 acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 911 } 912 913 // check same pending commands with later time stamps and eliminate them 914 for (i = mAudioCommands.size()-1; i >= 0; i--) { 915 AudioCommand *command2 = mAudioCommands[i]; 916 // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 917 if (command2->mTime <= command->mTime) break; 918 if (command2->mCommand != command->mCommand) continue; 919 920 switch (command->mCommand) { 921 case SET_PARAMETERS: { 922 ParametersData *data = (ParametersData *)command->mParam; 923 ParametersData *data2 = (ParametersData *)command2->mParam; 924 if (data->mIO != data2->mIO) break; 925 LOGV("Comparing parameter command %s to new command %s", 926 data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 927 AudioParameter param = AudioParameter(data->mKeyValuePairs); 928 AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 929 for (size_t j = 0; j < param.size(); j++) { 930 String8 key; 931 String8 value; 932 param.getAt(j, key, value); 933 for (size_t k = 0; k < param2.size(); k++) { 934 String8 key2; 935 String8 value2; 936 param2.getAt(k, key2, value2); 937 if (key2 == key) { 938 param2.remove(key2); 939 LOGV("Filtering out parameter %s", key2.string()); 940 break; 941 } 942 } 943 } 944 // if all keys have been filtered out, remove the command. 945 // otherwise, update the key value pairs 946 if (param2.size() == 0) { 947 removedCommands.add(command2); 948 } else { 949 data2->mKeyValuePairs = param2.toString(); 950 } 951 } break; 952 953 case SET_VOLUME: { 954 VolumeData *data = (VolumeData *)command->mParam; 955 VolumeData *data2 = (VolumeData *)command2->mParam; 956 if (data->mIO != data2->mIO) break; 957 if (data->mStream != data2->mStream) break; 958 LOGV("Filtering out volume command on output %d for stream %d", 959 data->mIO, data->mStream); 960 removedCommands.add(command2); 961 } break; 962 case START_TONE: 963 case STOP_TONE: 964 default: 965 break; 966 } 967 } 968 969 // remove filtered commands 970 for (size_t j = 0; j < removedCommands.size(); j++) { 971 // removed commands always have time stamps greater than current command 972 for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 973 if (mAudioCommands[k] == removedCommands[j]) { 974 LOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 975 mAudioCommands.removeAt(k); 976 break; 977 } 978 } 979 } 980 removedCommands.clear(); 981 982 // insert command at the right place according to its time stamp 983 LOGV("inserting command: %d at index %d, num commands %d", 984 command->mCommand, (int)i+1, mAudioCommands.size()); 985 mAudioCommands.insertAt(command, i + 1); 986} 987 988void AudioPolicyService::AudioCommandThread::exit() 989{ 990 LOGV("AudioCommandThread::exit"); 991 { 992 AutoMutex _l(mLock); 993 requestExit(); 994 mWaitWorkCV.signal(); 995 } 996 requestExitAndWait(); 997} 998 999void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 1000{ 1001 snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 1002 mCommand, 1003 (int)ns2s(mTime), 1004 (int)ns2ms(mTime)%1000, 1005 mWaitStatus, 1006 mParam); 1007} 1008 1009/******* helpers for the service_ops callbacks defined below *********/ 1010void AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 1011 const char *keyValuePairs, 1012 int delayMs) 1013{ 1014 mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs, 1015 delayMs); 1016} 1017 1018int AudioPolicyService::setStreamVolume(audio_stream_type_t stream, 1019 float volume, 1020 audio_io_handle_t output, 1021 int delayMs) 1022{ 1023 return (int)mAudioCommandThread->volumeCommand((int)stream, volume, 1024 (int)output, delayMs); 1025} 1026 1027int AudioPolicyService::startTone(audio_policy_tone_t tone, 1028 audio_stream_type_t stream) 1029{ 1030 if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) 1031 LOGE("startTone: illegal tone requested (%d)", tone); 1032 if (stream != AUDIO_STREAM_VOICE_CALL) 1033 LOGE("startTone: illegal stream (%d) requested for tone %d", stream, 1034 tone); 1035 mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING, 1036 AUDIO_STREAM_VOICE_CALL); 1037 return 0; 1038} 1039 1040int AudioPolicyService::stopTone() 1041{ 1042 mTonePlaybackThread->stopToneCommand(); 1043 return 0; 1044} 1045 1046int AudioPolicyService::setVoiceVolume(float volume, int delayMs) 1047{ 1048 return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 1049} 1050 1051// ---------------------------------------------------------------------------- 1052// Audio pre-processing configuration 1053// ---------------------------------------------------------------------------- 1054 1055const char *AudioPolicyService::kInputSourceNames[AUDIO_SOURCE_CNT -1] = { 1056 MIC_SRC_TAG, 1057 VOICE_UL_SRC_TAG, 1058 VOICE_DL_SRC_TAG, 1059 VOICE_CALL_SRC_TAG, 1060 CAMCORDER_SRC_TAG, 1061 VOICE_REC_SRC_TAG, 1062 VOICE_COMM_SRC_TAG 1063}; 1064 1065// returns the audio_source_t enum corresponding to the input source name or 1066// AUDIO_SOURCE_CNT is no match found 1067audio_source_t AudioPolicyService::inputSourceNameToEnum(const char *name) 1068{ 1069 int i; 1070 for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) { 1071 if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) { 1072 LOGV("inputSourceNameToEnum found source %s %d", name, i); 1073 break; 1074 } 1075 } 1076 return (audio_source_t)i; 1077} 1078 1079size_t AudioPolicyService::growParamSize(char *param, 1080 size_t size, 1081 size_t *curSize, 1082 size_t *totSize) 1083{ 1084 // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int) 1085 size_t pos = ((*curSize - 1 ) / size + 1) * size; 1086 1087 if (pos + size > *totSize) { 1088 while (pos + size > *totSize) { 1089 *totSize += ((*totSize + 7) / 8) * 4; 1090 } 1091 param = (char *)realloc(param, *totSize); 1092 } 1093 *curSize = pos + size; 1094 return pos; 1095} 1096 1097size_t AudioPolicyService::readParamValue(cnode *node, 1098 char *param, 1099 size_t *curSize, 1100 size_t *totSize) 1101{ 1102 if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) { 1103 size_t pos = growParamSize(param, sizeof(short), curSize, totSize); 1104 *(short *)((char *)param + pos) = (short)atoi(node->value); 1105 LOGV("readParamValue() reading short %d", *(short *)((char *)param + pos)); 1106 return sizeof(short); 1107 } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) { 1108 size_t pos = growParamSize(param, sizeof(int), curSize, totSize); 1109 *(int *)((char *)param + pos) = atoi(node->value); 1110 LOGV("readParamValue() reading int %d", *(int *)((char *)param + pos)); 1111 return sizeof(int); 1112 } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) { 1113 size_t pos = growParamSize(param, sizeof(float), curSize, totSize); 1114 *(float *)((char *)param + pos) = (float)atof(node->value); 1115 LOGV("readParamValue() reading float %f",*(float *)((char *)param + pos)); 1116 return sizeof(float); 1117 } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) { 1118 size_t pos = growParamSize(param, sizeof(bool), curSize, totSize); 1119 if (strncmp(node->value, "false", strlen("false") + 1) == 0) { 1120 *(bool *)((char *)param + pos) = false; 1121 } else { 1122 *(bool *)((char *)param + pos) = true; 1123 } 1124 LOGV("readParamValue() reading bool %s",*(bool *)((char *)param + pos) ? "true" : "false"); 1125 return sizeof(bool); 1126 } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) { 1127 size_t len = strnlen(node->value, EFFECT_STRING_LEN_MAX); 1128 if (*curSize + len + 1 > *totSize) { 1129 *totSize = *curSize + len + 1; 1130 param = (char *)realloc(param, *totSize); 1131 } 1132 strncpy(param + *curSize, node->value, len); 1133 *curSize += len; 1134 param[*curSize] = '\0'; 1135 LOGV("readParamValue() reading string %s", param + *curSize - len); 1136 return len; 1137 } 1138 LOGW("readParamValue() unknown param type %s", node->name); 1139 return 0; 1140} 1141 1142effect_param_t *AudioPolicyService::loadEffectParameter(cnode *root) 1143{ 1144 cnode *param; 1145 cnode *value; 1146 size_t curSize = sizeof(effect_param_t); 1147 size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int); 1148 effect_param_t *fx_param = (effect_param_t *)malloc(totSize); 1149 1150 param = config_find(root, PARAM_TAG); 1151 value = config_find(root, VALUE_TAG); 1152 if (param == NULL && value == NULL) { 1153 // try to parse simple parameter form {int int} 1154 param = root->first_child; 1155 if (param) { 1156 // Note: that a pair of random strings is read as 0 0 1157 int *ptr = (int *)fx_param->data; 1158 int *ptr2 = (int *)((char *)param + sizeof(effect_param_t)); 1159 LOGW("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2); 1160 *ptr++ = atoi(param->name); 1161 *ptr = atoi(param->value); 1162 fx_param->psize = sizeof(int); 1163 fx_param->vsize = sizeof(int); 1164 return fx_param; 1165 } 1166 } 1167 if (param == NULL || value == NULL) { 1168 LOGW("loadEffectParameter() invalid parameter description %s", root->name); 1169 goto error; 1170 } 1171 1172 fx_param->psize = 0; 1173 param = param->first_child; 1174 while (param) { 1175 LOGV("loadEffectParameter() reading param of type %s", param->name); 1176 size_t size = readParamValue(param, (char *)fx_param, &curSize, &totSize); 1177 if (size == 0) { 1178 goto error; 1179 } 1180 fx_param->psize += size; 1181 param = param->next; 1182 } 1183 1184 // align start of value field on 32 bit boundary 1185 curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int); 1186 1187 fx_param->vsize = 0; 1188 value = value->first_child; 1189 while (value) { 1190 LOGV("loadEffectParameter() reading value of type %s", value->name); 1191 size_t size = readParamValue(value, (char *)fx_param, &curSize, &totSize); 1192 if (size == 0) { 1193 goto error; 1194 } 1195 fx_param->vsize += size; 1196 value = value->next; 1197 } 1198 1199 return fx_param; 1200 1201error: 1202 delete fx_param; 1203 return NULL; 1204} 1205 1206void AudioPolicyService::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params) 1207{ 1208 cnode *node = root->first_child; 1209 while (node) { 1210 LOGV("loadEffectParameters() loading param %s", node->name); 1211 effect_param_t *param = loadEffectParameter(node); 1212 if (param == NULL) { 1213 node = node->next; 1214 continue; 1215 } 1216 params.add(param); 1217 node = node->next; 1218 } 1219} 1220 1221AudioPolicyService::InputSourceDesc *AudioPolicyService::loadInputSource( 1222 cnode *root, 1223 const Vector <EffectDesc *>& effects) 1224{ 1225 cnode *node = root->first_child; 1226 if (node == NULL) { 1227 LOGW("loadInputSource() empty element %s", root->name); 1228 return NULL; 1229 } 1230 InputSourceDesc *source = new InputSourceDesc(); 1231 while (node) { 1232 size_t i; 1233 for (i = 0; i < effects.size(); i++) { 1234 if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) { 1235 LOGV("loadInputSource() found effect %s in list", node->name); 1236 break; 1237 } 1238 } 1239 if (i == effects.size()) { 1240 LOGV("loadInputSource() effect %s not in list", node->name); 1241 node = node->next; 1242 continue; 1243 } 1244 EffectDesc *effect = new EffectDesc(*effects[i]); 1245 loadEffectParameters(node, effect->mParams); 1246 LOGV("loadInputSource() adding effect %s uuid %08x", effect->mName, effect->mUuid.timeLow); 1247 source->mEffects.add(effect); 1248 node = node->next; 1249 } 1250 if (source->mEffects.size() == 0) { 1251 LOGW("loadInputSource() no valid effects found in source %s", root->name); 1252 delete source; 1253 return NULL; 1254 } 1255 return source; 1256} 1257 1258status_t AudioPolicyService::loadInputSources(cnode *root, const Vector <EffectDesc *>& effects) 1259{ 1260 cnode *node = config_find(root, PREPROCESSING_TAG); 1261 if (node == NULL) { 1262 return -ENOENT; 1263 } 1264 node = node->first_child; 1265 while (node) { 1266 audio_source_t source = inputSourceNameToEnum(node->name); 1267 if (source == AUDIO_SOURCE_CNT) { 1268 LOGW("loadInputSources() invalid input source %s", node->name); 1269 node = node->next; 1270 continue; 1271 } 1272 LOGV("loadInputSources() loading input source %s", node->name); 1273 InputSourceDesc *desc = loadInputSource(node, effects); 1274 if (desc == NULL) { 1275 node = node->next; 1276 continue; 1277 } 1278 mInputSources.add(source, desc); 1279 node = node->next; 1280 } 1281 return NO_ERROR; 1282} 1283 1284AudioPolicyService::EffectDesc *AudioPolicyService::loadEffect(cnode *root) 1285{ 1286 cnode *node = config_find(root, UUID_TAG); 1287 if (node == NULL) { 1288 return NULL; 1289 } 1290 effect_uuid_t uuid; 1291 if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) { 1292 LOGW("loadEffect() invalid uuid %s", node->value); 1293 return NULL; 1294 } 1295 EffectDesc *effect = new EffectDesc(); 1296 effect->mName = strdup(root->name); 1297 memcpy(&effect->mUuid, &uuid, sizeof(effect_uuid_t)); 1298 1299 return effect; 1300} 1301 1302status_t AudioPolicyService::loadEffects(cnode *root, Vector <EffectDesc *>& effects) 1303{ 1304 cnode *node = config_find(root, EFFECTS_TAG); 1305 if (node == NULL) { 1306 return -ENOENT; 1307 } 1308 node = node->first_child; 1309 while (node) { 1310 LOGV("loadEffects() loading effect %s", node->name); 1311 EffectDesc *effect = loadEffect(node); 1312 if (effect == NULL) { 1313 node = node->next; 1314 continue; 1315 } 1316 effects.add(effect); 1317 node = node->next; 1318 } 1319 return NO_ERROR; 1320} 1321 1322status_t AudioPolicyService::loadPreProcessorConfig(const char *path) 1323{ 1324 cnode *root; 1325 char *data; 1326 1327 data = (char *)load_file(path, NULL); 1328 if (data == NULL) { 1329 return -ENODEV; 1330 } 1331 root = config_node("", ""); 1332 config_load(root, data); 1333 1334 Vector <EffectDesc *> effects; 1335 loadEffects(root, effects); 1336 loadInputSources(root, effects); 1337 1338 config_free(root); 1339 free(root); 1340 free(data); 1341 1342 return NO_ERROR; 1343} 1344 1345/* implementation of the interface to the policy manager */ 1346extern "C" { 1347 1348static audio_io_handle_t aps_open_output(void *service, 1349 uint32_t *pDevices, 1350 uint32_t *pSamplingRate, 1351 uint32_t *pFormat, 1352 uint32_t *pChannels, 1353 uint32_t *pLatencyMs, 1354 audio_policy_output_flags_t flags) 1355{ 1356 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 1357 if (af == NULL) { 1358 LOGW("%s: could not get AudioFlinger", __func__); 1359 return 0; 1360 } 1361 1362 return af->openOutput(pDevices, pSamplingRate, pFormat, pChannels, 1363 pLatencyMs, flags); 1364} 1365 1366static audio_io_handle_t aps_open_dup_output(void *service, 1367 audio_io_handle_t output1, 1368 audio_io_handle_t output2) 1369{ 1370 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 1371 if (af == NULL) { 1372 LOGW("%s: could not get AudioFlinger", __func__); 1373 return 0; 1374 } 1375 return af->openDuplicateOutput(output1, output2); 1376} 1377 1378static int aps_close_output(void *service, audio_io_handle_t output) 1379{ 1380 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 1381 if (af == NULL) 1382 return PERMISSION_DENIED; 1383 1384 return af->closeOutput(output); 1385} 1386 1387static int aps_suspend_output(void *service, audio_io_handle_t output) 1388{ 1389 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 1390 if (af == NULL) { 1391 LOGW("%s: could not get AudioFlinger", __func__); 1392 return PERMISSION_DENIED; 1393 } 1394 1395 return af->suspendOutput(output); 1396} 1397 1398static int aps_restore_output(void *service, audio_io_handle_t output) 1399{ 1400 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 1401 if (af == NULL) { 1402 LOGW("%s: could not get AudioFlinger", __func__); 1403 return PERMISSION_DENIED; 1404 } 1405 1406 return af->restoreOutput(output); 1407} 1408 1409static audio_io_handle_t aps_open_input(void *service, 1410 uint32_t *pDevices, 1411 uint32_t *pSamplingRate, 1412 uint32_t *pFormat, 1413 uint32_t *pChannels, 1414 uint32_t acoustics) 1415{ 1416 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 1417 if (af == NULL) { 1418 LOGW("%s: could not get AudioFlinger", __func__); 1419 return 0; 1420 } 1421 1422 return af->openInput(pDevices, pSamplingRate, pFormat, pChannels, 1423 acoustics); 1424} 1425 1426static int aps_close_input(void *service, audio_io_handle_t input) 1427{ 1428 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 1429 if (af == NULL) 1430 return PERMISSION_DENIED; 1431 1432 return af->closeInput(input); 1433} 1434 1435static int aps_set_stream_output(void *service, audio_stream_type_t stream, 1436 audio_io_handle_t output) 1437{ 1438 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 1439 if (af == NULL) 1440 return PERMISSION_DENIED; 1441 1442 return af->setStreamOutput(stream, output); 1443} 1444 1445static int aps_move_effects(void *service, int session, 1446 audio_io_handle_t src_output, 1447 audio_io_handle_t dst_output) 1448{ 1449 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 1450 if (af == NULL) 1451 return PERMISSION_DENIED; 1452 1453 return af->moveEffects(session, (int)src_output, (int)dst_output); 1454} 1455 1456static char * aps_get_parameters(void *service, audio_io_handle_t io_handle, 1457 const char *keys) 1458{ 1459 String8 result = AudioSystem::getParameters(io_handle, String8(keys)); 1460 return strdup(result.string()); 1461} 1462 1463static void aps_set_parameters(void *service, audio_io_handle_t io_handle, 1464 const char *kv_pairs, int delay_ms) 1465{ 1466 AudioPolicyService *audioPolicyService = (AudioPolicyService *)service; 1467 1468 audioPolicyService->setParameters(io_handle, kv_pairs, delay_ms); 1469} 1470 1471static int aps_set_stream_volume(void *service, audio_stream_type_t stream, 1472 float volume, audio_io_handle_t output, 1473 int delay_ms) 1474{ 1475 AudioPolicyService *audioPolicyService = (AudioPolicyService *)service; 1476 1477 return audioPolicyService->setStreamVolume(stream, volume, output, 1478 delay_ms); 1479} 1480 1481static int aps_start_tone(void *service, audio_policy_tone_t tone, 1482 audio_stream_type_t stream) 1483{ 1484 AudioPolicyService *audioPolicyService = (AudioPolicyService *)service; 1485 1486 return audioPolicyService->startTone(tone, stream); 1487} 1488 1489static int aps_stop_tone(void *service) 1490{ 1491 AudioPolicyService *audioPolicyService = (AudioPolicyService *)service; 1492 1493 return audioPolicyService->stopTone(); 1494} 1495 1496static int aps_set_voice_volume(void *service, float volume, int delay_ms) 1497{ 1498 AudioPolicyService *audioPolicyService = (AudioPolicyService *)service; 1499 1500 return audioPolicyService->setVoiceVolume(volume, delay_ms); 1501} 1502 1503}; // extern "C" 1504 1505namespace { 1506 struct audio_policy_service_ops aps_ops = { 1507 open_output : aps_open_output, 1508 open_duplicate_output : aps_open_dup_output, 1509 close_output : aps_close_output, 1510 suspend_output : aps_suspend_output, 1511 restore_output : aps_restore_output, 1512 open_input : aps_open_input, 1513 close_input : aps_close_input, 1514 set_stream_volume : aps_set_stream_volume, 1515 set_stream_output : aps_set_stream_output, 1516 set_parameters : aps_set_parameters, 1517 get_parameters : aps_get_parameters, 1518 start_tone : aps_start_tone, 1519 stop_tone : aps_stop_tone, 1520 set_voice_volume : aps_set_voice_volume, 1521 move_effects : aps_move_effects, 1522 }; 1523}; // namespace <unnamed> 1524 1525}; // namespace android 1526