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