AudioPolicyService.cpp revision f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04d
165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian/* 265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Copyright (C) 2009 The Android Open Source Project 365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * 465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * you may not use this file except in compliance with the License. 665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * You may obtain a copy of the License at 765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * 865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * 1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Unless required by applicable law or agreed to in writing, software 1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * See the License for the specific language governing permissions and 1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * limitations under the License. 1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian */ 1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "AudioPolicyService" 1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//#define LOG_NDEBUG 0 1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 20153b9fe667e6e78e0218ff0159353097428c7657Glenn Kasten#include "Configuration.h" 2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#undef __STRICT_ANSI__ 2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define __STDINT_LIMITS 2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define __STDC_LIMIT_MACROS 2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <stdint.h> 2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/time.h> 2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h> 2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h> 2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/properties.h> 3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h> 3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h> 3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/threads.h> 3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioPolicyService.h" 3444deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten#include "ServiceUtilities.h" 3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware_legacy/power.h> 367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent#include <media/AudioEffect.h> 377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent#include <media/EffectsFactoryApi.h> 3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 39fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <hardware/hardware.h> 4064760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h> 417394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin#include <system/audio_policy.h> 42fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <hardware/audio_policy.h> 43fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android { 4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 468dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n"; 478dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n"; 4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50; 5022ecc912a87099cff8cadc424cd12f85c118673fGlenn Kastenstatic const int kDumpLockSleepUs = 20000; 5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 520ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatic const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds 535fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher 54fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinnamespace { 55fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin extern struct audio_policy_service_ops aps_ops; 56fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}; 57fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioPolicyService() 61dce54a1492c410ad0d93253b341fb33305337505Eric Laurent : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL), 62bb6c9a05840d924b502ce0f1868fca4881ada1edEric Laurent mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID) 6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 64f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent} 65f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent 66f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurentvoid AudioPolicyService::onFirstRef() 67f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent{ 6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char value[PROPERTY_VALUE_MAX]; 69fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin const struct hw_module_t *module; 70fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int forced_val; 71fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int rc; 7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 738b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent { 748b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 75935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent 768b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start tone playback thread 778b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this); 788b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start audio commands thread 798b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this); 808b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start output activity command thread 818b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this); 82dce54a1492c410ad0d93253b341fb33305337505Eric Laurent 83dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#ifdef USE_LEGACY_AUDIO_POLICY 848b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGI("AudioPolicyService CSTOR in legacy mode"); 858b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent 868b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent /* instantiate the audio policy manager */ 878b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module); 888b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent if (rc) { 898b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent return; 908b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 918b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent rc = audio_policy_dev_open(module, &mpAudioPolicyDev); 928b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc)); 938b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent if (rc) { 948b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent return; 958b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 968b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent 978b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this, 988b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent &mpAudioPolicy); 998b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc)); 1008b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent if (rc) { 1018b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent return; 1028b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 1038b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent 1048b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent rc = mpAudioPolicy->init_check(mpAudioPolicy); 1058b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc)); 1068b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent if (rc) { 1078b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent return; 1088b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 1098b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGI("Loaded audio policy from %s (%s)", module->name, module->id); 110dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#else 1118b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGI("AudioPolicyService CSTOR in new mode"); 112dce54a1492c410ad0d93253b341fb33305337505Eric Laurent 1138b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyClient = new AudioPolicyClient(this); 1148b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); 115dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#endif 1168b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 117ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // load audio processing modules 1188b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects(); 1198b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent { 1208b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 1218b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyEffects = audioPolicyEffects; 1228b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 12365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 12465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::~AudioPolicyService() 12665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 12765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mTonePlaybackThread->exit(); 12865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommandThread->exit(); 129657ff61389d7316f798d4abe03efac56fd528d91Eric Laurent mOutputCommandThread->exit(); 1307c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent 131dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#ifdef USE_LEGACY_AUDIO_POLICY 1326e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (mpAudioPolicy != NULL && mpAudioPolicyDev != NULL) { 133fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy); 1346e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 1356e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (mpAudioPolicyDev != NULL) { 136fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_policy_dev_close(mpAudioPolicyDev); 1376e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 138dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#else 139f269b8e0e9ab950fc6652b9594b7a3431c81630cEric Laurent destroyAudioPolicyManager(mAudioPolicyManager); 140dce54a1492c410ad0d93253b341fb33305337505Eric Laurent delete mAudioPolicyClient; 141dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#endif 142b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 143b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.clear(); 144ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mAudioPolicyEffects.clear(); 145b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 146b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 147b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// A notification client is always registered by AudioSystem when the client process 148b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// connects to AudioPolicyService. 149b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client) 150b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 151b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 152b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent Mutex::Autolock _l(mLock); 153b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 154b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid_t uid = IPCThreadState::self()->getCallingUid(); 155b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (mNotificationClients.indexOfKey(uid) < 0) { 156b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<NotificationClient> notificationClient = new NotificationClient(this, 157b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent client, 158b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid); 159b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("registerClient() client %p, uid %d", client.get(), uid); 160b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 161b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.add(uid, notificationClient); 162b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 163b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<IBinder> binder = client->asBinder(); 164b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent binder->linkToDeath(notificationClient); 165b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 166b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 167b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 168b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// removeNotificationClient() is called when the client process dies. 169b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::removeNotificationClient(uid_t uid) 170b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 171b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent Mutex::Autolock _l(mLock); 172b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 173b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.removeItem(uid); 174b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 175b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent#ifndef USE_LEGACY_AUDIO_POLICY 176b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (mAudioPolicyManager) { 177b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mAudioPolicyManager->clearAudioPatches(uid); 178b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 179b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent#endif 180b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 181b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 182b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPortListUpdate() 183b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 184b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mOutputCommandThread->updateAudioPortListCommand(); 185b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 186b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 187b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPortListUpdate() 188b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 189b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent Mutex::Autolock _l(mLock); 190b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent for (size_t i = 0; i < mNotificationClients.size(); i++) { 191b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.valueAt(i)->onAudioPortListUpdate(); 192b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 193b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 194b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 195b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPatchListUpdate() 196b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 197b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mOutputCommandThread->updateAudioPatchListCommand(); 19865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 19965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 200951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch, 201951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent audio_patch_handle_t *handle, 202951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent int delayMs) 203951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{ 204951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs); 205951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent} 206951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 207951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle, 208951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent int delayMs) 209951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{ 210951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs); 211951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent} 212951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 213b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPatchListUpdate() 214b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 215b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent Mutex::Autolock _l(mLock); 216b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent for (size_t i = 0; i < mNotificationClients.size(); i++) { 217b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.valueAt(i)->onAudioPatchListUpdate(); 218b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 219b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 220b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 221e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config, 222e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent int delayMs) 223e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{ 224e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); 225e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent} 226e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 227b52c152d553556b2d227ffc943489de0c60b4b02Eric LaurentAudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service, 228b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent const sp<IAudioPolicyServiceClient>& client, 229b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid_t uid) 230b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent : mService(service), mUid(uid), mAudioPolicyServiceClient(client) 231b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 232b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 233b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 234b52c152d553556b2d227ffc943489de0c60b4b02Eric LaurentAudioPolicyService::NotificationClient::~NotificationClient() 235b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 236b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 237b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 238b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused) 239b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 240b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<NotificationClient> keep(this); 241b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<AudioPolicyService> service = mService.promote(); 242b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (service != 0) { 243b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent service->removeNotificationClient(mUid); 244b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 245b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 246b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 247b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::onAudioPortListUpdate() 248b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 249b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (mAudioPolicyServiceClient != 0) { 250b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mAudioPolicyServiceClient->onAudioPortListUpdate(); 251b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 252b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 253b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 254b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::onAudioPatchListUpdate() 255b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 256b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (mAudioPolicyServiceClient != 0) { 257b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mAudioPolicyServiceClient->onAudioPatchListUpdate(); 258b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 259b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 26057dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent 26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::binderDied(const wp<IBinder>& who) { 262411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), 263de070137f11d346fba77605bd76a44c040a618fcEric Laurent IPCThreadState::self()->getCallingPid()); 26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 26565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 26665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex) 26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = false; 26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < kDumpLockRetries; ++i) { 27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mutex.tryLock() == NO_ERROR) { 27165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian locked = true; 27265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 27365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 27422ecc912a87099cff8cadc424cd12f85c118673fGlenn Kasten usleep(kDumpLockSleepUs); 27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 27665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return locked; 27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpInternals(int fd) 28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 28165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 285dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#ifdef USE_LEGACY_AUDIO_POLICY 286fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy); 287dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#else 288dce54a1492c410ad0d93253b341fb33305337505Eric Laurent snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager); 289dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#endif 29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 29165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); 29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); 29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3000f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused) 30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 30244deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten if (!dumpAllowed()) { 30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dumpPermissionDenial(fd); 30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = tryLock(mLock); 30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!locked) { 30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result(kDeadlockedString); 30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dumpInternals(fd); 3129d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten if (mAudioCommandThread != 0) { 31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommandThread->dump(fd); 31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 3159d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten if (mTonePlaybackThread != 0) { 31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mTonePlaybackThread->dump(fd); 31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 319dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#ifdef USE_LEGACY_AUDIO_POLICY 320fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mpAudioPolicy) { 321fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mpAudioPolicy->dump(mpAudioPolicy, fd); 32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 323dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#else 324dce54a1492c410ad0d93253b341fb33305337505Eric Laurent if (mAudioPolicyManager) { 325dce54a1492c410ad0d93253b341fb33305337505Eric Laurent mAudioPolicyManager->dump(fd); 326dce54a1492c410ad0d93253b341fb33305337505Eric Laurent } 327dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#endif 32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (locked) mLock.unlock(); 33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpPermissionDenial(int fd) 33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Permission Denial: " 34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian "can't dump AudioPolicyService from pid=%d, uid=%d\n", 34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState::self()->getCallingPid(), 34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState::self()->getCallingUid()); 34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 34665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::onTransact( 34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return BnAudioPolicyService::onTransact(code, data, reply, flags); 35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------- AudioPolicyService::AudioCommandThread implementation ---------- 35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 357bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name, 358bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent const wp<AudioPolicyService>& service) 359bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent : Thread(false), mName(name), mService(service) 36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = NULL; 36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioCommandThread::~AudioCommandThread() 36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 367bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (!mAudioCommands.isEmpty()) { 36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian release_wake_lock(mName.string()); 36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.clear(); 371e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten delete mpToneGenerator; 37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::onFirstRef() 37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 376bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent run(mName.string(), ANDROID_PRIORITY_AUDIO); 37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioPolicyService::AudioCommandThread::threadLoop() 38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian nsecs_t waitTime = INT64_MAX; 38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian while (!exitPending()) 38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 38659a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent sp<AudioPolicyService> svc; 38759a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent while (!mAudioCommands.isEmpty() && !exitPending()) { 38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian nsecs_t curTime = systemTime(); 38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // commands are sorted by increasing time stamp: execute them from index 0 and up 39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mAudioCommands[0]->mTime <= curTime) { 3910ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = mAudioCommands[0]; 39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.removeAt(0); 3930ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mLastCommand = command; 39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (command->mCommand) { 39665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case START_TONE: { 39765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 3980ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ToneData *data = (ToneData *)command->mParam.get(); 3993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing start tone %d on stream %d", 40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mType, data->mStream); 401e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten delete mpToneGenerator; 40265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = new ToneGenerator(data->mStream, 1.0); 40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator->startTone(data->mType); 40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case STOP_TONE: { 40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 4083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing stop tone"); 40965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mpToneGenerator != NULL) { 41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator->stopTone(); 41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian delete mpToneGenerator; 41265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = NULL; 41365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 41465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOLUME: { 4170ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data = (VolumeData *)command->mParam.get(); 4183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing set volume stream %d, \ 419de070137f11d346fba77605bd76a44c040a618fcEric Laurent volume %f, output %d", data->mStream, data->mVolume, data->mIO); 420de070137f11d346fba77605bd76a44c040a618fcEric Laurent command->mStatus = AudioSystem::setStreamVolume(data->mStream, 421de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mVolume, 422de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mIO); 42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_PARAMETERS: { 4250ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data = (ParametersData *)command->mParam.get(); 426e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten ALOGV("AudioCommandThread() processing set parameters string %s, io %d", 427e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten data->mKeyValuePairs.string(), data->mIO); 428e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); 429e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten }break; 43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOICE_VOLUME: { 4310ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 4323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing set voice volume volume %f", 433de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mVolume); 43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); 43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 436bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent case STOP_OUTPUT: { 4370ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent StopOutputData *data = (StopOutputData *)command->mParam.get(); 438bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() processing stop output %d", 439bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO); 44059a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 441bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (svc == 0) { 442bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 443bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 444bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 445bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent svc->doStopOutput(data->mIO, data->mStream, data->mSession); 446bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 447bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent }break; 448bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent case RELEASE_OUTPUT: { 4490ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get(); 450bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() processing release output %d", 451bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO); 45259a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 453bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (svc == 0) { 454bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 455bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 456bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 457bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent svc->doReleaseOutput(data->mIO); 458bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 459bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent }break; 460951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent case CREATE_AUDIO_PATCH: { 461951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get(); 462951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() processing create audio patch"); 463951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 464951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (af == 0) { 465951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = PERMISSION_DENIED; 466951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } else { 467951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle); 468951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 469951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } break; 470951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent case RELEASE_AUDIO_PATCH: { 471951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get(); 472951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() processing release audio patch"); 473951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 474951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (af == 0) { 475951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = PERMISSION_DENIED; 476951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } else { 477951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = af->releaseAudioPatch(data->mHandle); 478951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 479951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } break; 480b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent case UPDATE_AUDIOPORT_LIST: { 481b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() processing update audio port list"); 48259a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 483b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (svc == 0) { 484b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent break; 485b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 486b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.unlock(); 487b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent svc->doOnAudioPortListUpdate(); 488b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.lock(); 489b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent }break; 490b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent case UPDATE_AUDIOPATCH_LIST: { 491b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() processing update audio patch list"); 49259a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 493b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (svc == 0) { 494b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent break; 495b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 496b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.unlock(); 497b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent svc->doOnAudioPatchListUpdate(); 498b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.lock(); 499b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent }break; 500e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent case SET_AUDIOPORT_CONFIG: { 501e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get(); 502e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("AudioCommandThread() processing set port config"); 503e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 504e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (af == 0) { 505e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mStatus = PERMISSION_DENIED; 506e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 507e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mStatus = af->setAudioPortConfig(&data->mConfig); 508e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 509e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } break; 51065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 5115ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AudioCommandThread() unknown command %d", command->mCommand); 51265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 5130ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent { 5140ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(command->mLock); 5150ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (command->mWaitStatus) { 5160ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = false; 5170ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mCond.signal(); 5180ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 5190ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 52065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian waitTime = INT64_MAX; 52165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 52265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian waitTime = mAudioCommands[0]->mTime - curTime; 52365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 52465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 52565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 52659a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent // release mLock before releasing strong reference on the service as 52759a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent // AudioPolicyService destructor calls AudioCommandThread::exit() which acquires mLock. 52859a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent mLock.unlock(); 52959a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc.clear(); 53059a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent mLock.lock(); 53105f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia if (!exitPending() && mAudioCommands.isEmpty()) { 53205f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia // release delayed commands wake lock 53305f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia release_wake_lock(mName.string()); 53459a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent ALOGV("AudioCommandThread() going to sleep"); 53559a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent mWaitWorkCV.waitRelative(mLock, waitTime); 53659a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent ALOGV("AudioCommandThread() waking up"); 53759a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent } 53865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 53905f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia // release delayed commands wake lock before quitting 54005f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia if (!mAudioCommands.isEmpty()) { 54105f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia release_wake_lock(mName.string()); 54205f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia } 54365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 54465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return false; 54565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 54665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 54765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::dump(int fd) 54865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 54965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 55065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 55165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 55265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 55365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 55465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 55565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 55665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 55765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = tryLock(mLock); 55865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!locked) { 55965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result2(kCmdDeadlockedString); 56065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result2.string(), result2.size()); 56165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 56265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 56365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "- Commands:\n"); 56465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = String8(buffer); 56565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(" Command Time Wait pParam\n"); 5668d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten for (size_t i = 0; i < mAudioCommands.size(); i++) { 56765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands[i]->dump(buffer, SIZE); 56865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 56965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 57065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(" Last Command\n"); 5710ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (mLastCommand != 0) { 5720ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mLastCommand->dump(buffer, SIZE); 5730ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent result.append(buffer); 5740ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } else { 5750ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent result.append(" none\n"); 5760ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 57765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 57865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 57965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 58065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (locked) mLock.unlock(); 58165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 58265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 58365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 58465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5853d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kastenvoid AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type, 5863d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kasten audio_stream_type_t stream) 58765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 5880ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 58965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = START_TONE; 5900ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ToneData> data = new ToneData(); 59165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mType = type; 59265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mStream = stream; 59348412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 5943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 5950ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 59665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 59765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 59865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::stopToneCommand() 59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 6000ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 60165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = STOP_TONE; 6023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding tone stop"); 6030ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 60465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 60565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 606fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream, 607de070137f11d346fba77605bd76a44c040a618fcEric Laurent float volume, 60872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten audio_io_handle_t output, 609de070137f11d346fba77605bd76a44c040a618fcEric Laurent int delayMs) 61065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 6110ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 61265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_VOLUME; 6130ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<VolumeData> data = new VolumeData(); 61465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mStream = stream; 61565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mVolume = volume; 61665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mIO = output; 61765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 6180ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 6193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 620de070137f11d346fba77605bd76a44c040a618fcEric Laurent stream, volume, output); 6210ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 62265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 62365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 62472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle, 625fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin const char *keyValuePairs, 626de070137f11d346fba77605bd76a44c040a618fcEric Laurent int delayMs) 62765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 6280ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 62965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_PARAMETERS; 6300ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ParametersData> data = new ParametersData(); 63165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mIO = ioHandle; 632fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin data->mKeyValuePairs = String8(keyValuePairs); 63365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 6340ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 6353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 636fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin keyValuePairs, ioHandle, delayMs); 6370ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 63865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 63965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 64065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 6420ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_VOICE_VOLUME; 6440ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<VoiceVolumeData> data = new VoiceVolumeData(); 64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mVolume = volume; 64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 6470ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 6483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set voice volume volume %f", volume); 6490ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 65165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 652bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output, 653bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent audio_stream_type_t stream, 654bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent int session) 655bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 6560ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 657bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent command->mCommand = STOP_OUTPUT; 6580ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<StopOutputData> data = new StopOutputData(); 659bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO = output; 660bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mStream = stream; 661bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mSession = session; 66248412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 663bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() adding stop output %d", output); 6640ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 665bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 666bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 667bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output) 668bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 6690ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 670bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent command->mCommand = RELEASE_OUTPUT; 6710ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ReleaseOutputData> data = new ReleaseOutputData(); 672bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO = output; 67348412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 674bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() adding release output %d", output); 6750ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 6760ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent} 6770ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent 678951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand( 679951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent const struct audio_patch *patch, 680951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent audio_patch_handle_t *handle, 681951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent int delayMs) 682951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{ 683951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent status_t status = NO_ERROR; 684951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 685951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<AudioCommand> command = new AudioCommand(); 686951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mCommand = CREATE_AUDIO_PATCH; 687951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent CreateAudioPatchData *data = new CreateAudioPatchData(); 688951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mPatch = *patch; 689951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mHandle = *handle; 690951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mParam = data; 691951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mWaitStatus = true; 692951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() adding create patch delay %d", delayMs); 693951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent status = sendCommand(command, delayMs); 694951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (status == NO_ERROR) { 695951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent *handle = data->mHandle; 696951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 697951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent return status; 698951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent} 699951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 700951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle, 701951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent int delayMs) 702951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{ 703951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<AudioCommand> command = new AudioCommand(); 704951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mCommand = RELEASE_AUDIO_PATCH; 705951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ReleaseAudioPatchData *data = new ReleaseAudioPatchData(); 706951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mHandle = handle; 707951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mParam = data; 708951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mWaitStatus = true; 709951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() adding release patch delay %d", delayMs); 710951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent return sendCommand(command, delayMs); 711951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent} 712951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 713b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPortListCommand() 714b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 715b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<AudioCommand> command = new AudioCommand(); 716b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent command->mCommand = UPDATE_AUDIOPORT_LIST; 717b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() adding update audio port list"); 718b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sendCommand(command); 719b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 720b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 721b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand() 722b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 723b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<AudioCommand>command = new AudioCommand(); 724b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent command->mCommand = UPDATE_AUDIOPATCH_LIST; 725b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() adding update audio patch list"); 726b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sendCommand(command); 727b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 728b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 729e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand( 730e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent const struct audio_port_config *config, int delayMs) 731e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{ 732e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent sp<AudioCommand> command = new AudioCommand(); 733e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mCommand = SET_AUDIOPORT_CONFIG; 734e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent SetAudioPortConfigData *data = new SetAudioPortConfigData(); 735e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent data->mConfig = *config; 736e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mParam = data; 737e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mWaitStatus = true; 738e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("AudioCommandThread() adding set port config delay %d", delayMs); 739e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return sendCommand(command, delayMs); 740e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent} 741e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 7420ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatus_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) 7430ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent{ 7440ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent { 7450ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(mLock); 7460ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent insertCommand_l(command, delayMs); 7470ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mWaitWorkCV.signal(); 7480ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 7490ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(command->mLock); 7500ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent while (command->mWaitStatus) { 7510ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs); 7520ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) { 7530ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mStatus = TIMED_OUT; 7540ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = false; 7550ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 7560ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 7570ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return command->mStatus; 758bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 759bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 76065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// insertCommand_l() must be called with mLock held 7610ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentvoid AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs) 76265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 7638d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten ssize_t i; // not size_t because i will count down to -1 7640ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Vector < sp<AudioCommand> > removedCommands; 76565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mTime = systemTime() + milliseconds(delayMs); 76665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 76765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // acquire wake lock to make sure delayed commands are processed 768bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mAudioCommands.isEmpty()) { 76965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 77065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 77165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 77265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // check same pending commands with later time stamps and eliminate them 77365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (i = mAudioCommands.size()-1; i >= 0; i--) { 7740ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command2 = mAudioCommands[i]; 77565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 77665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (command2->mTime <= command->mTime) break; 777e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 778e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // create audio patch or release audio patch commands are equivalent 779e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // with regard to filtering 780e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if ((command->mCommand == CREATE_AUDIO_PATCH) || 781e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command->mCommand == RELEASE_AUDIO_PATCH)) { 782e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if ((command2->mCommand != CREATE_AUDIO_PATCH) && 783e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command2->mCommand != RELEASE_AUDIO_PATCH)) { 784e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent continue; 785e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 786e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else if (command2->mCommand != command->mCommand) continue; 78765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 78865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (command->mCommand) { 78965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_PARAMETERS: { 7900ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data = (ParametersData *)command->mParam.get(); 7910ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data2 = (ParametersData *)command2->mParam.get(); 79265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mIO != data2->mIO) break; 7933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Comparing parameter command %s to new command %s", 794de070137f11d346fba77605bd76a44c040a618fcEric Laurent data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 79565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioParameter param = AudioParameter(data->mKeyValuePairs); 79665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 79765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t j = 0; j < param.size(); j++) { 798e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 key; 799e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 value; 800e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param.getAt(j, key, value); 801e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten for (size_t k = 0; k < param2.size(); k++) { 802e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 key2; 803e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 value2; 804e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param2.getAt(k, key2, value2); 805e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten if (key2 == key) { 806e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param2.remove(key2); 807e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten ALOGV("Filtering out parameter %s", key2.string()); 808e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten break; 809e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 810e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 81165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 81265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // if all keys have been filtered out, remove the command. 81365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // otherwise, update the key value pairs 81465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (param2.size() == 0) { 81565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.add(command2); 81665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 81765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data2->mKeyValuePairs = param2.toString(); 81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 81921e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent command->mTime = command2->mTime; 82021e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // force delayMs to non 0 so that code below does not request to wait for 82121e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // command status as the command is now delayed 82221e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent delayMs = 1; 82365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } break; 82465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 82565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOLUME: { 8260ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data = (VolumeData *)command->mParam.get(); 8270ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data2 = (VolumeData *)command2->mParam.get(); 82865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mIO != data2->mIO) break; 82965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mStream != data2->mStream) break; 8303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Filtering out volume command on output %d for stream %d", 831de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mIO, data->mStream); 83265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.add(command2); 83321e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent command->mTime = command2->mTime; 83421e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // force delayMs to non 0 so that code below does not request to wait for 83521e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // command status as the command is now delayed 83621e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent delayMs = 1; 83765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } break; 838e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 839e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent case CREATE_AUDIO_PATCH: 840e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent case RELEASE_AUDIO_PATCH: { 841e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent audio_patch_handle_t handle; 842e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (command->mCommand == CREATE_AUDIO_PATCH) { 843e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle; 844e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else { 845e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle; 846e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 847e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent audio_patch_handle_t handle2; 848e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (command2->mCommand == CREATE_AUDIO_PATCH) { 849e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle; 850e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else { 851e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle; 852e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 853e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (handle != handle2) break; 854e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent ALOGV("Filtering out %s audio patch command for handle %d", 855e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle); 856e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent removedCommands.add(command2); 857e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent command->mTime = command2->mTime; 858e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // force delayMs to non 0 so that code below does not request to wait for 859e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // command status as the command is now delayed 860e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent delayMs = 1; 861e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } break; 862e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 86365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case START_TONE: 86465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case STOP_TONE: 86565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 86665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 86765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 86865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 86965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 87065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // remove filtered commands 87165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t j = 0; j < removedCommands.size(); j++) { 87265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // removed commands always have time stamps greater than current command 87365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 8740ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (mAudioCommands[k].get() == removedCommands[j].get()) { 8753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 87665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.removeAt(k); 87765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 87865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 87965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 88065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 88165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.clear(); 88265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 8830ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent // Disable wait for status if delay is not 0 8840ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (delayMs != 0) { 885cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent command->mWaitStatus = false; 886cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent } 887cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent 88865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // insert command at the right place according to its time stamp 8891e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ALOGV("inserting command: %d at index %zd, num commands %zu", 8901e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent command->mCommand, i+1, mAudioCommands.size()); 89165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.insertAt(command, i + 1); 89265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 89365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 89465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::exit() 89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 8963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread::exit"); 89765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 89865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AutoMutex _l(mLock); 89965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian requestExit(); 90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mWaitWorkCV.signal(); 90165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 90265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian requestExitAndWait(); 90365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 90465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 90565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 90665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 90765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 90865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCommand, 90965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian (int)ns2s(mTime), 91065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian (int)ns2ms(mTime)%1000, 91165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mWaitStatus, 9120ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mParam.get()); 91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 915fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin/******* helpers for the service_ops callbacks defined below *********/ 916fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 917fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin const char *keyValuePairs, 918fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int delayMs) 919fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 92072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs, 921fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin delayMs); 922fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 923fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 924fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setStreamVolume(audio_stream_type_t stream, 925fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin float volume, 926fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t output, 927fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int delayMs) 928fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 929fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten return (int)mAudioCommandThread->volumeCommand(stream, volume, 93072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten output, delayMs); 931fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 932fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 933fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::startTone(audio_policy_tone_t tone, 934fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_stream_type_t stream) 935fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 9366e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) { 93729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("startTone: illegal tone requested (%d)", tone); 9386e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 9396e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (stream != AUDIO_STREAM_VOICE_CALL) { 94029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("startTone: illegal stream (%d) requested for tone %d", stream, 941e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten tone); 9426e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 943fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING, 944fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin AUDIO_STREAM_VOICE_CALL); 945fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return 0; 946fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 947fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 948fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::stopTone() 949fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 950fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mTonePlaybackThread->stopToneCommand(); 951fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return 0; 952fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 953fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 954fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setVoiceVolume(float volume, int delayMs) 955fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 956fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 957fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 958fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 959fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinextern "C" { 9602d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_module_handle_t aps_load_hw_module(void *service __unused, 9612d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *name); 9622d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output(void *service __unused, 963a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 964a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 965a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 966a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 967a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pLatencyMs, 9682d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_output_flags_t flags); 969fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 9702d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output_on_module(void *service __unused, 971a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_module_handle_t module, 972a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 973a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 974a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 975a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 976a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pLatencyMs, 977ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald audio_output_flags_t flags, 9782d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const audio_offload_info_t *offloadInfo); 9792d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_dup_output(void *service __unused, 980fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t output1, 9812d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_io_handle_t output2); 9822d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_output(void *service __unused, audio_io_handle_t output); 9832d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_suspend_output(void *service __unused, audio_io_handle_t output); 9842d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_restore_output(void *service __unused, audio_io_handle_t output); 9852d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input(void *service __unused, 986a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 987a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 988a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 989a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 9902d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_in_acoustics_t acoustics __unused); 9912d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input_on_module(void *service __unused, 992a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_module_handle_t module, 993a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 994a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 995a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 9962d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_channel_mask_t *pChannelMask); 9972d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_input(void *service __unused, audio_io_handle_t input); 9982d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_invalidate_stream(void *service __unused, audio_stream_type_t stream); 9992d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_move_effects(void *service __unused, int session, 1000fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t src_output, 10012d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_io_handle_t dst_output); 10022d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentchar * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle, 10032d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *keys); 10042d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentvoid aps_set_parameters(void *service, audio_io_handle_t io_handle, 10052d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *kv_pairs, int delay_ms); 10062d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_stream_volume(void *service, audio_stream_type_t stream, 1007fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin float volume, audio_io_handle_t output, 10082d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent int delay_ms); 10092d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_start_tone(void *service, audio_policy_tone_t tone, 10102d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_stream_type_t stream); 10112d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_stop_tone(void *service); 10122d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_voice_volume(void *service, float volume, int delay_ms); 10132d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent}; 1014fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1015fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinnamespace { 1016fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin struct audio_policy_service_ops aps_ops = { 101701d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .open_output = aps_open_output, 101801d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .open_duplicate_output = aps_open_dup_output, 101901d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .close_output = aps_close_output, 102001d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .suspend_output = aps_suspend_output, 102101d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .restore_output = aps_restore_output, 102201d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .open_input = aps_open_input, 102301d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .close_input = aps_close_input, 102401d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .set_stream_volume = aps_set_stream_volume, 1025d2304db2fcb5112292105a0949a55986a4c9875fGlenn Kasten .invalidate_stream = aps_invalidate_stream, 102601d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .set_parameters = aps_set_parameters, 102701d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .get_parameters = aps_get_parameters, 102801d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .start_tone = aps_start_tone, 102901d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .stop_tone = aps_stop_tone, 103001d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .set_voice_volume = aps_set_voice_volume, 103101d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .move_effects = aps_move_effects, 103201d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .load_hw_module = aps_load_hw_module, 103301d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .open_output_on_module = aps_open_output_on_module, 103401d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .open_input_on_module = aps_open_input_on_module, 1035fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin }; 1036fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}; // namespace <unnamed> 1037fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android 1039