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 42 namespace android { 43 44 static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n"; 45 static const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n"; 46 47 static const int kDumpLockRetries = 50; 48 static const int kDumpLockSleepUs = 20000; 49 50 static const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds 51 52 53 // ---------------------------------------------------------------------------- 54 55 AudioPolicyService::AudioPolicyService() 56 : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL), 57 mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID) 58 { 59 } 60 61 void 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 84 AudioPolicyService::~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. 99 void 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 121 void 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. 133 void 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 147 void AudioPolicyService::onAudioPortListUpdate() 148 { 149 mOutputCommandThread->updateAudioPortListCommand(); 150 } 151 152 void 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 160 void AudioPolicyService::onAudioPatchListUpdate() 161 { 162 mOutputCommandThread->updateAudioPatchListCommand(); 163 } 164 165 void 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 173 void 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 180 void 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 188 void AudioPolicyService::onRecordingConfigurationUpdate(int event, 189 const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig, 190 const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) 191 { 192 mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo, 193 clientConfig, deviceConfig, patchHandle); 194 } 195 196 void AudioPolicyService::doOnRecordingConfigurationUpdate(int event, 197 const record_client_info_t *clientInfo, 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, clientInfo, 203 clientConfig, deviceConfig, patchHandle); 204 } 205 } 206 207 status_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 214 status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle, 215 int delayMs) 216 { 217 return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs); 218 } 219 220 status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config, 221 int delayMs) 222 { 223 return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); 224 } 225 226 AudioPolicyService::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 234 AudioPolicyService::NotificationClient::~NotificationClient() 235 { 236 } 237 238 void 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 247 void AudioPolicyService::NotificationClient::onAudioPortListUpdate() 248 { 249 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 250 mAudioPolicyServiceClient->onAudioPortListUpdate(); 251 } 252 } 253 254 void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() 255 { 256 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 257 mAudioPolicyServiceClient->onAudioPatchListUpdate(); 258 } 259 } 260 261 void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( 262 const String8& regId, int32_t state) 263 { 264 if (mAudioPolicyServiceClient != 0) { 265 mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state); 266 } 267 } 268 269 void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate( 270 int event, const record_client_info_t *clientInfo, 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, clientInfo, 276 clientConfig, deviceConfig, patchHandle); 277 } 278 } 279 280 void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled) 281 { 282 mAudioPortCallbacksEnabled = enabled; 283 } 284 285 286 void AudioPolicyService::binderDied(const wp<IBinder>& who) { 287 ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), 288 IPCThreadState::self()->getCallingPid()); 289 } 290 291 static 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 304 status_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 321 status_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 349 status_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 363 status_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 372 AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name, 373 const wp<AudioPolicyService>& service) 374 : Thread(false), mName(name), mService(service) 375 { 376 mpToneGenerator = NULL; 377 } 378 379 380 AudioPolicyService::AudioCommandThread::~AudioCommandThread() 381 { 382 if (!mAudioCommands.isEmpty()) { 383 release_wake_lock(mName.string()); 384 } 385 mAudioCommands.clear(); 386 delete mpToneGenerator; 387 } 388 389 void AudioPolicyService::AudioCommandThread::onFirstRef() 390 { 391 run(mName.string(), ANDROID_PRIORITY_AUDIO); 392 } 393 394 bool 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->mClientInfo, 548 &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 599 status_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 637 void 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 650 void 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 658 status_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 676 status_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 692 status_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 704 void 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 719 void 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 734 status_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 756 status_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 769 void 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 777 void 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 785 status_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 798 void 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 812 void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand( 813 int event, const record_client_info_t *clientInfo, 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->mClientInfo = *clientInfo; 822 data->mClientConfig = *clientConfig; 823 data->mDeviceConfig = *deviceConfig; 824 data->mPatchHandle = patchHandle; 825 command->mParam = data; 826 ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u", 827 event, clientInfo->source, clientInfo->uid); 828 sendCommand(command); 829 } 830 831 status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) 832 { 833 { 834 Mutex::Autolock _l(mLock); 835 insertCommand_l(command, delayMs); 836 mWaitWorkCV.signal(); 837 } 838 Mutex::Autolock _l(command->mLock); 839 while (command->mWaitStatus) { 840 nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs); 841 if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) { 842 command->mStatus = TIMED_OUT; 843 command->mWaitStatus = false; 844 } 845 } 846 return command->mStatus; 847 } 848 849 // insertCommand_l() must be called with mLock held 850 void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs) 851 { 852 ssize_t i; // not size_t because i will count down to -1 853 Vector < sp<AudioCommand> > removedCommands; 854 command->mTime = systemTime() + milliseconds(delayMs); 855 856 // acquire wake lock to make sure delayed commands are processed 857 if (mAudioCommands.isEmpty()) { 858 acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 859 } 860 861 // check same pending commands with later time stamps and eliminate them 862 for (i = mAudioCommands.size()-1; i >= 0; i--) { 863 sp<AudioCommand> command2 = mAudioCommands[i]; 864 // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 865 if (command2->mTime <= command->mTime) break; 866 867 // create audio patch or release audio patch commands are equivalent 868 // with regard to filtering 869 if ((command->mCommand == CREATE_AUDIO_PATCH) || 870 (command->mCommand == RELEASE_AUDIO_PATCH)) { 871 if ((command2->mCommand != CREATE_AUDIO_PATCH) && 872 (command2->mCommand != RELEASE_AUDIO_PATCH)) { 873 continue; 874 } 875 } else if (command2->mCommand != command->mCommand) continue; 876 877 switch (command->mCommand) { 878 case SET_PARAMETERS: { 879 ParametersData *data = (ParametersData *)command->mParam.get(); 880 ParametersData *data2 = (ParametersData *)command2->mParam.get(); 881 if (data->mIO != data2->mIO) break; 882 ALOGV("Comparing parameter command %s to new command %s", 883 data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 884 AudioParameter param = AudioParameter(data->mKeyValuePairs); 885 AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 886 for (size_t j = 0; j < param.size(); j++) { 887 String8 key; 888 String8 value; 889 param.getAt(j, key, value); 890 for (size_t k = 0; k < param2.size(); k++) { 891 String8 key2; 892 String8 value2; 893 param2.getAt(k, key2, value2); 894 if (key2 == key) { 895 param2.remove(key2); 896 ALOGV("Filtering out parameter %s", key2.string()); 897 break; 898 } 899 } 900 } 901 // if all keys have been filtered out, remove the command. 902 // otherwise, update the key value pairs 903 if (param2.size() == 0) { 904 removedCommands.add(command2); 905 } else { 906 data2->mKeyValuePairs = param2.toString(); 907 } 908 command->mTime = command2->mTime; 909 // force delayMs to non 0 so that code below does not request to wait for 910 // command status as the command is now delayed 911 delayMs = 1; 912 } break; 913 914 case SET_VOLUME: { 915 VolumeData *data = (VolumeData *)command->mParam.get(); 916 VolumeData *data2 = (VolumeData *)command2->mParam.get(); 917 if (data->mIO != data2->mIO) break; 918 if (data->mStream != data2->mStream) break; 919 ALOGV("Filtering out volume command on output %d for stream %d", 920 data->mIO, data->mStream); 921 removedCommands.add(command2); 922 command->mTime = command2->mTime; 923 // force delayMs to non 0 so that code below does not request to wait for 924 // command status as the command is now delayed 925 delayMs = 1; 926 } break; 927 928 case SET_VOICE_VOLUME: { 929 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 930 VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get(); 931 ALOGV("Filtering out voice volume command value %f replaced by %f", 932 data2->mVolume, data->mVolume); 933 removedCommands.add(command2); 934 command->mTime = command2->mTime; 935 // force delayMs to non 0 so that code below does not request to wait for 936 // command status as the command is now delayed 937 delayMs = 1; 938 } break; 939 940 case CREATE_AUDIO_PATCH: 941 case RELEASE_AUDIO_PATCH: { 942 audio_patch_handle_t handle; 943 struct audio_patch patch; 944 if (command->mCommand == CREATE_AUDIO_PATCH) { 945 handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle; 946 patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch; 947 } else { 948 handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle; 949 } 950 audio_patch_handle_t handle2; 951 struct audio_patch patch2; 952 if (command2->mCommand == CREATE_AUDIO_PATCH) { 953 handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle; 954 patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch; 955 } else { 956 handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle; 957 memset(&patch2, 0, sizeof(patch2)); 958 } 959 if (handle != handle2) break; 960 /* Filter CREATE_AUDIO_PATCH commands only when they are issued for 961 same output. */ 962 if( (command->mCommand == CREATE_AUDIO_PATCH) && 963 (command2->mCommand == CREATE_AUDIO_PATCH) ) { 964 bool isOutputDiff = false; 965 if (patch.num_sources == patch2.num_sources) { 966 for (unsigned count = 0; count < patch.num_sources; count++) { 967 if (patch.sources[count].id != patch2.sources[count].id) { 968 isOutputDiff = true; 969 break; 970 } 971 } 972 if (isOutputDiff) 973 break; 974 } 975 } 976 ALOGV("Filtering out %s audio patch command for handle %d", 977 (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle); 978 removedCommands.add(command2); 979 command->mTime = command2->mTime; 980 // force delayMs to non 0 so that code below does not request to wait for 981 // command status as the command is now delayed 982 delayMs = 1; 983 } break; 984 985 case DYN_POLICY_MIX_STATE_UPDATE: { 986 987 } break; 988 989 case RECORDING_CONFIGURATION_UPDATE: { 990 991 } break; 992 993 case START_TONE: 994 case STOP_TONE: 995 default: 996 break; 997 } 998 } 999 1000 // remove filtered commands 1001 for (size_t j = 0; j < removedCommands.size(); j++) { 1002 // removed commands always have time stamps greater than current command 1003 for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 1004 if (mAudioCommands[k].get() == removedCommands[j].get()) { 1005 ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 1006 mAudioCommands.removeAt(k); 1007 break; 1008 } 1009 } 1010 } 1011 removedCommands.clear(); 1012 1013 // Disable wait for status if delay is not 0. 1014 // Except for create audio patch command because the returned patch handle 1015 // is needed by audio policy manager 1016 if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) { 1017 command->mWaitStatus = false; 1018 } 1019 1020 // insert command at the right place according to its time stamp 1021 ALOGV("inserting command: %d at index %zd, num commands %zu", 1022 command->mCommand, i+1, mAudioCommands.size()); 1023 mAudioCommands.insertAt(command, i + 1); 1024 } 1025 1026 void AudioPolicyService::AudioCommandThread::exit() 1027 { 1028 ALOGV("AudioCommandThread::exit"); 1029 { 1030 AutoMutex _l(mLock); 1031 requestExit(); 1032 mWaitWorkCV.signal(); 1033 } 1034 // Note that we can call it from the thread loop if all other references have been released 1035 // but it will safely return WOULD_BLOCK in this case 1036 requestExitAndWait(); 1037 } 1038 1039 void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 1040 { 1041 snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 1042 mCommand, 1043 (int)ns2s(mTime), 1044 (int)ns2ms(mTime)%1000, 1045 mWaitStatus, 1046 mParam.get()); 1047 } 1048 1049 /******* helpers for the service_ops callbacks defined below *********/ 1050 void AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 1051 const char *keyValuePairs, 1052 int delayMs) 1053 { 1054 mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs, 1055 delayMs); 1056 } 1057 1058 int AudioPolicyService::setStreamVolume(audio_stream_type_t stream, 1059 float volume, 1060 audio_io_handle_t output, 1061 int delayMs) 1062 { 1063 return (int)mAudioCommandThread->volumeCommand(stream, volume, 1064 output, delayMs); 1065 } 1066 1067 int AudioPolicyService::startTone(audio_policy_tone_t tone, 1068 audio_stream_type_t stream) 1069 { 1070 if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) { 1071 ALOGE("startTone: illegal tone requested (%d)", tone); 1072 } 1073 if (stream != AUDIO_STREAM_VOICE_CALL) { 1074 ALOGE("startTone: illegal stream (%d) requested for tone %d", stream, 1075 tone); 1076 } 1077 mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING, 1078 AUDIO_STREAM_VOICE_CALL); 1079 return 0; 1080 } 1081 1082 int AudioPolicyService::stopTone() 1083 { 1084 mTonePlaybackThread->stopToneCommand(); 1085 return 0; 1086 } 1087 1088 int AudioPolicyService::setVoiceVolume(float volume, int delayMs) 1089 { 1090 return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 1091 } 1092 1093 extern "C" { 1094 audio_module_handle_t aps_load_hw_module(void *service __unused, 1095 const char *name); 1096 audio_io_handle_t aps_open_output(void *service __unused, 1097 audio_devices_t *pDevices, 1098 uint32_t *pSamplingRate, 1099 audio_format_t *pFormat, 1100 audio_channel_mask_t *pChannelMask, 1101 uint32_t *pLatencyMs, 1102 audio_output_flags_t flags); 1103 1104 audio_io_handle_t aps_open_output_on_module(void *service __unused, 1105 audio_module_handle_t module, 1106 audio_devices_t *pDevices, 1107 uint32_t *pSamplingRate, 1108 audio_format_t *pFormat, 1109 audio_channel_mask_t *pChannelMask, 1110 uint32_t *pLatencyMs, 1111 audio_output_flags_t flags, 1112 const audio_offload_info_t *offloadInfo); 1113 audio_io_handle_t aps_open_dup_output(void *service __unused, 1114 audio_io_handle_t output1, 1115 audio_io_handle_t output2); 1116 int aps_close_output(void *service __unused, audio_io_handle_t output); 1117 int aps_suspend_output(void *service __unused, audio_io_handle_t output); 1118 int aps_restore_output(void *service __unused, audio_io_handle_t output); 1119 audio_io_handle_t aps_open_input(void *service __unused, 1120 audio_devices_t *pDevices, 1121 uint32_t *pSamplingRate, 1122 audio_format_t *pFormat, 1123 audio_channel_mask_t *pChannelMask, 1124 audio_in_acoustics_t acoustics __unused); 1125 audio_io_handle_t aps_open_input_on_module(void *service __unused, 1126 audio_module_handle_t module, 1127 audio_devices_t *pDevices, 1128 uint32_t *pSamplingRate, 1129 audio_format_t *pFormat, 1130 audio_channel_mask_t *pChannelMask); 1131 int aps_close_input(void *service __unused, audio_io_handle_t input); 1132 int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream); 1133 int aps_move_effects(void *service __unused, audio_session_t session, 1134 audio_io_handle_t src_output, 1135 audio_io_handle_t dst_output); 1136 char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle, 1137 const char *keys); 1138 void aps_set_parameters(void *service, audio_io_handle_t io_handle, 1139 const char *kv_pairs, int delay_ms); 1140 int aps_set_stream_volume(void *service, audio_stream_type_t stream, 1141 float volume, audio_io_handle_t output, 1142 int delay_ms); 1143 int aps_start_tone(void *service, audio_policy_tone_t tone, 1144 audio_stream_type_t stream); 1145 int aps_stop_tone(void *service); 1146 int aps_set_voice_volume(void *service, float volume, int delay_ms); 1147 }; 1148 1149 }; // namespace android 1150