AudioPolicyService.cpp revision ac4e42982d4537732b30e71c9a00ba0077944984
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> 37c84d9d235679a4d48245b316b7b2e4c0b19413e7Chih-Hung Hsieh#include <media/AudioParameter.h> 3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3964760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h> 407394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin#include <system/audio_policy.h> 4161a4fac2e3ec271241e3a4f405d7357b7f6ca4c2Mikhail Naganov 4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android { 4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 448dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n"; 458dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n"; 4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50; 4822ecc912a87099cff8cadc424cd12f85c118673fGlenn Kastenstatic const int kDumpLockSleepUs = 20000; 4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 500ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatic const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds 515fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher 52fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioPolicyService() 56dce54a1492c410ad0d93253b341fb33305337505Eric Laurent : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL), 57bb6c9a05840d924b502ce0f1868fca4881ada1edEric Laurent mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID) 5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 59f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent} 60f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent 61f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurentvoid AudioPolicyService::onFirstRef() 62f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent{ 638b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent { 648b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 65935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent 668b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start tone playback thread 678b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this); 688b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start audio commands thread 698b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this); 708b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start output activity command thread 718b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this); 72dce54a1492c410ad0d93253b341fb33305337505Eric Laurent 738b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyClient = new AudioPolicyClient(this); 748b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); 758b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 76ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // load audio processing modules 778b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects(); 788b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent { 798b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 808b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyEffects = audioPolicyEffects; 818b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 8265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 8365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 8465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::~AudioPolicyService() 8565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 8665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mTonePlaybackThread->exit(); 8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommandThread->exit(); 88657ff61389d7316f798d4abe03efac56fd528d91Eric Laurent mOutputCommandThread->exit(); 897c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent 90f269b8e0e9ab950fc6652b9594b7a3431c81630cEric Laurent destroyAudioPolicyManager(mAudioPolicyManager); 91dce54a1492c410ad0d93253b341fb33305337505Eric Laurent delete mAudioPolicyClient; 92b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 93b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.clear(); 94ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mAudioPolicyEffects.clear(); 95b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 96b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 97b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// A notification client is always registered by AudioSystem when the client process 98b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// connects to AudioPolicyService. 99b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client) 100b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 101125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent if (client == 0) { 102125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent ALOGW("%s got NULL client", __FUNCTION__); 103125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent return; 104125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent } 1050ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 106b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 107b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid_t uid = IPCThreadState::self()->getCallingUid(); 108b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (mNotificationClients.indexOfKey(uid) < 0) { 109b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<NotificationClient> notificationClient = new NotificationClient(this, 110b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent client, 111b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid); 112b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("registerClient() client %p, uid %d", client.get(), uid); 113b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 114b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.add(uid, notificationClient); 115b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 116f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen sp<IBinder> binder = IInterface::asBinder(client); 117b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent binder->linkToDeath(notificationClient); 118b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 119b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 120b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 121e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurentvoid AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled) 122e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent{ 123e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent Mutex::Autolock _l(mNotificationClientsLock); 124e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 125e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent uid_t uid = IPCThreadState::self()->getCallingUid(); 126e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (mNotificationClients.indexOfKey(uid) < 0) { 127e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent return; 128e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent } 129e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled); 130e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent} 131e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 132b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// removeNotificationClient() is called when the client process dies. 133b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::removeNotificationClient(uid_t uid) 134b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 1350ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent { 1360ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 1370ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent mNotificationClients.removeItem(uid); 1380ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent } 1390ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent { 1400ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mLock); 141b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (mAudioPolicyManager) { 1428c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent mAudioPolicyManager->releaseResourcesForUid(uid); 143b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 1440ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent } 145b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 146b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 147b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPortListUpdate() 148b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 149b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mOutputCommandThread->updateAudioPortListCommand(); 150b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 151b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 152b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPortListUpdate() 153b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 1540ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 155b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent for (size_t i = 0; i < mNotificationClients.size(); i++) { 156b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.valueAt(i)->onAudioPortListUpdate(); 157b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 158b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 159b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 160b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPatchListUpdate() 161b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 162b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mOutputCommandThread->updateAudioPatchListCommand(); 16365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 16465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 165b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPatchListUpdate() 166b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 1670ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 168b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent for (size_t i = 0; i < mNotificationClients.size(); i++) { 169b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.valueAt(i)->onAudioPatchListUpdate(); 170b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 171b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 172b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 173e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state) 174de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 175de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)", 176de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi regId.string(), state); 177de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state); 178de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 179de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 180e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state) 181de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 182de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi Mutex::Autolock _l(mNotificationClientsLock); 183de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi for (size_t i = 0; i < mNotificationClients.size(); i++) { 184de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state); 185de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 186de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 187de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 188ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivivoid AudioPolicyService::onRecordingConfigurationUpdate(int event, 189ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig, 1908c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) 1912f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 192ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo, 1938c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi clientConfig, deviceConfig, patchHandle); 1942f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 1952f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 196ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivivoid AudioPolicyService::doOnRecordingConfigurationUpdate(int event, 197ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig, 1988c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) 1992f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 2002f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi Mutex::Autolock _l(mNotificationClientsLock); 2012f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi for (size_t i = 0; i < mNotificationClients.size(); i++) { 202ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo, 2038c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi clientConfig, deviceConfig, patchHandle); 2042f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } 2052f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2062f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 2072f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivistatus_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch, 2082f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi audio_patch_handle_t *handle, 2092f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi int delayMs) 2102f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 2112f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs); 2122f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2132f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 2142f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivistatus_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle, 2152f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi int delayMs) 2162f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 2172f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs); 2182f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2192f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 220e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config, 221e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent int delayMs) 222e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{ 223e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); 224e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent} 225e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 226b52c152d553556b2d227ffc943489de0c60b4b02Eric LaurentAudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service, 227b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent const sp<IAudioPolicyServiceClient>& client, 228b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid_t uid) 229e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent : mService(service), mUid(uid), mAudioPolicyServiceClient(client), 230e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mAudioPortCallbacksEnabled(false) 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{ 249e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 250b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mAudioPolicyServiceClient->onAudioPortListUpdate(); 251b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 252b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 253b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 254b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::onAudioPatchListUpdate() 255b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 256e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 257b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mAudioPolicyServiceClient->onAudioPatchListUpdate(); 258b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 259b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 26057dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent 261de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivivoid AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( 262e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const String8& regId, int32_t state) 263de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 264de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi if (mAudioPolicyServiceClient != 0) { 2652f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state); 2662f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } 2672f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2682f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 2692f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate( 270ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi int event, const record_client_info_t *clientInfo, 2718c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, 2728c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi audio_patch_handle_t patchHandle) 2732f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 2742f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi if (mAudioPolicyServiceClient != 0) { 275ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo, 2768c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi clientConfig, deviceConfig, patchHandle); 277de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 278de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 279de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 280e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurentvoid AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled) 281e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent{ 282e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mAudioPortCallbacksEnabled = enabled; 283e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent} 284e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 285e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::binderDied(const wp<IBinder>& who) { 287411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), 288de070137f11d346fba77605bd76a44c040a618fcEric Laurent IPCThreadState::self()->getCallingPid()); 28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 29165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex) 29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = false; 29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < kDumpLockRetries; ++i) { 29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mutex.tryLock() == NO_ERROR) { 29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian locked = true; 29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 29922ecc912a87099cff8cadc424cd12f85c118673fGlenn Kasten usleep(kDumpLockSleepUs); 30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return locked; 30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpInternals(int fd) 30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 310dce54a1492c410ad0d93253b341fb33305337505Eric Laurent snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager); 31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); 31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); 31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3210f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused) 32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 32344deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten if (!dumpAllowed()) { 32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dumpPermissionDenial(fd); 32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = tryLock(mLock); 32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!locked) { 32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result(kDeadlockedString); 32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dumpInternals(fd); 3339d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten if (mAudioCommandThread != 0) { 33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommandThread->dump(fd); 33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 3369d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten if (mTonePlaybackThread != 0) { 33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mTonePlaybackThread->dump(fd); 33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 340dce54a1492c410ad0d93253b341fb33305337505Eric Laurent if (mAudioPolicyManager) { 341dce54a1492c410ad0d93253b341fb33305337505Eric Laurent mAudioPolicyManager->dump(fd); 342dce54a1492c410ad0d93253b341fb33305337505Eric Laurent } 34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (locked) mLock.unlock(); 34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 34665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpPermissionDenial(int fd) 35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Permission Denial: " 35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian "can't dump AudioPolicyService from pid=%d, uid=%d\n", 35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState::self()->getCallingPid(), 35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState::self()->getCallingUid()); 35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::onTransact( 36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return BnAudioPolicyService::onTransact(code, data, reply, flags); 36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------- AudioPolicyService::AudioCommandThread implementation ---------- 37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 372bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name, 373bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent const wp<AudioPolicyService>& service) 374bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent : Thread(false), mName(name), mService(service) 37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = NULL; 37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioCommandThread::~AudioCommandThread() 38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 382bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (!mAudioCommands.isEmpty()) { 38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian release_wake_lock(mName.string()); 38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.clear(); 386e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten delete mpToneGenerator; 38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::onFirstRef() 39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 391bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent run(mName.string(), ANDROID_PRIORITY_AUDIO); 39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 39365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioPolicyService::AudioCommandThread::threadLoop() 39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 396d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent nsecs_t waitTime = -1; 39765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 39865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 39965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian while (!exitPending()) 40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 40159a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent sp<AudioPolicyService> svc; 40259a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent while (!mAudioCommands.isEmpty() && !exitPending()) { 40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian nsecs_t curTime = systemTime(); 40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // commands are sorted by increasing time stamp: execute them from index 0 and up 40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mAudioCommands[0]->mTime <= curTime) { 4060ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = mAudioCommands[0]; 40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.removeAt(0); 4080ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mLastCommand = command; 40965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (command->mCommand) { 41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case START_TONE: { 41265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 4130ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ToneData *data = (ToneData *)command->mParam.get(); 4143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing start tone %d on stream %d", 41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mType, data->mStream); 416e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten delete mpToneGenerator; 41765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = new ToneGenerator(data->mStream, 1.0); 41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator->startTone(data->mType); 41965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case STOP_TONE: { 42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 4233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing stop tone"); 42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mpToneGenerator != NULL) { 42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator->stopTone(); 42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian delete mpToneGenerator; 42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = NULL; 42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 43165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOLUME: { 4320ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data = (VolumeData *)command->mParam.get(); 4333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing set volume stream %d, \ 434de070137f11d346fba77605bd76a44c040a618fcEric Laurent volume %f, output %d", data->mStream, data->mVolume, data->mIO); 435de070137f11d346fba77605bd76a44c040a618fcEric Laurent command->mStatus = AudioSystem::setStreamVolume(data->mStream, 436de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mVolume, 437de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mIO); 43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 43965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_PARAMETERS: { 4400ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data = (ParametersData *)command->mParam.get(); 441e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten ALOGV("AudioCommandThread() processing set parameters string %s, io %d", 442e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten data->mKeyValuePairs.string(), data->mIO); 443e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); 444e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten }break; 44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOICE_VOLUME: { 4460ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 4473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing set voice volume volume %f", 448de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mVolume); 44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); 45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 451bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent case STOP_OUTPUT: { 4520ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent StopOutputData *data = (StopOutputData *)command->mParam.get(); 453bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() processing stop output %d", 454bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO); 45559a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 456bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (svc == 0) { 457bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 458bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 459bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 460bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent svc->doStopOutput(data->mIO, data->mStream, data->mSession); 461bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 462bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent }break; 463bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent case RELEASE_OUTPUT: { 4640ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get(); 465bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() processing release output %d", 466bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO); 46759a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 468bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (svc == 0) { 469bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 470bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 471bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 472e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent svc->doReleaseOutput(data->mIO, data->mStream, data->mSession); 473bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 474bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent }break; 475951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent case CREATE_AUDIO_PATCH: { 476951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get(); 477951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() processing create audio patch"); 478951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 479951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (af == 0) { 480951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = PERMISSION_DENIED; 481951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } else { 482951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle); 483951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 484951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } break; 485951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent case RELEASE_AUDIO_PATCH: { 486951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get(); 487951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() processing release audio patch"); 488951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 489951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (af == 0) { 490951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = PERMISSION_DENIED; 491951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } else { 492951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = af->releaseAudioPatch(data->mHandle); 493951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 494951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } break; 495b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent case UPDATE_AUDIOPORT_LIST: { 496b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() processing update audio port list"); 49759a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 498b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (svc == 0) { 499b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent break; 500b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 501b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.unlock(); 502b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent svc->doOnAudioPortListUpdate(); 503b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.lock(); 504b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent }break; 505b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent case UPDATE_AUDIOPATCH_LIST: { 506b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() processing update audio patch list"); 50759a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 508b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (svc == 0) { 509b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent break; 510b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 511b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.unlock(); 512b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent svc->doOnAudioPatchListUpdate(); 513b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.lock(); 514b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent }break; 515e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent case SET_AUDIOPORT_CONFIG: { 516e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get(); 517e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("AudioCommandThread() processing set port config"); 518e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 519e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (af == 0) { 520e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mStatus = PERMISSION_DENIED; 521e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 522e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mStatus = af->setAudioPortConfig(&data->mConfig); 523e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 524e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } break; 525de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi case DYN_POLICY_MIX_STATE_UPDATE: { 526de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi DynPolicyMixStateUpdateData *data = 527de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi (DynPolicyMixStateUpdateData *)command->mParam.get(); 528de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d", 529de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi data->mRegId.string(), data->mState); 530de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi svc = mService.promote(); 531de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi if (svc == 0) { 532de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi break; 533de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 534de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mLock.unlock(); 535de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState); 536de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mLock.lock(); 537de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } break; 5382f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi case RECORDING_CONFIGURATION_UPDATE: { 5392f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi RecordingConfigurationUpdateData *data = 5402f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi (RecordingConfigurationUpdateData *)command->mParam.get(); 5412f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi ALOGV("AudioCommandThread() processing recording configuration update"); 5422f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi svc = mService.promote(); 5432f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi if (svc == 0) { 5442f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi break; 5452f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } 5462f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi mLock.unlock(); 547ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo, 548ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi &data->mClientConfig, &data->mDeviceConfig, 5498c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi data->mPatchHandle); 5502f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi mLock.lock(); 5512f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } break; 55265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 5535ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AudioCommandThread() unknown command %d", command->mCommand); 55465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 5550ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent { 5560ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(command->mLock); 5570ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (command->mWaitStatus) { 5580ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = false; 5590ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mCond.signal(); 5600ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 5610ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 562d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent waitTime = -1; 563a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // release mLock before releasing strong reference on the service as 564a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // AudioPolicyService destructor calls AudioCommandThread::exit() which 565a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // acquires mLock. 566a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang mLock.unlock(); 567a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang svc.clear(); 568a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang mLock.lock(); 56965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 57065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian waitTime = mAudioCommands[0]->mTime - curTime; 57165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 57265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 57365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 574a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang 575a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // release delayed commands wake lock if the queue is empty 576a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang if (mAudioCommands.isEmpty()) { 57705f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia release_wake_lock(mName.string()); 578a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang } 579a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang 580a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // At this stage we have either an empty command queue or the first command in the queue 581a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // has a finite delay. So unless we are exiting it is safe to wait. 582a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang if (!exitPending()) { 58359a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent ALOGV("AudioCommandThread() going to sleep"); 584d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent if (waitTime == -1) { 585d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent mWaitWorkCV.wait(mLock); 586d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent } else { 587d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent mWaitWorkCV.waitRelative(mLock, waitTime); 588d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent } 58959a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent } 59065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 59105f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia // release delayed commands wake lock before quitting 59205f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia if (!mAudioCommands.isEmpty()) { 59305f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia release_wake_lock(mName.string()); 59405f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia } 59565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 59665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return false; 59765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 59865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::dump(int fd) 60065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 60165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 60265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 60365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 60465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 60565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 60665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 60765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 60865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 60965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = tryLock(mLock); 61065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!locked) { 61165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result2(kCmdDeadlockedString); 61265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result2.string(), result2.size()); 61365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 61465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 61565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "- Commands:\n"); 61665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = String8(buffer); 61765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(" Command Time Wait pParam\n"); 6188d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten for (size_t i = 0; i < mAudioCommands.size(); i++) { 61965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands[i]->dump(buffer, SIZE); 62065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 62165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 62265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(" Last Command\n"); 6230ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (mLastCommand != 0) { 6240ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mLastCommand->dump(buffer, SIZE); 6250ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent result.append(buffer); 6260ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } else { 6270ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent result.append(" none\n"); 6280ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 62965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 63065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 63165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 63265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (locked) mLock.unlock(); 63365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 63465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 63565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6373d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kastenvoid AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type, 6383d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kasten audio_stream_type_t stream) 63965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 6400ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = START_TONE; 6420ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ToneData> data = new ToneData(); 64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mType = type; 64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mStream = stream; 64548412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 6463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 6470ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 64865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 64965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::stopToneCommand() 65165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 6520ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = STOP_TONE; 6543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding tone stop"); 6550ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 65765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 658fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream, 659de070137f11d346fba77605bd76a44c040a618fcEric Laurent float volume, 66072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten audio_io_handle_t output, 661de070137f11d346fba77605bd76a44c040a618fcEric Laurent int delayMs) 66265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 6630ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_VOLUME; 6650ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<VolumeData> data = new VolumeData(); 66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mStream = stream; 66765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mVolume = volume; 66865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mIO = output; 66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 6700ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 6713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 672de070137f11d346fba77605bd76a44c040a618fcEric Laurent stream, volume, output); 6730ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 67672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle, 677fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin const char *keyValuePairs, 678de070137f11d346fba77605bd76a44c040a618fcEric Laurent int delayMs) 67965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 6800ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_PARAMETERS; 6820ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ParametersData> data = new ParametersData(); 68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mIO = ioHandle; 684fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin data->mKeyValuePairs = String8(keyValuePairs); 68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 6860ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 6873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 688fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin keyValuePairs, ioHandle, delayMs); 6890ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 69165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 6940ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_VOICE_VOLUME; 6960ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<VoiceVolumeData> data = new VoiceVolumeData(); 69765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mVolume = volume; 69865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 6990ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 7003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set voice volume volume %f", volume); 7010ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 70265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 70365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 704bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output, 705bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent audio_stream_type_t stream, 706e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_session_t session) 707bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 7080ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 709bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent command->mCommand = STOP_OUTPUT; 7100ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<StopOutputData> data = new StopOutputData(); 711bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO = output; 712bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mStream = stream; 713bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mSession = session; 71448412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 715bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() adding stop output %d", output); 7160ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 717bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 718bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 719e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentvoid AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output, 720e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_stream_type_t stream, 721e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_session_t session) 722bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 7230ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 724bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent command->mCommand = RELEASE_OUTPUT; 7250ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ReleaseOutputData> data = new ReleaseOutputData(); 726bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO = output; 727e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent data->mStream = stream; 728e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent data->mSession = session; 72948412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 730bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() adding release output %d", output); 7310ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 7320ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent} 7330ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent 734951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand( 735951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent const struct audio_patch *patch, 736951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent audio_patch_handle_t *handle, 737951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent int delayMs) 738951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{ 739951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent status_t status = NO_ERROR; 740951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 741951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<AudioCommand> command = new AudioCommand(); 742951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mCommand = CREATE_AUDIO_PATCH; 743951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent CreateAudioPatchData *data = new CreateAudioPatchData(); 744951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mPatch = *patch; 745951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mHandle = *handle; 746951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mParam = data; 747951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mWaitStatus = true; 748951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() adding create patch delay %d", delayMs); 749951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent status = sendCommand(command, delayMs); 750951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (status == NO_ERROR) { 751951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent *handle = data->mHandle; 752951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 753951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent return status; 754951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent} 755951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 756951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle, 757951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent int delayMs) 758951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{ 759951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<AudioCommand> command = new AudioCommand(); 760951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mCommand = RELEASE_AUDIO_PATCH; 761951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ReleaseAudioPatchData *data = new ReleaseAudioPatchData(); 762951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mHandle = handle; 763951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mParam = data; 764951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mWaitStatus = true; 765951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() adding release patch delay %d", delayMs); 766951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent return sendCommand(command, delayMs); 767951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent} 768951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 769b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPortListCommand() 770b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 771b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<AudioCommand> command = new AudioCommand(); 772b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent command->mCommand = UPDATE_AUDIOPORT_LIST; 773b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() adding update audio port list"); 774b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sendCommand(command); 775b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 776b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 777b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand() 778b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 779b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<AudioCommand>command = new AudioCommand(); 780b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent command->mCommand = UPDATE_AUDIOPATCH_LIST; 781b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() adding update audio patch list"); 782b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sendCommand(command); 783b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 784b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 785e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand( 786e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent const struct audio_port_config *config, int delayMs) 787e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{ 788e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent sp<AudioCommand> command = new AudioCommand(); 789e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mCommand = SET_AUDIOPORT_CONFIG; 790e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent SetAudioPortConfigData *data = new SetAudioPortConfigData(); 791e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent data->mConfig = *config; 792e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mParam = data; 793e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mWaitStatus = true; 794e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("AudioCommandThread() adding set port config delay %d", delayMs); 795e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return sendCommand(command, delayMs); 796e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent} 797e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 798de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivivoid AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( 799e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const String8& regId, int32_t state) 800de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 801de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi sp<AudioCommand> command = new AudioCommand(); 802de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi command->mCommand = DYN_POLICY_MIX_STATE_UPDATE; 803de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData(); 804de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi data->mRegId = regId; 805de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi data->mState = state; 806de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi command->mParam = data; 807de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d", 808de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi regId.string(), state); 809de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi sendCommand(command); 810de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 811de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 8122f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand( 813ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi int event, const record_client_info_t *clientInfo, 8148c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, 8158c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi audio_patch_handle_t patchHandle) 8162f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 8172f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi sp<AudioCommand>command = new AudioCommand(); 8182f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi command->mCommand = RECORDING_CONFIGURATION_UPDATE; 8192f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData(); 8202f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi data->mEvent = event; 821ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi data->mClientInfo = *clientInfo; 8227281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi data->mClientConfig = *clientConfig; 8237281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi data->mDeviceConfig = *deviceConfig; 8248c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi data->mPatchHandle = patchHandle; 8252f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi command->mParam = data; 826ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u", 827ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi event, clientInfo->source, clientInfo->uid); 8282f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi sendCommand(command); 8292f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 8302f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 8310ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatus_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) 8320ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent{ 8330ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent { 8340ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(mLock); 8350ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent insertCommand_l(command, delayMs); 8360ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mWaitWorkCV.signal(); 8370ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 8380ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(command->mLock); 8390ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent while (command->mWaitStatus) { 8400ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs); 8410ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) { 8420ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mStatus = TIMED_OUT; 8430ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = false; 8440ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 8450ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 8460ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return command->mStatus; 847bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 848bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 84965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// insertCommand_l() must be called with mLock held 8500ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentvoid AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs) 85165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 8528d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten ssize_t i; // not size_t because i will count down to -1 8530ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Vector < sp<AudioCommand> > removedCommands; 85465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mTime = systemTime() + milliseconds(delayMs); 85565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 85665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // acquire wake lock to make sure delayed commands are processed 857bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mAudioCommands.isEmpty()) { 85865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 85965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 86065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 86165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // check same pending commands with later time stamps and eliminate them 86265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (i = mAudioCommands.size()-1; i >= 0; i--) { 8630ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command2 = mAudioCommands[i]; 86465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 86565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (command2->mTime <= command->mTime) break; 866e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 867e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // create audio patch or release audio patch commands are equivalent 868e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // with regard to filtering 869e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if ((command->mCommand == CREATE_AUDIO_PATCH) || 870e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command->mCommand == RELEASE_AUDIO_PATCH)) { 871e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if ((command2->mCommand != CREATE_AUDIO_PATCH) && 872e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command2->mCommand != RELEASE_AUDIO_PATCH)) { 873e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent continue; 874e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 875e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else if (command2->mCommand != command->mCommand) continue; 87665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 87765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (command->mCommand) { 87865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_PARAMETERS: { 8790ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data = (ParametersData *)command->mParam.get(); 8800ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data2 = (ParametersData *)command2->mParam.get(); 88165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mIO != data2->mIO) break; 8823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Comparing parameter command %s to new command %s", 883de070137f11d346fba77605bd76a44c040a618fcEric Laurent data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 88465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioParameter param = AudioParameter(data->mKeyValuePairs); 88565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 88665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t j = 0; j < param.size(); j++) { 887e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 key; 888e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 value; 889e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param.getAt(j, key, value); 890e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten for (size_t k = 0; k < param2.size(); k++) { 891e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 key2; 892e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 value2; 893e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param2.getAt(k, key2, value2); 894e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten if (key2 == key) { 895e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param2.remove(key2); 896e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten ALOGV("Filtering out parameter %s", key2.string()); 897e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten break; 898e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 899e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 90165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // if all keys have been filtered out, remove the command. 90265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // otherwise, update the key value pairs 90365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (param2.size() == 0) { 90465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.add(command2); 90565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 90665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data2->mKeyValuePairs = param2.toString(); 90765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 90821e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent command->mTime = command2->mTime; 90921e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // force delayMs to non 0 so that code below does not request to wait for 91021e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // command status as the command is now delayed 91121e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent delayMs = 1; 91265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } break; 91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOLUME: { 9150ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data = (VolumeData *)command->mParam.get(); 9160ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data2 = (VolumeData *)command2->mParam.get(); 91765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mIO != data2->mIO) break; 91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mStream != data2->mStream) break; 9193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Filtering out volume command on output %d for stream %d", 920de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mIO, data->mStream); 92165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.add(command2); 92221e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent command->mTime = command2->mTime; 92321e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // force delayMs to non 0 so that code below does not request to wait for 92421e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // command status as the command is now delayed 92521e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent delayMs = 1; 92665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } break; 927e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 928baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent case SET_VOICE_VOLUME: { 929baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 930baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get(); 931baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent ALOGV("Filtering out voice volume command value %f replaced by %f", 932baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent data2->mVolume, data->mVolume); 933baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent removedCommands.add(command2); 934baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent command->mTime = command2->mTime; 935baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent // force delayMs to non 0 so that code below does not request to wait for 936baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent // command status as the command is now delayed 937baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent delayMs = 1; 938baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent } break; 939baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent 940e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent case CREATE_AUDIO_PATCH: 941e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent case RELEASE_AUDIO_PATCH: { 942e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent audio_patch_handle_t handle; 943a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George struct audio_patch patch; 944e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (command->mCommand == CREATE_AUDIO_PATCH) { 945e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle; 946a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch; 947e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else { 948e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle; 949e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 950e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent audio_patch_handle_t handle2; 951a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George struct audio_patch patch2; 952e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (command2->mCommand == CREATE_AUDIO_PATCH) { 953e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle; 954a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch; 955e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else { 956e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle; 957f60b6b6c776a762827874f6f635c0577359a7ee4Glenn Kasten memset(&patch2, 0, sizeof(patch2)); 958e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 959e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (handle != handle2) break; 960a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George /* Filter CREATE_AUDIO_PATCH commands only when they are issued for 961a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George same output. */ 962a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if( (command->mCommand == CREATE_AUDIO_PATCH) && 963a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George (command2->mCommand == CREATE_AUDIO_PATCH) ) { 964a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George bool isOutputDiff = false; 965a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if (patch.num_sources == patch2.num_sources) { 966a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George for (unsigned count = 0; count < patch.num_sources; count++) { 967a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if (patch.sources[count].id != patch2.sources[count].id) { 968a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George isOutputDiff = true; 969a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George break; 970a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 971a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 972a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if (isOutputDiff) 973a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George break; 974a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 975a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 976e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent ALOGV("Filtering out %s audio patch command for handle %d", 977e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle); 978e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent removedCommands.add(command2); 979e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent command->mTime = command2->mTime; 980e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // force delayMs to non 0 so that code below does not request to wait for 981e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // command status as the command is now delayed 982e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent delayMs = 1; 983e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } break; 984e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 985de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi case DYN_POLICY_MIX_STATE_UPDATE: { 986de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 987de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } break; 988de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 9892f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi case RECORDING_CONFIGURATION_UPDATE: { 9902f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 9912f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } break; 9922f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 99365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case START_TONE: 99465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case STOP_TONE: 99565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 99665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 99765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 99865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 99965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 100065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // remove filtered commands 100165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t j = 0; j < removedCommands.size(); j++) { 100265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // removed commands always have time stamps greater than current command 100365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 10040ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (mAudioCommands[k].get() == removedCommands[j].get()) { 10053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 100665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.removeAt(k); 100765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 100865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 100965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 101065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 101165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.clear(); 101265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1013aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent // Disable wait for status if delay is not 0. 1014aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent // Except for create audio patch command because the returned patch handle 1015aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent // is needed by audio policy manager 1016aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) { 1017cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent command->mWaitStatus = false; 1018cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent } 1019cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent 102065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // insert command at the right place according to its time stamp 10211e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ALOGV("inserting command: %d at index %zd, num commands %zu", 10221e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent command->mCommand, i+1, mAudioCommands.size()); 102365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.insertAt(command, i + 1); 102465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 102565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 102665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::exit() 102765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 10283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread::exit"); 102965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 103065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AutoMutex _l(mLock); 103165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian requestExit(); 103265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mWaitWorkCV.signal(); 103365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 1034a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // Note that we can call it from the thread loop if all other references have been released 1035a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // but it will safely return WOULD_BLOCK in this case 103665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian requestExitAndWait(); 103765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 103965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 104065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 104165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 104265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCommand, 104365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian (int)ns2s(mTime), 104465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian (int)ns2ms(mTime)%1000, 104565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mWaitStatus, 10460ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mParam.get()); 104765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 104865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1049fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin/******* helpers for the service_ops callbacks defined below *********/ 1050fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 1051fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin const char *keyValuePairs, 1052fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int delayMs) 1053fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 105472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs, 1055fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin delayMs); 1056fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1057fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1058fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setStreamVolume(audio_stream_type_t stream, 1059fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin float volume, 1060fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t output, 1061fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int delayMs) 1062fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 1063fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten return (int)mAudioCommandThread->volumeCommand(stream, volume, 106472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten output, delayMs); 1065fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1066fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1067fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::startTone(audio_policy_tone_t tone, 1068fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_stream_type_t stream) 1069fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 10706e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) { 107129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("startTone: illegal tone requested (%d)", tone); 10726e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 10736e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (stream != AUDIO_STREAM_VOICE_CALL) { 107429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("startTone: illegal stream (%d) requested for tone %d", stream, 1075e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten tone); 10766e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 1077fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING, 1078fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin AUDIO_STREAM_VOICE_CALL); 1079fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return 0; 1080fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1081fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1082fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::stopTone() 1083fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 1084fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mTonePlaybackThread->stopToneCommand(); 1085fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return 0; 1086fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1087fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1088fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setVoiceVolume(float volume, int delayMs) 1089fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 1090fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 1091fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1092fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1093fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinextern "C" { 10942d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_module_handle_t aps_load_hw_module(void *service __unused, 10952d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *name); 10962d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output(void *service __unused, 1097a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1098a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1099a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 1100a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 1101a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pLatencyMs, 11022d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_output_flags_t flags); 1103fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 11042d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output_on_module(void *service __unused, 1105a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_module_handle_t module, 1106a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1107a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1108a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 1109a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 1110a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pLatencyMs, 1111ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald audio_output_flags_t flags, 11122d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const audio_offload_info_t *offloadInfo); 11132d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_dup_output(void *service __unused, 1114fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t output1, 11152d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_io_handle_t output2); 11162d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_output(void *service __unused, audio_io_handle_t output); 11172d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_suspend_output(void *service __unused, audio_io_handle_t output); 11182d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_restore_output(void *service __unused, audio_io_handle_t output); 11192d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input(void *service __unused, 1120a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1121a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1122a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 1123a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 11242d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_in_acoustics_t acoustics __unused); 11252d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input_on_module(void *service __unused, 1126a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_module_handle_t module, 1127a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1128a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1129a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 11302d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_channel_mask_t *pChannelMask); 11312d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_input(void *service __unused, audio_io_handle_t input); 11322d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_invalidate_stream(void *service __unused, audio_stream_type_t stream); 1133d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastenint aps_move_effects(void *service __unused, audio_session_t session, 1134fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t src_output, 11352d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_io_handle_t dst_output); 11362d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentchar * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle, 11372d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *keys); 11382d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentvoid aps_set_parameters(void *service, audio_io_handle_t io_handle, 11392d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *kv_pairs, int delay_ms); 11402d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_stream_volume(void *service, audio_stream_type_t stream, 1141fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin float volume, audio_io_handle_t output, 11422d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent int delay_ms); 11432d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_start_tone(void *service, audio_policy_tone_t tone, 11442d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_stream_type_t stream); 11452d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_stop_tone(void *service); 11462d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_voice_volume(void *service, float volume, int delay_ms); 11472d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent}; 1148fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 114965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android 1150