1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "AudioPolicyService" 18//#define LOG_NDEBUG 0 19 20#include "Configuration.h" 21#undef __STRICT_ANSI__ 22#define __STDINT_LIMITS 23#define __STDC_LIMIT_MACROS 24#include <stdint.h> 25 26#include <sys/time.h> 27#include <binder/IServiceManager.h> 28#include <utils/Log.h> 29#include <cutils/properties.h> 30#include <binder/IPCThreadState.h> 31#include <utils/String16.h> 32#include <utils/threads.h> 33#include "AudioPolicyService.h" 34#include "ServiceUtilities.h" 35#include <hardware_legacy/power.h> 36#include <media/AudioEffect.h> 37#include <media/AudioParameter.h> 38 39#include <system/audio.h> 40#include <system/audio_policy.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 kDumpLockSleepUs = 20000; 49 50static const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds 51 52 53// ---------------------------------------------------------------------------- 54 55AudioPolicyService::AudioPolicyService() 56 : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL), 57 mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID) 58{ 59} 60 61void AudioPolicyService::onFirstRef() 62{ 63 { 64 Mutex::Autolock _l(mLock); 65 66 // start tone playback thread 67 mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this); 68 // start audio commands thread 69 mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this); 70 // start output activity command thread 71 mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this); 72 73 mAudioPolicyClient = new AudioPolicyClient(this); 74 mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); 75 } 76 // load audio processing modules 77 sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects(); 78 { 79 Mutex::Autolock _l(mLock); 80 mAudioPolicyEffects = audioPolicyEffects; 81 } 82} 83 84AudioPolicyService::~AudioPolicyService() 85{ 86 mTonePlaybackThread->exit(); 87 mAudioCommandThread->exit(); 88 mOutputCommandThread->exit(); 89 90 destroyAudioPolicyManager(mAudioPolicyManager); 91 delete mAudioPolicyClient; 92 93 mNotificationClients.clear(); 94 mAudioPolicyEffects.clear(); 95} 96 97// A notification client is always registered by AudioSystem when the client process 98// connects to AudioPolicyService. 99void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client) 100{ 101 if (client == 0) { 102 ALOGW("%s got NULL client", __FUNCTION__); 103 return; 104 } 105 Mutex::Autolock _l(mNotificationClientsLock); 106 107 uid_t uid = IPCThreadState::self()->getCallingUid(); 108 if (mNotificationClients.indexOfKey(uid) < 0) { 109 sp<NotificationClient> notificationClient = new NotificationClient(this, 110 client, 111 uid); 112 ALOGV("registerClient() client %p, uid %d", client.get(), uid); 113 114 mNotificationClients.add(uid, notificationClient); 115 116 sp<IBinder> binder = IInterface::asBinder(client); 117 binder->linkToDeath(notificationClient); 118 } 119} 120 121void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled) 122{ 123 Mutex::Autolock _l(mNotificationClientsLock); 124 125 uid_t uid = IPCThreadState::self()->getCallingUid(); 126 if (mNotificationClients.indexOfKey(uid) < 0) { 127 return; 128 } 129 mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled); 130} 131 132// removeNotificationClient() is called when the client process dies. 133void AudioPolicyService::removeNotificationClient(uid_t uid) 134{ 135 { 136 Mutex::Autolock _l(mNotificationClientsLock); 137 mNotificationClients.removeItem(uid); 138 } 139 { 140 Mutex::Autolock _l(mLock); 141 if (mAudioPolicyManager) { 142 mAudioPolicyManager->releaseResourcesForUid(uid); 143 } 144 } 145} 146 147void AudioPolicyService::onAudioPortListUpdate() 148{ 149 mOutputCommandThread->updateAudioPortListCommand(); 150} 151 152void AudioPolicyService::doOnAudioPortListUpdate() 153{ 154 Mutex::Autolock _l(mNotificationClientsLock); 155 for (size_t i = 0; i < mNotificationClients.size(); i++) { 156 mNotificationClients.valueAt(i)->onAudioPortListUpdate(); 157 } 158} 159 160void AudioPolicyService::onAudioPatchListUpdate() 161{ 162 mOutputCommandThread->updateAudioPatchListCommand(); 163} 164 165void AudioPolicyService::doOnAudioPatchListUpdate() 166{ 167 Mutex::Autolock _l(mNotificationClientsLock); 168 for (size_t i = 0; i < mNotificationClients.size(); i++) { 169 mNotificationClients.valueAt(i)->onAudioPatchListUpdate(); 170 } 171} 172 173void AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state) 174{ 175 ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)", 176 regId.string(), state); 177 mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state); 178} 179 180void AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state) 181{ 182 Mutex::Autolock _l(mNotificationClientsLock); 183 for (size_t i = 0; i < mNotificationClients.size(); i++) { 184 mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state); 185 } 186} 187 188void AudioPolicyService::onRecordingConfigurationUpdate(int event, audio_session_t session, 189 audio_source_t source, const audio_config_base_t *clientConfig, 190 const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) 191{ 192 mOutputCommandThread->recordingConfigurationUpdateCommand(event, session, source, 193 clientConfig, deviceConfig, patchHandle); 194} 195 196void AudioPolicyService::doOnRecordingConfigurationUpdate(int event, audio_session_t session, 197 audio_source_t source, const audio_config_base_t *clientConfig, 198 const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) 199{ 200 Mutex::Autolock _l(mNotificationClientsLock); 201 for (size_t i = 0; i < mNotificationClients.size(); i++) { 202 mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, session, source, 203 clientConfig, deviceConfig, patchHandle); 204 } 205} 206 207status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch, 208 audio_patch_handle_t *handle, 209 int delayMs) 210{ 211 return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs); 212} 213 214status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle, 215 int delayMs) 216{ 217 return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs); 218} 219 220status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config, 221 int delayMs) 222{ 223 return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); 224} 225 226AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service, 227 const sp<IAudioPolicyServiceClient>& client, 228 uid_t uid) 229 : mService(service), mUid(uid), mAudioPolicyServiceClient(client), 230 mAudioPortCallbacksEnabled(false) 231{ 232} 233 234AudioPolicyService::NotificationClient::~NotificationClient() 235{ 236} 237 238void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused) 239{ 240 sp<NotificationClient> keep(this); 241 sp<AudioPolicyService> service = mService.promote(); 242 if (service != 0) { 243 service->removeNotificationClient(mUid); 244 } 245} 246 247void AudioPolicyService::NotificationClient::onAudioPortListUpdate() 248{ 249 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 250 mAudioPolicyServiceClient->onAudioPortListUpdate(); 251 } 252} 253 254void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() 255{ 256 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 257 mAudioPolicyServiceClient->onAudioPatchListUpdate(); 258 } 259} 260 261void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( 262 const String8& regId, int32_t state) 263{ 264 if (mAudioPolicyServiceClient != 0) { 265 mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state); 266 } 267} 268 269void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate( 270 int event, audio_session_t session, audio_source_t source, 271 const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, 272 audio_patch_handle_t patchHandle) 273{ 274 if (mAudioPolicyServiceClient != 0) { 275 mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, session, source, 276 clientConfig, deviceConfig, patchHandle); 277 } 278} 279 280void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled) 281{ 282 mAudioPortCallbacksEnabled = enabled; 283} 284 285 286void AudioPolicyService::binderDied(const wp<IBinder>& who) { 287 ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), 288 IPCThreadState::self()->getCallingPid()); 289} 290 291static bool tryLock(Mutex& mutex) 292{ 293 bool locked = false; 294 for (int i = 0; i < kDumpLockRetries; ++i) { 295 if (mutex.tryLock() == NO_ERROR) { 296 locked = true; 297 break; 298 } 299 usleep(kDumpLockSleepUs); 300 } 301 return locked; 302} 303 304status_t AudioPolicyService::dumpInternals(int fd) 305{ 306 const size_t SIZE = 256; 307 char buffer[SIZE]; 308 String8 result; 309 310 snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager); 311 result.append(buffer); 312 snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); 313 result.append(buffer); 314 snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); 315 result.append(buffer); 316 317 write(fd, result.string(), result.size()); 318 return NO_ERROR; 319} 320 321status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused) 322{ 323 if (!dumpAllowed()) { 324 dumpPermissionDenial(fd); 325 } else { 326 bool locked = tryLock(mLock); 327 if (!locked) { 328 String8 result(kDeadlockedString); 329 write(fd, result.string(), result.size()); 330 } 331 332 dumpInternals(fd); 333 if (mAudioCommandThread != 0) { 334 mAudioCommandThread->dump(fd); 335 } 336 if (mTonePlaybackThread != 0) { 337 mTonePlaybackThread->dump(fd); 338 } 339 340 if (mAudioPolicyManager) { 341 mAudioPolicyManager->dump(fd); 342 } 343 344 if (locked) mLock.unlock(); 345 } 346 return NO_ERROR; 347} 348 349status_t AudioPolicyService::dumpPermissionDenial(int fd) 350{ 351 const size_t SIZE = 256; 352 char buffer[SIZE]; 353 String8 result; 354 snprintf(buffer, SIZE, "Permission Denial: " 355 "can't dump AudioPolicyService from pid=%d, uid=%d\n", 356 IPCThreadState::self()->getCallingPid(), 357 IPCThreadState::self()->getCallingUid()); 358 result.append(buffer); 359 write(fd, result.string(), result.size()); 360 return NO_ERROR; 361} 362 363status_t AudioPolicyService::onTransact( 364 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 365{ 366 return BnAudioPolicyService::onTransact(code, data, reply, flags); 367} 368 369 370// ----------- AudioPolicyService::AudioCommandThread implementation ---------- 371 372AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name, 373 const wp<AudioPolicyService>& service) 374 : Thread(false), mName(name), mService(service) 375{ 376 mpToneGenerator = NULL; 377} 378 379 380AudioPolicyService::AudioCommandThread::~AudioCommandThread() 381{ 382 if (!mAudioCommands.isEmpty()) { 383 release_wake_lock(mName.string()); 384 } 385 mAudioCommands.clear(); 386 delete mpToneGenerator; 387} 388 389void AudioPolicyService::AudioCommandThread::onFirstRef() 390{ 391 run(mName.string(), ANDROID_PRIORITY_AUDIO); 392} 393 394bool AudioPolicyService::AudioCommandThread::threadLoop() 395{ 396 nsecs_t waitTime = -1; 397 398 mLock.lock(); 399 while (!exitPending()) 400 { 401 sp<AudioPolicyService> svc; 402 while (!mAudioCommands.isEmpty() && !exitPending()) { 403 nsecs_t curTime = systemTime(); 404 // commands are sorted by increasing time stamp: execute them from index 0 and up 405 if (mAudioCommands[0]->mTime <= curTime) { 406 sp<AudioCommand> command = mAudioCommands[0]; 407 mAudioCommands.removeAt(0); 408 mLastCommand = command; 409 410 switch (command->mCommand) { 411 case START_TONE: { 412 mLock.unlock(); 413 ToneData *data = (ToneData *)command->mParam.get(); 414 ALOGV("AudioCommandThread() processing start tone %d on stream %d", 415 data->mType, data->mStream); 416 delete mpToneGenerator; 417 mpToneGenerator = new ToneGenerator(data->mStream, 1.0); 418 mpToneGenerator->startTone(data->mType); 419 mLock.lock(); 420 }break; 421 case STOP_TONE: { 422 mLock.unlock(); 423 ALOGV("AudioCommandThread() processing stop tone"); 424 if (mpToneGenerator != NULL) { 425 mpToneGenerator->stopTone(); 426 delete mpToneGenerator; 427 mpToneGenerator = NULL; 428 } 429 mLock.lock(); 430 }break; 431 case SET_VOLUME: { 432 VolumeData *data = (VolumeData *)command->mParam.get(); 433 ALOGV("AudioCommandThread() processing set volume stream %d, \ 434 volume %f, output %d", data->mStream, data->mVolume, data->mIO); 435 command->mStatus = AudioSystem::setStreamVolume(data->mStream, 436 data->mVolume, 437 data->mIO); 438 }break; 439 case SET_PARAMETERS: { 440 ParametersData *data = (ParametersData *)command->mParam.get(); 441 ALOGV("AudioCommandThread() processing set parameters string %s, io %d", 442 data->mKeyValuePairs.string(), data->mIO); 443 command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); 444 }break; 445 case SET_VOICE_VOLUME: { 446 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 447 ALOGV("AudioCommandThread() processing set voice volume volume %f", 448 data->mVolume); 449 command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); 450 }break; 451 case STOP_OUTPUT: { 452 StopOutputData *data = (StopOutputData *)command->mParam.get(); 453 ALOGV("AudioCommandThread() processing stop output %d", 454 data->mIO); 455 svc = mService.promote(); 456 if (svc == 0) { 457 break; 458 } 459 mLock.unlock(); 460 svc->doStopOutput(data->mIO, data->mStream, data->mSession); 461 mLock.lock(); 462 }break; 463 case RELEASE_OUTPUT: { 464 ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get(); 465 ALOGV("AudioCommandThread() processing release output %d", 466 data->mIO); 467 svc = mService.promote(); 468 if (svc == 0) { 469 break; 470 } 471 mLock.unlock(); 472 svc->doReleaseOutput(data->mIO, data->mStream, data->mSession); 473 mLock.lock(); 474 }break; 475 case CREATE_AUDIO_PATCH: { 476 CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get(); 477 ALOGV("AudioCommandThread() processing create audio patch"); 478 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 479 if (af == 0) { 480 command->mStatus = PERMISSION_DENIED; 481 } else { 482 command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle); 483 } 484 } break; 485 case RELEASE_AUDIO_PATCH: { 486 ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get(); 487 ALOGV("AudioCommandThread() processing release audio patch"); 488 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 489 if (af == 0) { 490 command->mStatus = PERMISSION_DENIED; 491 } else { 492 command->mStatus = af->releaseAudioPatch(data->mHandle); 493 } 494 } break; 495 case UPDATE_AUDIOPORT_LIST: { 496 ALOGV("AudioCommandThread() processing update audio port list"); 497 svc = mService.promote(); 498 if (svc == 0) { 499 break; 500 } 501 mLock.unlock(); 502 svc->doOnAudioPortListUpdate(); 503 mLock.lock(); 504 }break; 505 case UPDATE_AUDIOPATCH_LIST: { 506 ALOGV("AudioCommandThread() processing update audio patch list"); 507 svc = mService.promote(); 508 if (svc == 0) { 509 break; 510 } 511 mLock.unlock(); 512 svc->doOnAudioPatchListUpdate(); 513 mLock.lock(); 514 }break; 515 case SET_AUDIOPORT_CONFIG: { 516 SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get(); 517 ALOGV("AudioCommandThread() processing set port config"); 518 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 519 if (af == 0) { 520 command->mStatus = PERMISSION_DENIED; 521 } else { 522 command->mStatus = af->setAudioPortConfig(&data->mConfig); 523 } 524 } break; 525 case DYN_POLICY_MIX_STATE_UPDATE: { 526 DynPolicyMixStateUpdateData *data = 527 (DynPolicyMixStateUpdateData *)command->mParam.get(); 528 ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d", 529 data->mRegId.string(), data->mState); 530 svc = mService.promote(); 531 if (svc == 0) { 532 break; 533 } 534 mLock.unlock(); 535 svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState); 536 mLock.lock(); 537 } break; 538 case RECORDING_CONFIGURATION_UPDATE: { 539 RecordingConfigurationUpdateData *data = 540 (RecordingConfigurationUpdateData *)command->mParam.get(); 541 ALOGV("AudioCommandThread() processing recording configuration update"); 542 svc = mService.promote(); 543 if (svc == 0) { 544 break; 545 } 546 mLock.unlock(); 547 svc->doOnRecordingConfigurationUpdate(data->mEvent, data->mSession, 548 data->mSource, &data->mClientConfig, &data->mDeviceConfig, 549 data->mPatchHandle); 550 mLock.lock(); 551 } break; 552 default: 553 ALOGW("AudioCommandThread() unknown command %d", command->mCommand); 554 } 555 { 556 Mutex::Autolock _l(command->mLock); 557 if (command->mWaitStatus) { 558 command->mWaitStatus = false; 559 command->mCond.signal(); 560 } 561 } 562 waitTime = -1; 563 // release mLock before releasing strong reference on the service as 564 // AudioPolicyService destructor calls AudioCommandThread::exit() which 565 // acquires mLock. 566 mLock.unlock(); 567 svc.clear(); 568 mLock.lock(); 569 } else { 570 waitTime = mAudioCommands[0]->mTime - curTime; 571 break; 572 } 573 } 574 575 // release delayed commands wake lock if the queue is empty 576 if (mAudioCommands.isEmpty()) { 577 release_wake_lock(mName.string()); 578 } 579 580 // At this stage we have either an empty command queue or the first command in the queue 581 // has a finite delay. So unless we are exiting it is safe to wait. 582 if (!exitPending()) { 583 ALOGV("AudioCommandThread() going to sleep"); 584 if (waitTime == -1) { 585 mWaitWorkCV.wait(mLock); 586 } else { 587 mWaitWorkCV.waitRelative(mLock, waitTime); 588 } 589 } 590 } 591 // release delayed commands wake lock before quitting 592 if (!mAudioCommands.isEmpty()) { 593 release_wake_lock(mName.string()); 594 } 595 mLock.unlock(); 596 return false; 597} 598 599status_t AudioPolicyService::AudioCommandThread::dump(int fd) 600{ 601 const size_t SIZE = 256; 602 char buffer[SIZE]; 603 String8 result; 604 605 snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 606 result.append(buffer); 607 write(fd, result.string(), result.size()); 608 609 bool locked = tryLock(mLock); 610 if (!locked) { 611 String8 result2(kCmdDeadlockedString); 612 write(fd, result2.string(), result2.size()); 613 } 614 615 snprintf(buffer, SIZE, "- Commands:\n"); 616 result = String8(buffer); 617 result.append(" Command Time Wait pParam\n"); 618 for (size_t i = 0; i < mAudioCommands.size(); i++) { 619 mAudioCommands[i]->dump(buffer, SIZE); 620 result.append(buffer); 621 } 622 result.append(" Last Command\n"); 623 if (mLastCommand != 0) { 624 mLastCommand->dump(buffer, SIZE); 625 result.append(buffer); 626 } else { 627 result.append(" none\n"); 628 } 629 630 write(fd, result.string(), result.size()); 631 632 if (locked) mLock.unlock(); 633 634 return NO_ERROR; 635} 636 637void AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type, 638 audio_stream_type_t stream) 639{ 640 sp<AudioCommand> command = new AudioCommand(); 641 command->mCommand = START_TONE; 642 sp<ToneData> data = new ToneData(); 643 data->mType = type; 644 data->mStream = stream; 645 command->mParam = data; 646 ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 647 sendCommand(command); 648} 649 650void AudioPolicyService::AudioCommandThread::stopToneCommand() 651{ 652 sp<AudioCommand> command = new AudioCommand(); 653 command->mCommand = STOP_TONE; 654 ALOGV("AudioCommandThread() adding tone stop"); 655 sendCommand(command); 656} 657 658status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream, 659 float volume, 660 audio_io_handle_t output, 661 int delayMs) 662{ 663 sp<AudioCommand> command = new AudioCommand(); 664 command->mCommand = SET_VOLUME; 665 sp<VolumeData> data = new VolumeData(); 666 data->mStream = stream; 667 data->mVolume = volume; 668 data->mIO = output; 669 command->mParam = data; 670 command->mWaitStatus = true; 671 ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 672 stream, volume, output); 673 return sendCommand(command, delayMs); 674} 675 676status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle, 677 const char *keyValuePairs, 678 int delayMs) 679{ 680 sp<AudioCommand> command = new AudioCommand(); 681 command->mCommand = SET_PARAMETERS; 682 sp<ParametersData> data = new ParametersData(); 683 data->mIO = ioHandle; 684 data->mKeyValuePairs = String8(keyValuePairs); 685 command->mParam = data; 686 command->mWaitStatus = true; 687 ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 688 keyValuePairs, ioHandle, delayMs); 689 return sendCommand(command, delayMs); 690} 691 692status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 693{ 694 sp<AudioCommand> command = new AudioCommand(); 695 command->mCommand = SET_VOICE_VOLUME; 696 sp<VoiceVolumeData> data = new VoiceVolumeData(); 697 data->mVolume = volume; 698 command->mParam = data; 699 command->mWaitStatus = true; 700 ALOGV("AudioCommandThread() adding set voice volume volume %f", volume); 701 return sendCommand(command, delayMs); 702} 703 704void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output, 705 audio_stream_type_t stream, 706 audio_session_t session) 707{ 708 sp<AudioCommand> command = new AudioCommand(); 709 command->mCommand = STOP_OUTPUT; 710 sp<StopOutputData> data = new StopOutputData(); 711 data->mIO = output; 712 data->mStream = stream; 713 data->mSession = session; 714 command->mParam = data; 715 ALOGV("AudioCommandThread() adding stop output %d", output); 716 sendCommand(command); 717} 718 719void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output, 720 audio_stream_type_t stream, 721 audio_session_t session) 722{ 723 sp<AudioCommand> command = new AudioCommand(); 724 command->mCommand = RELEASE_OUTPUT; 725 sp<ReleaseOutputData> data = new ReleaseOutputData(); 726 data->mIO = output; 727 data->mStream = stream; 728 data->mSession = session; 729 command->mParam = data; 730 ALOGV("AudioCommandThread() adding release output %d", output); 731 sendCommand(command); 732} 733 734status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand( 735 const struct audio_patch *patch, 736 audio_patch_handle_t *handle, 737 int delayMs) 738{ 739 status_t status = NO_ERROR; 740 741 sp<AudioCommand> command = new AudioCommand(); 742 command->mCommand = CREATE_AUDIO_PATCH; 743 CreateAudioPatchData *data = new CreateAudioPatchData(); 744 data->mPatch = *patch; 745 data->mHandle = *handle; 746 command->mParam = data; 747 command->mWaitStatus = true; 748 ALOGV("AudioCommandThread() adding create patch delay %d", delayMs); 749 status = sendCommand(command, delayMs); 750 if (status == NO_ERROR) { 751 *handle = data->mHandle; 752 } 753 return status; 754} 755 756status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle, 757 int delayMs) 758{ 759 sp<AudioCommand> command = new AudioCommand(); 760 command->mCommand = RELEASE_AUDIO_PATCH; 761 ReleaseAudioPatchData *data = new ReleaseAudioPatchData(); 762 data->mHandle = handle; 763 command->mParam = data; 764 command->mWaitStatus = true; 765 ALOGV("AudioCommandThread() adding release patch delay %d", delayMs); 766 return sendCommand(command, delayMs); 767} 768 769void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand() 770{ 771 sp<AudioCommand> command = new AudioCommand(); 772 command->mCommand = UPDATE_AUDIOPORT_LIST; 773 ALOGV("AudioCommandThread() adding update audio port list"); 774 sendCommand(command); 775} 776 777void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand() 778{ 779 sp<AudioCommand>command = new AudioCommand(); 780 command->mCommand = UPDATE_AUDIOPATCH_LIST; 781 ALOGV("AudioCommandThread() adding update audio patch list"); 782 sendCommand(command); 783} 784 785status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand( 786 const struct audio_port_config *config, int delayMs) 787{ 788 sp<AudioCommand> command = new AudioCommand(); 789 command->mCommand = SET_AUDIOPORT_CONFIG; 790 SetAudioPortConfigData *data = new SetAudioPortConfigData(); 791 data->mConfig = *config; 792 command->mParam = data; 793 command->mWaitStatus = true; 794 ALOGV("AudioCommandThread() adding set port config delay %d", delayMs); 795 return sendCommand(command, delayMs); 796} 797 798void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( 799 const String8& regId, int32_t state) 800{ 801 sp<AudioCommand> command = new AudioCommand(); 802 command->mCommand = DYN_POLICY_MIX_STATE_UPDATE; 803 DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData(); 804 data->mRegId = regId; 805 data->mState = state; 806 command->mParam = data; 807 ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d", 808 regId.string(), state); 809 sendCommand(command); 810} 811 812void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand( 813 int event, audio_session_t session, audio_source_t source, 814 const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, 815 audio_patch_handle_t patchHandle) 816{ 817 sp<AudioCommand>command = new AudioCommand(); 818 command->mCommand = RECORDING_CONFIGURATION_UPDATE; 819 RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData(); 820 data->mEvent = event; 821 data->mSession = session; 822 data->mSource = source; 823 data->mClientConfig = *clientConfig; 824 data->mDeviceConfig = *deviceConfig; 825 data->mPatchHandle = patchHandle; 826 command->mParam = data; 827 ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d", 828 event, source); 829 sendCommand(command); 830} 831 832status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) 833{ 834 { 835 Mutex::Autolock _l(mLock); 836 insertCommand_l(command, delayMs); 837 mWaitWorkCV.signal(); 838 } 839 Mutex::Autolock _l(command->mLock); 840 while (command->mWaitStatus) { 841 nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs); 842 if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) { 843 command->mStatus = TIMED_OUT; 844 command->mWaitStatus = false; 845 } 846 } 847 return command->mStatus; 848} 849 850// insertCommand_l() must be called with mLock held 851void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs) 852{ 853 ssize_t i; // not size_t because i will count down to -1 854 Vector < sp<AudioCommand> > removedCommands; 855 command->mTime = systemTime() + milliseconds(delayMs); 856 857 // acquire wake lock to make sure delayed commands are processed 858 if (mAudioCommands.isEmpty()) { 859 acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 860 } 861 862 // check same pending commands with later time stamps and eliminate them 863 for (i = mAudioCommands.size()-1; i >= 0; i--) { 864 sp<AudioCommand> command2 = mAudioCommands[i]; 865 // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 866 if (command2->mTime <= command->mTime) break; 867 868 // create audio patch or release audio patch commands are equivalent 869 // with regard to filtering 870 if ((command->mCommand == CREATE_AUDIO_PATCH) || 871 (command->mCommand == RELEASE_AUDIO_PATCH)) { 872 if ((command2->mCommand != CREATE_AUDIO_PATCH) && 873 (command2->mCommand != RELEASE_AUDIO_PATCH)) { 874 continue; 875 } 876 } else if (command2->mCommand != command->mCommand) continue; 877 878 switch (command->mCommand) { 879 case SET_PARAMETERS: { 880 ParametersData *data = (ParametersData *)command->mParam.get(); 881 ParametersData *data2 = (ParametersData *)command2->mParam.get(); 882 if (data->mIO != data2->mIO) break; 883 ALOGV("Comparing parameter command %s to new command %s", 884 data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 885 AudioParameter param = AudioParameter(data->mKeyValuePairs); 886 AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 887 for (size_t j = 0; j < param.size(); j++) { 888 String8 key; 889 String8 value; 890 param.getAt(j, key, value); 891 for (size_t k = 0; k < param2.size(); k++) { 892 String8 key2; 893 String8 value2; 894 param2.getAt(k, key2, value2); 895 if (key2 == key) { 896 param2.remove(key2); 897 ALOGV("Filtering out parameter %s", key2.string()); 898 break; 899 } 900 } 901 } 902 // if all keys have been filtered out, remove the command. 903 // otherwise, update the key value pairs 904 if (param2.size() == 0) { 905 removedCommands.add(command2); 906 } else { 907 data2->mKeyValuePairs = param2.toString(); 908 } 909 command->mTime = command2->mTime; 910 // force delayMs to non 0 so that code below does not request to wait for 911 // command status as the command is now delayed 912 delayMs = 1; 913 } break; 914 915 case SET_VOLUME: { 916 VolumeData *data = (VolumeData *)command->mParam.get(); 917 VolumeData *data2 = (VolumeData *)command2->mParam.get(); 918 if (data->mIO != data2->mIO) break; 919 if (data->mStream != data2->mStream) break; 920 ALOGV("Filtering out volume command on output %d for stream %d", 921 data->mIO, data->mStream); 922 removedCommands.add(command2); 923 command->mTime = command2->mTime; 924 // force delayMs to non 0 so that code below does not request to wait for 925 // command status as the command is now delayed 926 delayMs = 1; 927 } break; 928 929 case SET_VOICE_VOLUME: { 930 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 931 VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get(); 932 ALOGV("Filtering out voice volume command value %f replaced by %f", 933 data2->mVolume, data->mVolume); 934 removedCommands.add(command2); 935 command->mTime = command2->mTime; 936 // force delayMs to non 0 so that code below does not request to wait for 937 // command status as the command is now delayed 938 delayMs = 1; 939 } break; 940 941 case CREATE_AUDIO_PATCH: 942 case RELEASE_AUDIO_PATCH: { 943 audio_patch_handle_t handle; 944 struct audio_patch patch; 945 if (command->mCommand == CREATE_AUDIO_PATCH) { 946 handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle; 947 patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch; 948 } else { 949 handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle; 950 } 951 audio_patch_handle_t handle2; 952 struct audio_patch patch2; 953 if (command2->mCommand == CREATE_AUDIO_PATCH) { 954 handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle; 955 patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch; 956 } else { 957 handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle; 958 memset(&patch2, 0, sizeof(patch2)); 959 } 960 if (handle != handle2) break; 961 /* Filter CREATE_AUDIO_PATCH commands only when they are issued for 962 same output. */ 963 if( (command->mCommand == CREATE_AUDIO_PATCH) && 964 (command2->mCommand == CREATE_AUDIO_PATCH) ) { 965 bool isOutputDiff = false; 966 if (patch.num_sources == patch2.num_sources) { 967 for (unsigned count = 0; count < patch.num_sources; count++) { 968 if (patch.sources[count].id != patch2.sources[count].id) { 969 isOutputDiff = true; 970 break; 971 } 972 } 973 if (isOutputDiff) 974 break; 975 } 976 } 977 ALOGV("Filtering out %s audio patch command for handle %d", 978 (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle); 979 removedCommands.add(command2); 980 command->mTime = command2->mTime; 981 // force delayMs to non 0 so that code below does not request to wait for 982 // command status as the command is now delayed 983 delayMs = 1; 984 } break; 985 986 case DYN_POLICY_MIX_STATE_UPDATE: { 987 988 } break; 989 990 case RECORDING_CONFIGURATION_UPDATE: { 991 992 } break; 993 994 case START_TONE: 995 case STOP_TONE: 996 default: 997 break; 998 } 999 } 1000 1001 // remove filtered commands 1002 for (size_t j = 0; j < removedCommands.size(); j++) { 1003 // removed commands always have time stamps greater than current command 1004 for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 1005 if (mAudioCommands[k].get() == removedCommands[j].get()) { 1006 ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 1007 mAudioCommands.removeAt(k); 1008 break; 1009 } 1010 } 1011 } 1012 removedCommands.clear(); 1013 1014 // Disable wait for status if delay is not 0. 1015 // Except for create audio patch command because the returned patch handle 1016 // is needed by audio policy manager 1017 if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) { 1018 command->mWaitStatus = false; 1019 } 1020 1021 // insert command at the right place according to its time stamp 1022 ALOGV("inserting command: %d at index %zd, num commands %zu", 1023 command->mCommand, i+1, mAudioCommands.size()); 1024 mAudioCommands.insertAt(command, i + 1); 1025} 1026 1027void AudioPolicyService::AudioCommandThread::exit() 1028{ 1029 ALOGV("AudioCommandThread::exit"); 1030 { 1031 AutoMutex _l(mLock); 1032 requestExit(); 1033 mWaitWorkCV.signal(); 1034 } 1035 // Note that we can call it from the thread loop if all other references have been released 1036 // but it will safely return WOULD_BLOCK in this case 1037 requestExitAndWait(); 1038} 1039 1040void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 1041{ 1042 snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 1043 mCommand, 1044 (int)ns2s(mTime), 1045 (int)ns2ms(mTime)%1000, 1046 mWaitStatus, 1047 mParam.get()); 1048} 1049 1050/******* helpers for the service_ops callbacks defined below *********/ 1051void AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 1052 const char *keyValuePairs, 1053 int delayMs) 1054{ 1055 mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs, 1056 delayMs); 1057} 1058 1059int AudioPolicyService::setStreamVolume(audio_stream_type_t stream, 1060 float volume, 1061 audio_io_handle_t output, 1062 int delayMs) 1063{ 1064 return (int)mAudioCommandThread->volumeCommand(stream, volume, 1065 output, delayMs); 1066} 1067 1068int AudioPolicyService::startTone(audio_policy_tone_t tone, 1069 audio_stream_type_t stream) 1070{ 1071 if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) { 1072 ALOGE("startTone: illegal tone requested (%d)", tone); 1073 } 1074 if (stream != AUDIO_STREAM_VOICE_CALL) { 1075 ALOGE("startTone: illegal stream (%d) requested for tone %d", stream, 1076 tone); 1077 } 1078 mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING, 1079 AUDIO_STREAM_VOICE_CALL); 1080 return 0; 1081} 1082 1083int AudioPolicyService::stopTone() 1084{ 1085 mTonePlaybackThread->stopToneCommand(); 1086 return 0; 1087} 1088 1089int AudioPolicyService::setVoiceVolume(float volume, int delayMs) 1090{ 1091 return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 1092} 1093 1094extern "C" { 1095audio_module_handle_t aps_load_hw_module(void *service __unused, 1096 const char *name); 1097audio_io_handle_t aps_open_output(void *service __unused, 1098 audio_devices_t *pDevices, 1099 uint32_t *pSamplingRate, 1100 audio_format_t *pFormat, 1101 audio_channel_mask_t *pChannelMask, 1102 uint32_t *pLatencyMs, 1103 audio_output_flags_t flags); 1104 1105audio_io_handle_t aps_open_output_on_module(void *service __unused, 1106 audio_module_handle_t module, 1107 audio_devices_t *pDevices, 1108 uint32_t *pSamplingRate, 1109 audio_format_t *pFormat, 1110 audio_channel_mask_t *pChannelMask, 1111 uint32_t *pLatencyMs, 1112 audio_output_flags_t flags, 1113 const audio_offload_info_t *offloadInfo); 1114audio_io_handle_t aps_open_dup_output(void *service __unused, 1115 audio_io_handle_t output1, 1116 audio_io_handle_t output2); 1117int aps_close_output(void *service __unused, audio_io_handle_t output); 1118int aps_suspend_output(void *service __unused, audio_io_handle_t output); 1119int aps_restore_output(void *service __unused, audio_io_handle_t output); 1120audio_io_handle_t aps_open_input(void *service __unused, 1121 audio_devices_t *pDevices, 1122 uint32_t *pSamplingRate, 1123 audio_format_t *pFormat, 1124 audio_channel_mask_t *pChannelMask, 1125 audio_in_acoustics_t acoustics __unused); 1126audio_io_handle_t aps_open_input_on_module(void *service __unused, 1127 audio_module_handle_t module, 1128 audio_devices_t *pDevices, 1129 uint32_t *pSamplingRate, 1130 audio_format_t *pFormat, 1131 audio_channel_mask_t *pChannelMask); 1132int aps_close_input(void *service __unused, audio_io_handle_t input); 1133int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream); 1134int aps_move_effects(void *service __unused, audio_session_t session, 1135 audio_io_handle_t src_output, 1136 audio_io_handle_t dst_output); 1137char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle, 1138 const char *keys); 1139void aps_set_parameters(void *service, audio_io_handle_t io_handle, 1140 const char *kv_pairs, int delay_ms); 1141int aps_set_stream_volume(void *service, audio_stream_type_t stream, 1142 float volume, audio_io_handle_t output, 1143 int delay_ms); 1144int aps_start_tone(void *service, audio_policy_tone_t tone, 1145 audio_stream_type_t stream); 1146int aps_stop_tone(void *service); 1147int aps_set_voice_volume(void *service, float volume, int delay_ms); 1148}; 1149 1150}; // namespace android 1151