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/multiuser.h> 30 #include <cutils/properties.h> 31 #include <binder/IPCThreadState.h> 32 #include <binder/ActivityManager.h> 33 #include <binder/PermissionController.h> 34 #include <binder/IResultReceiver.h> 35 #include <utils/String16.h> 36 #include <utils/threads.h> 37 #include "AudioPolicyService.h" 38 #include "ServiceUtilities.h" 39 #include <hardware_legacy/power.h> 40 #include <media/AudioEffect.h> 41 #include <media/AudioParameter.h> 42 43 #include <system/audio.h> 44 #include <system/audio_policy.h> 45 46 #include <private/android_filesystem_config.h> 47 48 namespace android { 49 50 static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n"; 51 static const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n"; 52 53 static const int kDumpLockRetries = 50; 54 static const int kDumpLockSleepUs = 20000; 55 56 static const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds 57 58 static const String16 sManageAudioPolicyPermission("android.permission.MANAGE_AUDIO_POLICY"); 59 60 // ---------------------------------------------------------------------------- 61 62 AudioPolicyService::AudioPolicyService() 63 : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL), 64 mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID) 65 { 66 } 67 68 void AudioPolicyService::onFirstRef() 69 { 70 { 71 Mutex::Autolock _l(mLock); 72 73 // start tone playback thread 74 mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this); 75 // start audio commands thread 76 mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this); 77 // start output activity command thread 78 mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this); 79 80 mAudioPolicyClient = new AudioPolicyClient(this); 81 mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); 82 } 83 // load audio processing modules 84 sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects(); 85 { 86 Mutex::Autolock _l(mLock); 87 mAudioPolicyEffects = audioPolicyEffects; 88 } 89 90 mUidPolicy = new UidPolicy(this); 91 mUidPolicy->registerSelf(); 92 } 93 94 AudioPolicyService::~AudioPolicyService() 95 { 96 mTonePlaybackThread->exit(); 97 mAudioCommandThread->exit(); 98 mOutputCommandThread->exit(); 99 100 destroyAudioPolicyManager(mAudioPolicyManager); 101 delete mAudioPolicyClient; 102 103 mNotificationClients.clear(); 104 mAudioPolicyEffects.clear(); 105 106 mUidPolicy->unregisterSelf(); 107 mUidPolicy.clear(); 108 } 109 110 // A notification client is always registered by AudioSystem when the client process 111 // connects to AudioPolicyService. 112 void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client) 113 { 114 if (client == 0) { 115 ALOGW("%s got NULL client", __FUNCTION__); 116 return; 117 } 118 Mutex::Autolock _l(mNotificationClientsLock); 119 120 uid_t uid = IPCThreadState::self()->getCallingUid(); 121 if (mNotificationClients.indexOfKey(uid) < 0) { 122 sp<NotificationClient> notificationClient = new NotificationClient(this, 123 client, 124 uid); 125 ALOGV("registerClient() client %p, uid %d", client.get(), uid); 126 127 mNotificationClients.add(uid, notificationClient); 128 129 sp<IBinder> binder = IInterface::asBinder(client); 130 binder->linkToDeath(notificationClient); 131 } 132 } 133 134 void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled) 135 { 136 Mutex::Autolock _l(mNotificationClientsLock); 137 138 uid_t uid = IPCThreadState::self()->getCallingUid(); 139 if (mNotificationClients.indexOfKey(uid) < 0) { 140 return; 141 } 142 mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled); 143 } 144 145 // removeNotificationClient() is called when the client process dies. 146 void AudioPolicyService::removeNotificationClient(uid_t uid) 147 { 148 { 149 Mutex::Autolock _l(mNotificationClientsLock); 150 mNotificationClients.removeItem(uid); 151 } 152 { 153 Mutex::Autolock _l(mLock); 154 if (mAudioPolicyManager) { 155 // called from binder death notification: no need to clear caller identity 156 mAudioPolicyManager->releaseResourcesForUid(uid); 157 } 158 } 159 } 160 161 void AudioPolicyService::onAudioPortListUpdate() 162 { 163 mOutputCommandThread->updateAudioPortListCommand(); 164 } 165 166 void AudioPolicyService::doOnAudioPortListUpdate() 167 { 168 Mutex::Autolock _l(mNotificationClientsLock); 169 for (size_t i = 0; i < mNotificationClients.size(); i++) { 170 mNotificationClients.valueAt(i)->onAudioPortListUpdate(); 171 } 172 } 173 174 void AudioPolicyService::onAudioPatchListUpdate() 175 { 176 mOutputCommandThread->updateAudioPatchListCommand(); 177 } 178 179 void AudioPolicyService::doOnAudioPatchListUpdate() 180 { 181 Mutex::Autolock _l(mNotificationClientsLock); 182 for (size_t i = 0; i < mNotificationClients.size(); i++) { 183 mNotificationClients.valueAt(i)->onAudioPatchListUpdate(); 184 } 185 } 186 187 void AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state) 188 { 189 ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)", 190 regId.string(), state); 191 mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state); 192 } 193 194 void AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state) 195 { 196 Mutex::Autolock _l(mNotificationClientsLock); 197 for (size_t i = 0; i < mNotificationClients.size(); i++) { 198 mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state); 199 } 200 } 201 202 void AudioPolicyService::onRecordingConfigurationUpdate(int event, 203 const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig, 204 const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) 205 { 206 mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo, 207 clientConfig, deviceConfig, patchHandle); 208 } 209 210 void AudioPolicyService::doOnRecordingConfigurationUpdate(int event, 211 const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig, 212 const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) 213 { 214 Mutex::Autolock _l(mNotificationClientsLock); 215 for (size_t i = 0; i < mNotificationClients.size(); i++) { 216 mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo, 217 clientConfig, deviceConfig, patchHandle); 218 } 219 } 220 221 status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch, 222 audio_patch_handle_t *handle, 223 int delayMs) 224 { 225 return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs); 226 } 227 228 status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle, 229 int delayMs) 230 { 231 return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs); 232 } 233 234 status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config, 235 int delayMs) 236 { 237 return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); 238 } 239 240 AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service, 241 const sp<IAudioPolicyServiceClient>& client, 242 uid_t uid) 243 : mService(service), mUid(uid), mAudioPolicyServiceClient(client), 244 mAudioPortCallbacksEnabled(false) 245 { 246 } 247 248 AudioPolicyService::NotificationClient::~NotificationClient() 249 { 250 } 251 252 void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused) 253 { 254 sp<NotificationClient> keep(this); 255 sp<AudioPolicyService> service = mService.promote(); 256 if (service != 0) { 257 service->removeNotificationClient(mUid); 258 } 259 } 260 261 void AudioPolicyService::NotificationClient::onAudioPortListUpdate() 262 { 263 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 264 mAudioPolicyServiceClient->onAudioPortListUpdate(); 265 } 266 } 267 268 void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() 269 { 270 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 271 mAudioPolicyServiceClient->onAudioPatchListUpdate(); 272 } 273 } 274 275 void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( 276 const String8& regId, int32_t state) 277 { 278 if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) { 279 mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state); 280 } 281 } 282 283 void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate( 284 int event, const record_client_info_t *clientInfo, 285 const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, 286 audio_patch_handle_t patchHandle) 287 { 288 if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) { 289 mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo, 290 clientConfig, deviceConfig, patchHandle); 291 } 292 } 293 294 void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled) 295 { 296 mAudioPortCallbacksEnabled = enabled; 297 } 298 299 300 void AudioPolicyService::binderDied(const wp<IBinder>& who) { 301 ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), 302 IPCThreadState::self()->getCallingPid()); 303 } 304 305 static bool tryLock(Mutex& mutex) 306 { 307 bool locked = false; 308 for (int i = 0; i < kDumpLockRetries; ++i) { 309 if (mutex.tryLock() == NO_ERROR) { 310 locked = true; 311 break; 312 } 313 usleep(kDumpLockSleepUs); 314 } 315 return locked; 316 } 317 318 status_t AudioPolicyService::dumpInternals(int fd) 319 { 320 const size_t SIZE = 256; 321 char buffer[SIZE]; 322 String8 result; 323 324 snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager); 325 result.append(buffer); 326 snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); 327 result.append(buffer); 328 snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); 329 result.append(buffer); 330 331 write(fd, result.string(), result.size()); 332 return NO_ERROR; 333 } 334 335 void AudioPolicyService::setRecordSilenced(uid_t uid, bool silenced) 336 { 337 { 338 Mutex::Autolock _l(mLock); 339 if (mAudioPolicyManager) { 340 AutoCallerClear acc; 341 mAudioPolicyManager->setRecordSilenced(uid, silenced); 342 } 343 } 344 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 345 if (af) { 346 af->setRecordSilenced(uid, silenced); 347 } 348 } 349 350 status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused) 351 { 352 if (!dumpAllowed()) { 353 dumpPermissionDenial(fd); 354 } else { 355 bool locked = tryLock(mLock); 356 if (!locked) { 357 String8 result(kDeadlockedString); 358 write(fd, result.string(), result.size()); 359 } 360 361 dumpInternals(fd); 362 if (mAudioCommandThread != 0) { 363 mAudioCommandThread->dump(fd); 364 } 365 if (mTonePlaybackThread != 0) { 366 mTonePlaybackThread->dump(fd); 367 } 368 369 if (mAudioPolicyManager) { 370 mAudioPolicyManager->dump(fd); 371 } 372 373 if (locked) mLock.unlock(); 374 } 375 return NO_ERROR; 376 } 377 378 status_t AudioPolicyService::dumpPermissionDenial(int fd) 379 { 380 const size_t SIZE = 256; 381 char buffer[SIZE]; 382 String8 result; 383 snprintf(buffer, SIZE, "Permission Denial: " 384 "can't dump AudioPolicyService from pid=%d, uid=%d\n", 385 IPCThreadState::self()->getCallingPid(), 386 IPCThreadState::self()->getCallingUid()); 387 result.append(buffer); 388 write(fd, result.string(), result.size()); 389 return NO_ERROR; 390 } 391 392 status_t AudioPolicyService::onTransact( 393 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 394 switch (code) { 395 case SHELL_COMMAND_TRANSACTION: { 396 int in = data.readFileDescriptor(); 397 int out = data.readFileDescriptor(); 398 int err = data.readFileDescriptor(); 399 int argc = data.readInt32(); 400 Vector<String16> args; 401 for (int i = 0; i < argc && data.dataAvail() > 0; i++) { 402 args.add(data.readString16()); 403 } 404 sp<IBinder> unusedCallback; 405 sp<IResultReceiver> resultReceiver; 406 status_t status; 407 if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) { 408 return status; 409 } 410 if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) { 411 return status; 412 } 413 status = shellCommand(in, out, err, args); 414 if (resultReceiver != nullptr) { 415 resultReceiver->send(status); 416 } 417 return NO_ERROR; 418 } 419 } 420 421 return BnAudioPolicyService::onTransact(code, data, reply, flags); 422 } 423 424 // ------------------- Shell command implementation ------------------- 425 426 // NOTE: This is a remote API - make sure all args are validated 427 status_t AudioPolicyService::shellCommand(int in, int out, int err, Vector<String16>& args) { 428 if (!checkCallingPermission(sManageAudioPolicyPermission, nullptr, nullptr)) { 429 return PERMISSION_DENIED; 430 } 431 if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) { 432 return BAD_VALUE; 433 } 434 if (args.size() == 3 && args[0] == String16("set-uid-state")) { 435 return handleSetUidState(args, err); 436 } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) { 437 return handleResetUidState(args, err); 438 } else if (args.size() == 2 && args[0] == String16("get-uid-state")) { 439 return handleGetUidState(args, out, err); 440 } else if (args.size() == 1 && args[0] == String16("help")) { 441 printHelp(out); 442 return NO_ERROR; 443 } 444 printHelp(err); 445 return BAD_VALUE; 446 } 447 448 status_t AudioPolicyService::handleSetUidState(Vector<String16>& args, int err) { 449 PermissionController pc; 450 int uid = pc.getPackageUid(args[1], 0); 451 if (uid <= 0) { 452 ALOGE("Unknown package: '%s'", String8(args[1]).string()); 453 dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); 454 return BAD_VALUE; 455 } 456 bool active = false; 457 if (args[2] == String16("active")) { 458 active = true; 459 } else if ((args[2] != String16("idle"))) { 460 ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string()); 461 return BAD_VALUE; 462 } 463 mUidPolicy->addOverrideUid(uid, active); 464 return NO_ERROR; 465 } 466 467 status_t AudioPolicyService::handleResetUidState(Vector<String16>& args, int err) { 468 PermissionController pc; 469 int uid = pc.getPackageUid(args[1], 0); 470 if (uid < 0) { 471 ALOGE("Unknown package: '%s'", String8(args[1]).string()); 472 dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); 473 return BAD_VALUE; 474 } 475 mUidPolicy->removeOverrideUid(uid); 476 return NO_ERROR; 477 } 478 479 status_t AudioPolicyService::handleGetUidState(Vector<String16>& args, int out, int err) { 480 PermissionController pc; 481 int uid = pc.getPackageUid(args[1], 0); 482 if (uid < 0) { 483 ALOGE("Unknown package: '%s'", String8(args[1]).string()); 484 dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); 485 return BAD_VALUE; 486 } 487 if (mUidPolicy->isUidActive(uid)) { 488 return dprintf(out, "active\n"); 489 } else { 490 return dprintf(out, "idle\n"); 491 } 492 } 493 494 status_t AudioPolicyService::printHelp(int out) { 495 return dprintf(out, "Audio policy service commands:\n" 496 " get-uid-state <PACKAGE> gets the uid state\n" 497 " set-uid-state <PACKAGE> <active|idle> overrides the uid state\n" 498 " reset-uid-state <PACKAGE> clears the uid state override\n" 499 " help print this message\n"); 500 } 501 502 // ----------- AudioPolicyService::UidPolicy implementation ---------- 503 504 void AudioPolicyService::UidPolicy::registerSelf() { 505 ActivityManager am; 506 am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE 507 | ActivityManager::UID_OBSERVER_IDLE 508 | ActivityManager::UID_OBSERVER_ACTIVE, 509 ActivityManager::PROCESS_STATE_UNKNOWN, 510 String16("audioserver")); 511 status_t res = am.linkToDeath(this); 512 if (!res) { 513 Mutex::Autolock _l(mLock); 514 mObserverRegistered = true; 515 } else { 516 ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res); 517 am.unregisterUidObserver(this); 518 } 519 } 520 521 void AudioPolicyService::UidPolicy::unregisterSelf() { 522 ActivityManager am; 523 am.unlinkToDeath(this); 524 am.unregisterUidObserver(this); 525 Mutex::Autolock _l(mLock); 526 mObserverRegistered = false; 527 } 528 529 void AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) { 530 Mutex::Autolock _l(mLock); 531 mCachedUids.clear(); 532 mObserverRegistered = false; 533 } 534 535 bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) { 536 if (isServiceUid(uid)) return true; 537 bool needToReregister = false; 538 { 539 Mutex::Autolock _l(mLock); 540 needToReregister = !mObserverRegistered; 541 } 542 if (needToReregister) { 543 // Looks like ActivityManager has died previously, attempt to re-register. 544 registerSelf(); 545 } 546 { 547 Mutex::Autolock _l(mLock); 548 auto overrideIter = mOverrideUids.find(uid); 549 if (overrideIter != mOverrideUids.end()) { 550 return overrideIter->second; 551 } 552 // In an absense of the ActivityManager, assume everything to be active. 553 if (!mObserverRegistered) return true; 554 auto cacheIter = mCachedUids.find(uid); 555 if (cacheIter != mCachedUids.end()) { 556 return cacheIter->second; 557 } 558 } 559 ActivityManager am; 560 bool active = am.isUidActive(uid, String16("audioserver")); 561 { 562 Mutex::Autolock _l(mLock); 563 mCachedUids.insert(std::pair<uid_t, bool>(uid, active)); 564 } 565 return active; 566 } 567 568 void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) { 569 updateUidCache(uid, true, true); 570 } 571 572 void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) { 573 updateUidCache(uid, false, false); 574 } 575 576 void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) { 577 updateUidCache(uid, false, true); 578 } 579 580 bool AudioPolicyService::UidPolicy::isServiceUid(uid_t uid) const { 581 return multiuser_get_app_id(uid) < AID_APP_START; 582 } 583 584 void AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) { 585 sp<AudioPolicyService> service = mService.promote(); 586 if (service != nullptr) { 587 service->setRecordSilenced(uid, !active); 588 } 589 } 590 591 void AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) { 592 if (isServiceUid(uid)) return; 593 bool wasOverridden = false, wasActive = false; 594 { 595 Mutex::Autolock _l(mLock); 596 updateUidLocked(&mOverrideUids, uid, active, insert, &wasOverridden, &wasActive); 597 } 598 if (!wasOverridden && insert) { 599 notifyService(uid, active); // Started to override. 600 } else if (wasOverridden && !insert) { 601 notifyService(uid, isUidActive(uid)); // Override ceased, notify with ground truth. 602 } else if (wasActive != active) { 603 notifyService(uid, active); // Override updated. 604 } 605 } 606 607 void AudioPolicyService::UidPolicy::updateUidCache(uid_t uid, bool active, bool insert) { 608 if (isServiceUid(uid)) return; 609 bool wasActive = false; 610 { 611 Mutex::Autolock _l(mLock); 612 updateUidLocked(&mCachedUids, uid, active, insert, nullptr, &wasActive); 613 // Do not notify service if currently overridden. 614 if (mOverrideUids.find(uid) != mOverrideUids.end()) return; 615 } 616 bool nowActive = active && insert; 617 if (wasActive != nowActive) notifyService(uid, nowActive); 618 } 619 620 void AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t, bool> *uids, 621 uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive) { 622 auto it = uids->find(uid); 623 if (it != uids->end()) { 624 if (wasThere != nullptr) *wasThere = true; 625 if (wasActive != nullptr) *wasActive = it->second; 626 if (insert) { 627 it->second = active; 628 } else { 629 uids->erase(it); 630 } 631 } else if (insert) { 632 uids->insert(std::pair<uid_t, bool>(uid, active)); 633 } 634 } 635 636 // ----------- AudioPolicyService::AudioCommandThread implementation ---------- 637 638 AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name, 639 const wp<AudioPolicyService>& service) 640 : Thread(false), mName(name), mService(service) 641 { 642 mpToneGenerator = NULL; 643 } 644 645 646 AudioPolicyService::AudioCommandThread::~AudioCommandThread() 647 { 648 if (!mAudioCommands.isEmpty()) { 649 release_wake_lock(mName.string()); 650 } 651 mAudioCommands.clear(); 652 delete mpToneGenerator; 653 } 654 655 void AudioPolicyService::AudioCommandThread::onFirstRef() 656 { 657 run(mName.string(), ANDROID_PRIORITY_AUDIO); 658 } 659 660 bool AudioPolicyService::AudioCommandThread::threadLoop() 661 { 662 nsecs_t waitTime = -1; 663 664 mLock.lock(); 665 while (!exitPending()) 666 { 667 sp<AudioPolicyService> svc; 668 while (!mAudioCommands.isEmpty() && !exitPending()) { 669 nsecs_t curTime = systemTime(); 670 // commands are sorted by increasing time stamp: execute them from index 0 and up 671 if (mAudioCommands[0]->mTime <= curTime) { 672 sp<AudioCommand> command = mAudioCommands[0]; 673 mAudioCommands.removeAt(0); 674 mLastCommand = command; 675 676 switch (command->mCommand) { 677 case START_TONE: { 678 mLock.unlock(); 679 ToneData *data = (ToneData *)command->mParam.get(); 680 ALOGV("AudioCommandThread() processing start tone %d on stream %d", 681 data->mType, data->mStream); 682 delete mpToneGenerator; 683 mpToneGenerator = new ToneGenerator(data->mStream, 1.0); 684 mpToneGenerator->startTone(data->mType); 685 mLock.lock(); 686 }break; 687 case STOP_TONE: { 688 mLock.unlock(); 689 ALOGV("AudioCommandThread() processing stop tone"); 690 if (mpToneGenerator != NULL) { 691 mpToneGenerator->stopTone(); 692 delete mpToneGenerator; 693 mpToneGenerator = NULL; 694 } 695 mLock.lock(); 696 }break; 697 case SET_VOLUME: { 698 VolumeData *data = (VolumeData *)command->mParam.get(); 699 ALOGV("AudioCommandThread() processing set volume stream %d, \ 700 volume %f, output %d", data->mStream, data->mVolume, data->mIO); 701 command->mStatus = AudioSystem::setStreamVolume(data->mStream, 702 data->mVolume, 703 data->mIO); 704 }break; 705 case SET_PARAMETERS: { 706 ParametersData *data = (ParametersData *)command->mParam.get(); 707 ALOGV("AudioCommandThread() processing set parameters string %s, io %d", 708 data->mKeyValuePairs.string(), data->mIO); 709 command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); 710 }break; 711 case SET_VOICE_VOLUME: { 712 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 713 ALOGV("AudioCommandThread() processing set voice volume volume %f", 714 data->mVolume); 715 command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); 716 }break; 717 case STOP_OUTPUT: { 718 StopOutputData *data = (StopOutputData *)command->mParam.get(); 719 ALOGV("AudioCommandThread() processing stop output %d", 720 data->mIO); 721 svc = mService.promote(); 722 if (svc == 0) { 723 break; 724 } 725 mLock.unlock(); 726 svc->doStopOutput(data->mIO, data->mStream, data->mSession); 727 mLock.lock(); 728 }break; 729 case RELEASE_OUTPUT: { 730 ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get(); 731 ALOGV("AudioCommandThread() processing release output %d", 732 data->mIO); 733 svc = mService.promote(); 734 if (svc == 0) { 735 break; 736 } 737 mLock.unlock(); 738 svc->doReleaseOutput(data->mIO, data->mStream, data->mSession); 739 mLock.lock(); 740 }break; 741 case CREATE_AUDIO_PATCH: { 742 CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get(); 743 ALOGV("AudioCommandThread() processing create audio patch"); 744 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 745 if (af == 0) { 746 command->mStatus = PERMISSION_DENIED; 747 } else { 748 command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle); 749 } 750 } break; 751 case RELEASE_AUDIO_PATCH: { 752 ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get(); 753 ALOGV("AudioCommandThread() processing release audio patch"); 754 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 755 if (af == 0) { 756 command->mStatus = PERMISSION_DENIED; 757 } else { 758 command->mStatus = af->releaseAudioPatch(data->mHandle); 759 } 760 } break; 761 case UPDATE_AUDIOPORT_LIST: { 762 ALOGV("AudioCommandThread() processing update audio port list"); 763 svc = mService.promote(); 764 if (svc == 0) { 765 break; 766 } 767 mLock.unlock(); 768 svc->doOnAudioPortListUpdate(); 769 mLock.lock(); 770 }break; 771 case UPDATE_AUDIOPATCH_LIST: { 772 ALOGV("AudioCommandThread() processing update audio patch list"); 773 svc = mService.promote(); 774 if (svc == 0) { 775 break; 776 } 777 mLock.unlock(); 778 svc->doOnAudioPatchListUpdate(); 779 mLock.lock(); 780 }break; 781 case SET_AUDIOPORT_CONFIG: { 782 SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get(); 783 ALOGV("AudioCommandThread() processing set port config"); 784 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 785 if (af == 0) { 786 command->mStatus = PERMISSION_DENIED; 787 } else { 788 command->mStatus = af->setAudioPortConfig(&data->mConfig); 789 } 790 } break; 791 case DYN_POLICY_MIX_STATE_UPDATE: { 792 DynPolicyMixStateUpdateData *data = 793 (DynPolicyMixStateUpdateData *)command->mParam.get(); 794 ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d", 795 data->mRegId.string(), data->mState); 796 svc = mService.promote(); 797 if (svc == 0) { 798 break; 799 } 800 mLock.unlock(); 801 svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState); 802 mLock.lock(); 803 } break; 804 case RECORDING_CONFIGURATION_UPDATE: { 805 RecordingConfigurationUpdateData *data = 806 (RecordingConfigurationUpdateData *)command->mParam.get(); 807 ALOGV("AudioCommandThread() processing recording configuration update"); 808 svc = mService.promote(); 809 if (svc == 0) { 810 break; 811 } 812 mLock.unlock(); 813 svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo, 814 &data->mClientConfig, &data->mDeviceConfig, 815 data->mPatchHandle); 816 mLock.lock(); 817 } break; 818 default: 819 ALOGW("AudioCommandThread() unknown command %d", command->mCommand); 820 } 821 { 822 Mutex::Autolock _l(command->mLock); 823 if (command->mWaitStatus) { 824 command->mWaitStatus = false; 825 command->mCond.signal(); 826 } 827 } 828 waitTime = -1; 829 // release mLock before releasing strong reference on the service as 830 // AudioPolicyService destructor calls AudioCommandThread::exit() which 831 // acquires mLock. 832 mLock.unlock(); 833 svc.clear(); 834 mLock.lock(); 835 } else { 836 waitTime = mAudioCommands[0]->mTime - curTime; 837 break; 838 } 839 } 840 841 // release delayed commands wake lock if the queue is empty 842 if (mAudioCommands.isEmpty()) { 843 release_wake_lock(mName.string()); 844 } 845 846 // At this stage we have either an empty command queue or the first command in the queue 847 // has a finite delay. So unless we are exiting it is safe to wait. 848 if (!exitPending()) { 849 ALOGV("AudioCommandThread() going to sleep"); 850 if (waitTime == -1) { 851 mWaitWorkCV.wait(mLock); 852 } else { 853 mWaitWorkCV.waitRelative(mLock, waitTime); 854 } 855 } 856 } 857 // release delayed commands wake lock before quitting 858 if (!mAudioCommands.isEmpty()) { 859 release_wake_lock(mName.string()); 860 } 861 mLock.unlock(); 862 return false; 863 } 864 865 status_t AudioPolicyService::AudioCommandThread::dump(int fd) 866 { 867 const size_t SIZE = 256; 868 char buffer[SIZE]; 869 String8 result; 870 871 snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 872 result.append(buffer); 873 write(fd, result.string(), result.size()); 874 875 bool locked = tryLock(mLock); 876 if (!locked) { 877 String8 result2(kCmdDeadlockedString); 878 write(fd, result2.string(), result2.size()); 879 } 880 881 snprintf(buffer, SIZE, "- Commands:\n"); 882 result = String8(buffer); 883 result.append(" Command Time Wait pParam\n"); 884 for (size_t i = 0; i < mAudioCommands.size(); i++) { 885 mAudioCommands[i]->dump(buffer, SIZE); 886 result.append(buffer); 887 } 888 result.append(" Last Command\n"); 889 if (mLastCommand != 0) { 890 mLastCommand->dump(buffer, SIZE); 891 result.append(buffer); 892 } else { 893 result.append(" none\n"); 894 } 895 896 write(fd, result.string(), result.size()); 897 898 if (locked) mLock.unlock(); 899 900 return NO_ERROR; 901 } 902 903 void AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type, 904 audio_stream_type_t stream) 905 { 906 sp<AudioCommand> command = new AudioCommand(); 907 command->mCommand = START_TONE; 908 sp<ToneData> data = new ToneData(); 909 data->mType = type; 910 data->mStream = stream; 911 command->mParam = data; 912 ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 913 sendCommand(command); 914 } 915 916 void AudioPolicyService::AudioCommandThread::stopToneCommand() 917 { 918 sp<AudioCommand> command = new AudioCommand(); 919 command->mCommand = STOP_TONE; 920 ALOGV("AudioCommandThread() adding tone stop"); 921 sendCommand(command); 922 } 923 924 status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream, 925 float volume, 926 audio_io_handle_t output, 927 int delayMs) 928 { 929 sp<AudioCommand> command = new AudioCommand(); 930 command->mCommand = SET_VOLUME; 931 sp<VolumeData> data = new VolumeData(); 932 data->mStream = stream; 933 data->mVolume = volume; 934 data->mIO = output; 935 command->mParam = data; 936 command->mWaitStatus = true; 937 ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 938 stream, volume, output); 939 return sendCommand(command, delayMs); 940 } 941 942 status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle, 943 const char *keyValuePairs, 944 int delayMs) 945 { 946 sp<AudioCommand> command = new AudioCommand(); 947 command->mCommand = SET_PARAMETERS; 948 sp<ParametersData> data = new ParametersData(); 949 data->mIO = ioHandle; 950 data->mKeyValuePairs = String8(keyValuePairs); 951 command->mParam = data; 952 command->mWaitStatus = true; 953 ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 954 keyValuePairs, ioHandle, delayMs); 955 return sendCommand(command, delayMs); 956 } 957 958 status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 959 { 960 sp<AudioCommand> command = new AudioCommand(); 961 command->mCommand = SET_VOICE_VOLUME; 962 sp<VoiceVolumeData> data = new VoiceVolumeData(); 963 data->mVolume = volume; 964 command->mParam = data; 965 command->mWaitStatus = true; 966 ALOGV("AudioCommandThread() adding set voice volume volume %f", volume); 967 return sendCommand(command, delayMs); 968 } 969 970 void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output, 971 audio_stream_type_t stream, 972 audio_session_t session) 973 { 974 sp<AudioCommand> command = new AudioCommand(); 975 command->mCommand = STOP_OUTPUT; 976 sp<StopOutputData> data = new StopOutputData(); 977 data->mIO = output; 978 data->mStream = stream; 979 data->mSession = session; 980 command->mParam = data; 981 ALOGV("AudioCommandThread() adding stop output %d", output); 982 sendCommand(command); 983 } 984 985 void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output, 986 audio_stream_type_t stream, 987 audio_session_t session) 988 { 989 sp<AudioCommand> command = new AudioCommand(); 990 command->mCommand = RELEASE_OUTPUT; 991 sp<ReleaseOutputData> data = new ReleaseOutputData(); 992 data->mIO = output; 993 data->mStream = stream; 994 data->mSession = session; 995 command->mParam = data; 996 ALOGV("AudioCommandThread() adding release output %d", output); 997 sendCommand(command); 998 } 999 1000 status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand( 1001 const struct audio_patch *patch, 1002 audio_patch_handle_t *handle, 1003 int delayMs) 1004 { 1005 status_t status = NO_ERROR; 1006 1007 sp<AudioCommand> command = new AudioCommand(); 1008 command->mCommand = CREATE_AUDIO_PATCH; 1009 CreateAudioPatchData *data = new CreateAudioPatchData(); 1010 data->mPatch = *patch; 1011 data->mHandle = *handle; 1012 command->mParam = data; 1013 command->mWaitStatus = true; 1014 ALOGV("AudioCommandThread() adding create patch delay %d", delayMs); 1015 status = sendCommand(command, delayMs); 1016 if (status == NO_ERROR) { 1017 *handle = data->mHandle; 1018 } 1019 return status; 1020 } 1021 1022 status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle, 1023 int delayMs) 1024 { 1025 sp<AudioCommand> command = new AudioCommand(); 1026 command->mCommand = RELEASE_AUDIO_PATCH; 1027 ReleaseAudioPatchData *data = new ReleaseAudioPatchData(); 1028 data->mHandle = handle; 1029 command->mParam = data; 1030 command->mWaitStatus = true; 1031 ALOGV("AudioCommandThread() adding release patch delay %d", delayMs); 1032 return sendCommand(command, delayMs); 1033 } 1034 1035 void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand() 1036 { 1037 sp<AudioCommand> command = new AudioCommand(); 1038 command->mCommand = UPDATE_AUDIOPORT_LIST; 1039 ALOGV("AudioCommandThread() adding update audio port list"); 1040 sendCommand(command); 1041 } 1042 1043 void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand() 1044 { 1045 sp<AudioCommand>command = new AudioCommand(); 1046 command->mCommand = UPDATE_AUDIOPATCH_LIST; 1047 ALOGV("AudioCommandThread() adding update audio patch list"); 1048 sendCommand(command); 1049 } 1050 1051 status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand( 1052 const struct audio_port_config *config, int delayMs) 1053 { 1054 sp<AudioCommand> command = new AudioCommand(); 1055 command->mCommand = SET_AUDIOPORT_CONFIG; 1056 SetAudioPortConfigData *data = new SetAudioPortConfigData(); 1057 data->mConfig = *config; 1058 command->mParam = data; 1059 command->mWaitStatus = true; 1060 ALOGV("AudioCommandThread() adding set port config delay %d", delayMs); 1061 return sendCommand(command, delayMs); 1062 } 1063 1064 void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( 1065 const String8& regId, int32_t state) 1066 { 1067 sp<AudioCommand> command = new AudioCommand(); 1068 command->mCommand = DYN_POLICY_MIX_STATE_UPDATE; 1069 DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData(); 1070 data->mRegId = regId; 1071 data->mState = state; 1072 command->mParam = data; 1073 ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d", 1074 regId.string(), state); 1075 sendCommand(command); 1076 } 1077 1078 void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand( 1079 int event, const record_client_info_t *clientInfo, 1080 const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, 1081 audio_patch_handle_t patchHandle) 1082 { 1083 sp<AudioCommand>command = new AudioCommand(); 1084 command->mCommand = RECORDING_CONFIGURATION_UPDATE; 1085 RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData(); 1086 data->mEvent = event; 1087 data->mClientInfo = *clientInfo; 1088 data->mClientConfig = *clientConfig; 1089 data->mDeviceConfig = *deviceConfig; 1090 data->mPatchHandle = patchHandle; 1091 command->mParam = data; 1092 ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u", 1093 event, clientInfo->source, clientInfo->uid); 1094 sendCommand(command); 1095 } 1096 1097 status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) 1098 { 1099 { 1100 Mutex::Autolock _l(mLock); 1101 insertCommand_l(command, delayMs); 1102 mWaitWorkCV.signal(); 1103 } 1104 Mutex::Autolock _l(command->mLock); 1105 while (command->mWaitStatus) { 1106 nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs); 1107 if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) { 1108 command->mStatus = TIMED_OUT; 1109 command->mWaitStatus = false; 1110 } 1111 } 1112 return command->mStatus; 1113 } 1114 1115 // insertCommand_l() must be called with mLock held 1116 void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs) 1117 { 1118 ssize_t i; // not size_t because i will count down to -1 1119 Vector < sp<AudioCommand> > removedCommands; 1120 command->mTime = systemTime() + milliseconds(delayMs); 1121 1122 // acquire wake lock to make sure delayed commands are processed 1123 if (mAudioCommands.isEmpty()) { 1124 acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 1125 } 1126 1127 // check same pending commands with later time stamps and eliminate them 1128 for (i = (ssize_t)mAudioCommands.size()-1; i >= 0; i--) { 1129 sp<AudioCommand> command2 = mAudioCommands[i]; 1130 // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 1131 if (command2->mTime <= command->mTime) break; 1132 1133 // create audio patch or release audio patch commands are equivalent 1134 // with regard to filtering 1135 if ((command->mCommand == CREATE_AUDIO_PATCH) || 1136 (command->mCommand == RELEASE_AUDIO_PATCH)) { 1137 if ((command2->mCommand != CREATE_AUDIO_PATCH) && 1138 (command2->mCommand != RELEASE_AUDIO_PATCH)) { 1139 continue; 1140 } 1141 } else if (command2->mCommand != command->mCommand) continue; 1142 1143 switch (command->mCommand) { 1144 case SET_PARAMETERS: { 1145 ParametersData *data = (ParametersData *)command->mParam.get(); 1146 ParametersData *data2 = (ParametersData *)command2->mParam.get(); 1147 if (data->mIO != data2->mIO) break; 1148 ALOGV("Comparing parameter command %s to new command %s", 1149 data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 1150 AudioParameter param = AudioParameter(data->mKeyValuePairs); 1151 AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 1152 for (size_t j = 0; j < param.size(); j++) { 1153 String8 key; 1154 String8 value; 1155 param.getAt(j, key, value); 1156 for (size_t k = 0; k < param2.size(); k++) { 1157 String8 key2; 1158 String8 value2; 1159 param2.getAt(k, key2, value2); 1160 if (key2 == key) { 1161 param2.remove(key2); 1162 ALOGV("Filtering out parameter %s", key2.string()); 1163 break; 1164 } 1165 } 1166 } 1167 // if all keys have been filtered out, remove the command. 1168 // otherwise, update the key value pairs 1169 if (param2.size() == 0) { 1170 removedCommands.add(command2); 1171 } else { 1172 data2->mKeyValuePairs = param2.toString(); 1173 } 1174 command->mTime = command2->mTime; 1175 // force delayMs to non 0 so that code below does not request to wait for 1176 // command status as the command is now delayed 1177 delayMs = 1; 1178 } break; 1179 1180 case SET_VOLUME: { 1181 VolumeData *data = (VolumeData *)command->mParam.get(); 1182 VolumeData *data2 = (VolumeData *)command2->mParam.get(); 1183 if (data->mIO != data2->mIO) break; 1184 if (data->mStream != data2->mStream) break; 1185 ALOGV("Filtering out volume command on output %d for stream %d", 1186 data->mIO, data->mStream); 1187 removedCommands.add(command2); 1188 command->mTime = command2->mTime; 1189 // force delayMs to non 0 so that code below does not request to wait for 1190 // command status as the command is now delayed 1191 delayMs = 1; 1192 } break; 1193 1194 case SET_VOICE_VOLUME: { 1195 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 1196 VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get(); 1197 ALOGV("Filtering out voice volume command value %f replaced by %f", 1198 data2->mVolume, data->mVolume); 1199 removedCommands.add(command2); 1200 command->mTime = command2->mTime; 1201 // force delayMs to non 0 so that code below does not request to wait for 1202 // command status as the command is now delayed 1203 delayMs = 1; 1204 } break; 1205 1206 case CREATE_AUDIO_PATCH: 1207 case RELEASE_AUDIO_PATCH: { 1208 audio_patch_handle_t handle; 1209 struct audio_patch patch; 1210 if (command->mCommand == CREATE_AUDIO_PATCH) { 1211 handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle; 1212 patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch; 1213 } else { 1214 handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle; 1215 } 1216 audio_patch_handle_t handle2; 1217 struct audio_patch patch2; 1218 if (command2->mCommand == CREATE_AUDIO_PATCH) { 1219 handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle; 1220 patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch; 1221 } else { 1222 handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle; 1223 memset(&patch2, 0, sizeof(patch2)); 1224 } 1225 if (handle != handle2) break; 1226 /* Filter CREATE_AUDIO_PATCH commands only when they are issued for 1227 same output. */ 1228 if( (command->mCommand == CREATE_AUDIO_PATCH) && 1229 (command2->mCommand == CREATE_AUDIO_PATCH) ) { 1230 bool isOutputDiff = false; 1231 if (patch.num_sources == patch2.num_sources) { 1232 for (unsigned count = 0; count < patch.num_sources; count++) { 1233 if (patch.sources[count].id != patch2.sources[count].id) { 1234 isOutputDiff = true; 1235 break; 1236 } 1237 } 1238 if (isOutputDiff) 1239 break; 1240 } 1241 } 1242 ALOGV("Filtering out %s audio patch command for handle %d", 1243 (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle); 1244 removedCommands.add(command2); 1245 command->mTime = command2->mTime; 1246 // force delayMs to non 0 so that code below does not request to wait for 1247 // command status as the command is now delayed 1248 delayMs = 1; 1249 } break; 1250 1251 case DYN_POLICY_MIX_STATE_UPDATE: { 1252 1253 } break; 1254 1255 case RECORDING_CONFIGURATION_UPDATE: { 1256 1257 } break; 1258 1259 case START_TONE: 1260 case STOP_TONE: 1261 default: 1262 break; 1263 } 1264 } 1265 1266 // remove filtered commands 1267 for (size_t j = 0; j < removedCommands.size(); j++) { 1268 // removed commands always have time stamps greater than current command 1269 for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 1270 if (mAudioCommands[k].get() == removedCommands[j].get()) { 1271 ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 1272 mAudioCommands.removeAt(k); 1273 break; 1274 } 1275 } 1276 } 1277 removedCommands.clear(); 1278 1279 // Disable wait for status if delay is not 0. 1280 // Except for create audio patch command because the returned patch handle 1281 // is needed by audio policy manager 1282 if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) { 1283 command->mWaitStatus = false; 1284 } 1285 1286 // insert command at the right place according to its time stamp 1287 ALOGV("inserting command: %d at index %zd, num commands %zu", 1288 command->mCommand, i+1, mAudioCommands.size()); 1289 mAudioCommands.insertAt(command, i + 1); 1290 } 1291 1292 void AudioPolicyService::AudioCommandThread::exit() 1293 { 1294 ALOGV("AudioCommandThread::exit"); 1295 { 1296 AutoMutex _l(mLock); 1297 requestExit(); 1298 mWaitWorkCV.signal(); 1299 } 1300 // Note that we can call it from the thread loop if all other references have been released 1301 // but it will safely return WOULD_BLOCK in this case 1302 requestExitAndWait(); 1303 } 1304 1305 void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 1306 { 1307 snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 1308 mCommand, 1309 (int)ns2s(mTime), 1310 (int)ns2ms(mTime)%1000, 1311 mWaitStatus, 1312 mParam.get()); 1313 } 1314 1315 /******* helpers for the service_ops callbacks defined below *********/ 1316 void AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 1317 const char *keyValuePairs, 1318 int delayMs) 1319 { 1320 mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs, 1321 delayMs); 1322 } 1323 1324 int AudioPolicyService::setStreamVolume(audio_stream_type_t stream, 1325 float volume, 1326 audio_io_handle_t output, 1327 int delayMs) 1328 { 1329 return (int)mAudioCommandThread->volumeCommand(stream, volume, 1330 output, delayMs); 1331 } 1332 1333 int AudioPolicyService::startTone(audio_policy_tone_t tone, 1334 audio_stream_type_t stream) 1335 { 1336 if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) { 1337 ALOGE("startTone: illegal tone requested (%d)", tone); 1338 } 1339 if (stream != AUDIO_STREAM_VOICE_CALL) { 1340 ALOGE("startTone: illegal stream (%d) requested for tone %d", stream, 1341 tone); 1342 } 1343 mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING, 1344 AUDIO_STREAM_VOICE_CALL); 1345 return 0; 1346 } 1347 1348 int AudioPolicyService::stopTone() 1349 { 1350 mTonePlaybackThread->stopToneCommand(); 1351 return 0; 1352 } 1353 1354 int AudioPolicyService::setVoiceVolume(float volume, int delayMs) 1355 { 1356 return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 1357 } 1358 1359 extern "C" { 1360 audio_module_handle_t aps_load_hw_module(void *service __unused, 1361 const char *name); 1362 audio_io_handle_t aps_open_output(void *service __unused, 1363 audio_devices_t *pDevices, 1364 uint32_t *pSamplingRate, 1365 audio_format_t *pFormat, 1366 audio_channel_mask_t *pChannelMask, 1367 uint32_t *pLatencyMs, 1368 audio_output_flags_t flags); 1369 1370 audio_io_handle_t aps_open_output_on_module(void *service __unused, 1371 audio_module_handle_t module, 1372 audio_devices_t *pDevices, 1373 uint32_t *pSamplingRate, 1374 audio_format_t *pFormat, 1375 audio_channel_mask_t *pChannelMask, 1376 uint32_t *pLatencyMs, 1377 audio_output_flags_t flags, 1378 const audio_offload_info_t *offloadInfo); 1379 audio_io_handle_t aps_open_dup_output(void *service __unused, 1380 audio_io_handle_t output1, 1381 audio_io_handle_t output2); 1382 int aps_close_output(void *service __unused, audio_io_handle_t output); 1383 int aps_suspend_output(void *service __unused, audio_io_handle_t output); 1384 int aps_restore_output(void *service __unused, audio_io_handle_t output); 1385 audio_io_handle_t aps_open_input(void *service __unused, 1386 audio_devices_t *pDevices, 1387 uint32_t *pSamplingRate, 1388 audio_format_t *pFormat, 1389 audio_channel_mask_t *pChannelMask, 1390 audio_in_acoustics_t acoustics __unused); 1391 audio_io_handle_t aps_open_input_on_module(void *service __unused, 1392 audio_module_handle_t module, 1393 audio_devices_t *pDevices, 1394 uint32_t *pSamplingRate, 1395 audio_format_t *pFormat, 1396 audio_channel_mask_t *pChannelMask); 1397 int aps_close_input(void *service __unused, audio_io_handle_t input); 1398 int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream); 1399 int aps_move_effects(void *service __unused, audio_session_t session, 1400 audio_io_handle_t src_output, 1401 audio_io_handle_t dst_output); 1402 char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle, 1403 const char *keys); 1404 void aps_set_parameters(void *service, audio_io_handle_t io_handle, 1405 const char *kv_pairs, int delay_ms); 1406 int aps_set_stream_volume(void *service, audio_stream_type_t stream, 1407 float volume, audio_io_handle_t output, 1408 int delay_ms); 1409 int aps_start_tone(void *service, audio_policy_tone_t tone, 1410 audio_stream_type_t stream); 1411 int aps_stop_tone(void *service); 1412 int aps_set_voice_volume(void *service, float volume, int delay_ms); 1413 }; 1414 1415 } // namespace android 1416