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> 29f1047e87767be1acd2c32f4d36028d1d0014f4c0Eric Laurent#include <cutils/multiuser.h> 3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/properties.h> 3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h> 32f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <binder/ActivityManager.h> 33f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <binder/PermissionController.h> 34f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <binder/IResultReceiver.h> 3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h> 3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/threads.h> 3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioPolicyService.h" 3844deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten#include "ServiceUtilities.h" 3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware_legacy/power.h> 407c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent#include <media/AudioEffect.h> 41c84d9d235679a4d48245b316b7b2e4c0b19413e7Chih-Hung Hsieh#include <media/AudioParameter.h> 4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4364760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h> 447394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin#include <system/audio_policy.h> 4561a4fac2e3ec271241e3a4f405d7357b7f6ca4c2Mikhail Naganov 46f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <private/android_filesystem_config.h> 47f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android { 4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 508dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n"; 518dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n"; 5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50; 5422ecc912a87099cff8cadc424cd12f85c118673fGlenn Kastenstatic const int kDumpLockSleepUs = 20000; 5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 560ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatic const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds 575fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher 58f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatic const String16 sManageAudioPolicyPermission("android.permission.MANAGE_AUDIO_POLICY"); 59fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioPolicyService() 63dce54a1492c410ad0d93253b341fb33305337505Eric Laurent : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL), 64bb6c9a05840d924b502ce0f1868fca4881ada1edEric Laurent mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID) 6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 66f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent} 67f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent 68f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurentvoid AudioPolicyService::onFirstRef() 69f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent{ 708b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent { 718b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 72935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent 738b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start tone playback thread 748b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this); 758b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start audio commands thread 768b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this); 778b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start output activity command thread 788b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this); 79dce54a1492c410ad0d93253b341fb33305337505Eric Laurent 808b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyClient = new AudioPolicyClient(this); 818b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); 828b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 83ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // load audio processing modules 848b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects(); 858b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent { 868b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 878b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyEffects = audioPolicyEffects; 888b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 89f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 90f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov mUidPolicy = new UidPolicy(this); 91f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov mUidPolicy->registerSelf(); 9265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 9365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::~AudioPolicyService() 9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mTonePlaybackThread->exit(); 9765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommandThread->exit(); 98657ff61389d7316f798d4abe03efac56fd528d91Eric Laurent mOutputCommandThread->exit(); 997c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent 100f269b8e0e9ab950fc6652b9594b7a3431c81630cEric Laurent destroyAudioPolicyManager(mAudioPolicyManager); 101dce54a1492c410ad0d93253b341fb33305337505Eric Laurent delete mAudioPolicyClient; 102b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 103b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.clear(); 104ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mAudioPolicyEffects.clear(); 105f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 106f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov mUidPolicy->unregisterSelf(); 107f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov mUidPolicy.clear(); 108b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 109b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 110b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// A notification client is always registered by AudioSystem when the client process 111b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// connects to AudioPolicyService. 112b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client) 113b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 114125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent if (client == 0) { 115125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent ALOGW("%s got NULL client", __FUNCTION__); 116125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent return; 117125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent } 1180ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 119b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 120b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid_t uid = IPCThreadState::self()->getCallingUid(); 121b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (mNotificationClients.indexOfKey(uid) < 0) { 122b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<NotificationClient> notificationClient = new NotificationClient(this, 123b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent client, 124b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid); 125b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("registerClient() client %p, uid %d", client.get(), uid); 126b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 127b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.add(uid, notificationClient); 128b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 129f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen sp<IBinder> binder = IInterface::asBinder(client); 130b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent binder->linkToDeath(notificationClient); 131b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 132b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 133b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 134e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurentvoid AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled) 135e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent{ 136e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent Mutex::Autolock _l(mNotificationClientsLock); 137e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 138e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent uid_t uid = IPCThreadState::self()->getCallingUid(); 139e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (mNotificationClients.indexOfKey(uid) < 0) { 140e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent return; 141e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent } 142e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled); 143e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent} 144e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 145b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// removeNotificationClient() is called when the client process dies. 146b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::removeNotificationClient(uid_t uid) 147b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 1480ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent { 1490ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 1500ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent mNotificationClients.removeItem(uid); 1510ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent } 1520ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent { 1530ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mLock); 154b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (mAudioPolicyManager) { 15510b7123bd6ce29fe756422aeedc5cfe469c4309fEric Laurent // called from binder death notification: no need to clear caller identity 1568c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent mAudioPolicyManager->releaseResourcesForUid(uid); 157b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 1580ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent } 159b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 160b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 161b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPortListUpdate() 162b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 163b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mOutputCommandThread->updateAudioPortListCommand(); 164b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 165b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 166b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPortListUpdate() 167b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 1680ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 169b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent for (size_t i = 0; i < mNotificationClients.size(); i++) { 170b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.valueAt(i)->onAudioPortListUpdate(); 171b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 172b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 173b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 174b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPatchListUpdate() 175b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 176b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mOutputCommandThread->updateAudioPatchListCommand(); 17765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 17865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 179b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPatchListUpdate() 180b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 1810ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 182b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent for (size_t i = 0; i < mNotificationClients.size(); i++) { 183b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.valueAt(i)->onAudioPatchListUpdate(); 184b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 185b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 186b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 187e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state) 188de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 189de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)", 190de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi regId.string(), state); 191de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state); 192de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 193de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 194e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state) 195de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 196de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi Mutex::Autolock _l(mNotificationClientsLock); 197de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi for (size_t i = 0; i < mNotificationClients.size(); i++) { 198de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state); 199de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 200de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 201de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 202ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivivoid AudioPolicyService::onRecordingConfigurationUpdate(int event, 203ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig, 2048c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) 2052f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 206ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo, 2078c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi clientConfig, deviceConfig, patchHandle); 2082f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2092f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 210ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivivoid AudioPolicyService::doOnRecordingConfigurationUpdate(int event, 211ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig, 2128c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) 2132f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 2142f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi Mutex::Autolock _l(mNotificationClientsLock); 2152f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi for (size_t i = 0; i < mNotificationClients.size(); i++) { 216ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo, 2178c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi clientConfig, deviceConfig, patchHandle); 2182f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } 2192f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2202f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 2212f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivistatus_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch, 2222f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi audio_patch_handle_t *handle, 2232f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi int delayMs) 2242f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 2252f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs); 2262f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2272f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 2282f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivistatus_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle, 2292f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi int delayMs) 2302f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 2312f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs); 2322f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2332f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 234e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config, 235e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent int delayMs) 236e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{ 237e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); 238e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent} 239e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 240b52c152d553556b2d227ffc943489de0c60b4b02Eric LaurentAudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service, 241b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent const sp<IAudioPolicyServiceClient>& client, 242b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid_t uid) 243e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent : mService(service), mUid(uid), mAudioPolicyServiceClient(client), 244e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mAudioPortCallbacksEnabled(false) 245b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 246b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 247b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 248b52c152d553556b2d227ffc943489de0c60b4b02Eric LaurentAudioPolicyService::NotificationClient::~NotificationClient() 249b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 250b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 251b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 252b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused) 253b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 254b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<NotificationClient> keep(this); 255b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<AudioPolicyService> service = mService.promote(); 256b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (service != 0) { 257b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent service->removeNotificationClient(mUid); 258b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 259b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 260b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 261b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::onAudioPortListUpdate() 262b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 263e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 264b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mAudioPolicyServiceClient->onAudioPortListUpdate(); 265b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 266b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 267b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 268b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::onAudioPatchListUpdate() 269b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 270e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 271b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mAudioPolicyServiceClient->onAudioPatchListUpdate(); 272b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 273b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 27457dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent 275de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivivoid AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( 276e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const String8& regId, int32_t state) 277de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 278f1047e87767be1acd2c32f4d36028d1d0014f4c0Eric Laurent if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) { 2792f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state); 2802f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } 2812f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2822f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 2832f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate( 284ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi int event, const record_client_info_t *clientInfo, 2858c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, 2868c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi audio_patch_handle_t patchHandle) 2872f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 288f1047e87767be1acd2c32f4d36028d1d0014f4c0Eric Laurent if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) { 289ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo, 2908c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi clientConfig, deviceConfig, patchHandle); 291de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 292de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 293de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 294e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurentvoid AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled) 295e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent{ 296e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mAudioPortCallbacksEnabled = enabled; 297e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent} 298e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 299e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::binderDied(const wp<IBinder>& who) { 301411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), 302de070137f11d346fba77605bd76a44c040a618fcEric Laurent IPCThreadState::self()->getCallingPid()); 30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex) 30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = false; 30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < kDumpLockRetries; ++i) { 30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mutex.tryLock() == NO_ERROR) { 31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian locked = true; 31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 31322ecc912a87099cff8cadc424cd12f85c118673fGlenn Kasten usleep(kDumpLockSleepUs); 31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return locked; 31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpInternals(int fd) 31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 32365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 324dce54a1492c410ad0d93253b341fb33305337505Eric Laurent snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager); 32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); 32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); 32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 335f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::setRecordSilenced(uid_t uid, bool silenced) 336f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov{ 337eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov { 338eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov Mutex::Autolock _l(mLock); 339eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (mAudioPolicyManager) { 34010b7123bd6ce29fe756422aeedc5cfe469c4309fEric Laurent AutoCallerClear acc; 341eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov mAudioPolicyManager->setRecordSilenced(uid, silenced); 342eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } 343eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } 344eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 345eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (af) { 346eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov af->setRecordSilenced(uid, silenced); 347eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } 348f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 349f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 3500f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused) 35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 35244deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten if (!dumpAllowed()) { 35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dumpPermissionDenial(fd); 35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = tryLock(mLock); 35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!locked) { 35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result(kDeadlockedString); 35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dumpInternals(fd); 3629d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten if (mAudioCommandThread != 0) { 36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommandThread->dump(fd); 36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 3659d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten if (mTonePlaybackThread != 0) { 36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mTonePlaybackThread->dump(fd); 36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 369dce54a1492c410ad0d93253b341fb33305337505Eric Laurent if (mAudioPolicyManager) { 370dce54a1492c410ad0d93253b341fb33305337505Eric Laurent mAudioPolicyManager->dump(fd); 371dce54a1492c410ad0d93253b341fb33305337505Eric Laurent } 37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (locked) mLock.unlock(); 37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpPermissionDenial(int fd) 37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Permission Denial: " 38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian "can't dump AudioPolicyService from pid=%d, uid=%d\n", 38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState::self()->getCallingPid(), 38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState::self()->getCallingUid()); 38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::onTransact( 393f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 394f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov switch (code) { 395f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov case SHELL_COMMAND_TRANSACTION: { 396f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov int in = data.readFileDescriptor(); 397f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov int out = data.readFileDescriptor(); 398f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov int err = data.readFileDescriptor(); 399f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov int argc = data.readInt32(); 400f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov Vector<String16> args; 401f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov for (int i = 0; i < argc && data.dataAvail() > 0; i++) { 402f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov args.add(data.readString16()); 403f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 404f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov sp<IBinder> unusedCallback; 405f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov sp<IResultReceiver> resultReceiver; 406f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov status_t status; 407f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) { 408f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return status; 409f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 410f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) { 411f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return status; 412f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 413f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov status = shellCommand(in, out, err, args); 414f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if (resultReceiver != nullptr) { 415f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov resultReceiver->send(status); 416f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 417f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return NO_ERROR; 418f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 419f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 420f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return BnAudioPolicyService::onTransact(code, data, reply, flags); 42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 424f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov// ------------------- Shell command implementation ------------------- 425f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 426f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov// NOTE: This is a remote API - make sure all args are validated 427f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::shellCommand(int in, int out, int err, Vector<String16>& args) { 428f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if (!checkCallingPermission(sManageAudioPolicyPermission, nullptr, nullptr)) { 429f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return PERMISSION_DENIED; 430f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 431f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) { 432f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return BAD_VALUE; 433f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 434f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if (args.size() == 3 && args[0] == String16("set-uid-state")) { 435f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return handleSetUidState(args, err); 436f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) { 437f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return handleResetUidState(args, err); 438f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } else if (args.size() == 2 && args[0] == String16("get-uid-state")) { 439f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return handleGetUidState(args, out, err); 440f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } else if (args.size() == 1 && args[0] == String16("help")) { 441f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov printHelp(out); 442f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return NO_ERROR; 443f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 444f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov printHelp(err); 445f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return BAD_VALUE; 446f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 447f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 448f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::handleSetUidState(Vector<String16>& args, int err) { 449f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov PermissionController pc; 450f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov int uid = pc.getPackageUid(args[1], 0); 451f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if (uid <= 0) { 452f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov ALOGE("Unknown package: '%s'", String8(args[1]).string()); 453f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); 454f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return BAD_VALUE; 455f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 456f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov bool active = false; 457f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if (args[2] == String16("active")) { 458f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov active = true; 459f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } else if ((args[2] != String16("idle"))) { 460f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string()); 461f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return BAD_VALUE; 462f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 463f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov mUidPolicy->addOverrideUid(uid, active); 464f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return NO_ERROR; 465f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 466f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 467f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::handleResetUidState(Vector<String16>& args, int err) { 468f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov PermissionController pc; 469f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov int uid = pc.getPackageUid(args[1], 0); 470f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if (uid < 0) { 471f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov ALOGE("Unknown package: '%s'", String8(args[1]).string()); 472f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); 473f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return BAD_VALUE; 474f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 475f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov mUidPolicy->removeOverrideUid(uid); 476f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return NO_ERROR; 477f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 478f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 479f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::handleGetUidState(Vector<String16>& args, int out, int err) { 480f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov PermissionController pc; 481f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov int uid = pc.getPackageUid(args[1], 0); 482f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if (uid < 0) { 483f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov ALOGE("Unknown package: '%s'", String8(args[1]).string()); 484f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); 485f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return BAD_VALUE; 486f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 487f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if (mUidPolicy->isUidActive(uid)) { 488f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return dprintf(out, "active\n"); 489f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } else { 490f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return dprintf(out, "idle\n"); 491f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 492f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 493f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 494f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::printHelp(int out) { 495f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov return dprintf(out, "Audio policy service commands:\n" 496f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov " get-uid-state <PACKAGE> gets the uid state\n" 497f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov " set-uid-state <PACKAGE> <active|idle> overrides the uid state\n" 498f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov " reset-uid-state <PACKAGE> clears the uid state override\n" 499f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov " help print this message\n"); 500f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 501f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 502f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov// ----------- AudioPolicyService::UidPolicy implementation ---------- 503f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 504f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::UidPolicy::registerSelf() { 505f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov ActivityManager am; 506f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE 507f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov | ActivityManager::UID_OBSERVER_IDLE 508f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov | ActivityManager::UID_OBSERVER_ACTIVE, 509f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov ActivityManager::PROCESS_STATE_UNKNOWN, 510f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov String16("audioserver")); 511eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov status_t res = am.linkToDeath(this); 512eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (!res) { 513eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov Mutex::Autolock _l(mLock); 514eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov mObserverRegistered = true; 515eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } else { 516eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res); 517eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov am.unregisterUidObserver(this); 518eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } 519f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 520f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 521f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::UidPolicy::unregisterSelf() { 522f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov ActivityManager am; 523eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov am.unlinkToDeath(this); 524f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov am.unregisterUidObserver(this); 525eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov Mutex::Autolock _l(mLock); 526eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov mObserverRegistered = false; 527f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 528f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 529eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) { 530eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov Mutex::Autolock _l(mLock); 531eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov mCachedUids.clear(); 532eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov mObserverRegistered = false; 533f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 534f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 535eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovbool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) { 536eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (isServiceUid(uid)) return true; 537eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov bool needToReregister = false; 538f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov { 539eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov Mutex::Autolock _l(mLock); 540eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov needToReregister = !mObserverRegistered; 541f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 542eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (needToReregister) { 543eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov // Looks like ActivityManager has died previously, attempt to re-register. 544eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov registerSelf(); 545f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 546f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov { 547eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov Mutex::Autolock _l(mLock); 548eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov auto overrideIter = mOverrideUids.find(uid); 549eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (overrideIter != mOverrideUids.end()) { 550eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov return overrideIter->second; 551f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 552eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov // In an absense of the ActivityManager, assume everything to be active. 553eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (!mObserverRegistered) return true; 554eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov auto cacheIter = mCachedUids.find(uid); 555eba668adbdee1ecfcf00fa9f9fc066c022cfddbaMikhail Naganov if (cacheIter != mCachedUids.end()) { 556eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov return cacheIter->second; 557f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 558f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 559eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov ActivityManager am; 560eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov bool active = am.isUidActive(uid, String16("audioserver")); 561eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov { 562eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov Mutex::Autolock _l(mLock); 563eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov mCachedUids.insert(std::pair<uid_t, bool>(uid, active)); 564eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } 565eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov return active; 566f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 567f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 568eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::onUidActive(uid_t uid) { 569eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov updateUidCache(uid, true, true); 570f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 571f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 572eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) { 573eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov updateUidCache(uid, false, false); 574eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov} 575eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov 576eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) { 577eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov updateUidCache(uid, false, true); 578eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov} 579eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov 580eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovbool AudioPolicyService::UidPolicy::isServiceUid(uid_t uid) const { 581f1047e87767be1acd2c32f4d36028d1d0014f4c0Eric Laurent return multiuser_get_app_id(uid) < AID_APP_START; 582eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov} 583eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov 584eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) { 585eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov sp<AudioPolicyService> service = mService.promote(); 586eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (service != nullptr) { 587eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov service->setRecordSilenced(uid, !active); 588eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } 589f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 590f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 591f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) { 592eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (isServiceUid(uid)) return; 593eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov bool wasOverridden = false, wasActive = false; 594f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov { 595eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov Mutex::Autolock _l(mLock); 596eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov updateUidLocked(&mOverrideUids, uid, active, insert, &wasOverridden, &wasActive); 597f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 598eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (!wasOverridden && insert) { 599eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov notifyService(uid, active); // Started to override. 600eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } else if (wasOverridden && !insert) { 601eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov notifyService(uid, isUidActive(uid)); // Override ceased, notify with ground truth. 602eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } else if (wasActive != active) { 603eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov notifyService(uid, active); // Override updated. 604f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 605f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 606f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 607eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::updateUidCache(uid_t uid, bool active, bool insert) { 608eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (isServiceUid(uid)) return; 609eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov bool wasActive = false; 610eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov { 611eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov Mutex::Autolock _l(mLock); 612eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov updateUidLocked(&mCachedUids, uid, active, insert, nullptr, &wasActive); 613eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov // Do not notify service if currently overridden. 614eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (mOverrideUids.find(uid) != mOverrideUids.end()) return; 615eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } 616eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov bool nowActive = active && insert; 617eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (wasActive != nowActive) notifyService(uid, nowActive); 618eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov} 619eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov 620eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t, bool> *uids, 621eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive) { 622eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov auto it = uids->find(uid); 623eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (it != uids->end()) { 624eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (wasThere != nullptr) *wasThere = true; 625eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (wasActive != nullptr) *wasActive = it->second; 626eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov if (insert) { 627eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov it->second = active; 628eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } else { 629eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov uids->erase(it); 630eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } 631eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } else if (insert) { 632eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov uids->insert(std::pair<uid_t, bool>(uid, active)); 633eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov } 634f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 63565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------- AudioPolicyService::AudioCommandThread implementation ---------- 63765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 638bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name, 639bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent const wp<AudioPolicyService>& service) 640bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent : Thread(false), mName(name), mService(service) 64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 64265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = NULL; 64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioCommandThread::~AudioCommandThread() 64765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 648bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (!mAudioCommands.isEmpty()) { 64965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian release_wake_lock(mName.string()); 65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 65165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.clear(); 652e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten delete mpToneGenerator; 65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::onFirstRef() 65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 657bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent run(mName.string(), ANDROID_PRIORITY_AUDIO); 65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 66065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioPolicyService::AudioCommandThread::threadLoop() 66165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 662d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent nsecs_t waitTime = -1; 66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 66565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian while (!exitPending()) 66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 66759a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent sp<AudioPolicyService> svc; 66859a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent while (!mAudioCommands.isEmpty() && !exitPending()) { 66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian nsecs_t curTime = systemTime(); 67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // commands are sorted by increasing time stamp: execute them from index 0 and up 67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mAudioCommands[0]->mTime <= curTime) { 6720ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = mAudioCommands[0]; 67365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.removeAt(0); 6740ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mLastCommand = command; 67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (command->mCommand) { 67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case START_TONE: { 67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 6790ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ToneData *data = (ToneData *)command->mParam.get(); 6803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing start tone %d on stream %d", 68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mType, data->mStream); 682e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten delete mpToneGenerator; 68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = new ToneGenerator(data->mStream, 1.0); 68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator->startTone(data->mType); 68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case STOP_TONE: { 68865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 6893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing stop tone"); 69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mpToneGenerator != NULL) { 69165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator->stopTone(); 69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian delete mpToneGenerator; 69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = NULL; 69465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 69665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 69765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOLUME: { 6980ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data = (VolumeData *)command->mParam.get(); 6993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing set volume stream %d, \ 700de070137f11d346fba77605bd76a44c040a618fcEric Laurent volume %f, output %d", data->mStream, data->mVolume, data->mIO); 701de070137f11d346fba77605bd76a44c040a618fcEric Laurent command->mStatus = AudioSystem::setStreamVolume(data->mStream, 702de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mVolume, 703de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mIO); 70465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 70565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_PARAMETERS: { 7060ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data = (ParametersData *)command->mParam.get(); 707e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten ALOGV("AudioCommandThread() processing set parameters string %s, io %d", 708e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten data->mKeyValuePairs.string(), data->mIO); 709e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); 710e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten }break; 71165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOICE_VOLUME: { 7120ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 7133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing set voice volume volume %f", 714de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mVolume); 71565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); 71665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 717bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent case STOP_OUTPUT: { 7180ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent StopOutputData *data = (StopOutputData *)command->mParam.get(); 719bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() processing stop output %d", 720bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO); 72159a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 722bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (svc == 0) { 723bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 724bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 725bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 726bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent svc->doStopOutput(data->mIO, data->mStream, data->mSession); 727bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 728bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent }break; 729bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent case RELEASE_OUTPUT: { 7300ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get(); 731bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() processing release output %d", 732bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO); 73359a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 734bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (svc == 0) { 735bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 736bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 737bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 738e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent svc->doReleaseOutput(data->mIO, data->mStream, data->mSession); 739bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 740bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent }break; 741951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent case CREATE_AUDIO_PATCH: { 742951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get(); 743951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() processing create audio patch"); 744951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 745951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (af == 0) { 746951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = PERMISSION_DENIED; 747951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } else { 748951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle); 749951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 750951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } break; 751951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent case RELEASE_AUDIO_PATCH: { 752951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get(); 753951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() processing release audio patch"); 754951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 755951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (af == 0) { 756951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = PERMISSION_DENIED; 757951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } else { 758951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = af->releaseAudioPatch(data->mHandle); 759951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 760951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } break; 761b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent case UPDATE_AUDIOPORT_LIST: { 762b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() processing update audio port list"); 76359a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 764b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (svc == 0) { 765b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent break; 766b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 767b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.unlock(); 768b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent svc->doOnAudioPortListUpdate(); 769b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.lock(); 770b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent }break; 771b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent case UPDATE_AUDIOPATCH_LIST: { 772b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() processing update audio patch list"); 77359a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 774b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (svc == 0) { 775b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent break; 776b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 777b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.unlock(); 778b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent svc->doOnAudioPatchListUpdate(); 779b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.lock(); 780b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent }break; 781e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent case SET_AUDIOPORT_CONFIG: { 782e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get(); 783e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("AudioCommandThread() processing set port config"); 784e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 785e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (af == 0) { 786e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mStatus = PERMISSION_DENIED; 787e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 788e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mStatus = af->setAudioPortConfig(&data->mConfig); 789e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 790e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } break; 791de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi case DYN_POLICY_MIX_STATE_UPDATE: { 792de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi DynPolicyMixStateUpdateData *data = 793de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi (DynPolicyMixStateUpdateData *)command->mParam.get(); 794de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d", 795de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi data->mRegId.string(), data->mState); 796de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi svc = mService.promote(); 797de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi if (svc == 0) { 798de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi break; 799de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 800de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mLock.unlock(); 801de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState); 802de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mLock.lock(); 803de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } break; 8042f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi case RECORDING_CONFIGURATION_UPDATE: { 8052f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi RecordingConfigurationUpdateData *data = 8062f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi (RecordingConfigurationUpdateData *)command->mParam.get(); 8072f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi ALOGV("AudioCommandThread() processing recording configuration update"); 8082f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi svc = mService.promote(); 8092f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi if (svc == 0) { 8102f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi break; 8112f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } 8122f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi mLock.unlock(); 813ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo, 814ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi &data->mClientConfig, &data->mDeviceConfig, 8158c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi data->mPatchHandle); 8162f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi mLock.lock(); 8172f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } break; 81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 8195ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AudioCommandThread() unknown command %d", command->mCommand); 82065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 8210ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent { 8220ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(command->mLock); 8230ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (command->mWaitStatus) { 8240ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = false; 8250ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mCond.signal(); 8260ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 8270ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 828d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent waitTime = -1; 829a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // release mLock before releasing strong reference on the service as 830a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // AudioPolicyService destructor calls AudioCommandThread::exit() which 831a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // acquires mLock. 832a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang mLock.unlock(); 833a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang svc.clear(); 834a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang mLock.lock(); 83565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 83665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian waitTime = mAudioCommands[0]->mTime - curTime; 83765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 83865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 83965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 840a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang 841a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // release delayed commands wake lock if the queue is empty 842a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang if (mAudioCommands.isEmpty()) { 84305f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia release_wake_lock(mName.string()); 844a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang } 845a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang 846a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // At this stage we have either an empty command queue or the first command in the queue 847a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // has a finite delay. So unless we are exiting it is safe to wait. 848a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang if (!exitPending()) { 84959a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent ALOGV("AudioCommandThread() going to sleep"); 850d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent if (waitTime == -1) { 851d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent mWaitWorkCV.wait(mLock); 852d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent } else { 853d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent mWaitWorkCV.waitRelative(mLock, waitTime); 854d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent } 85559a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent } 85665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 85705f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia // release delayed commands wake lock before quitting 85805f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia if (!mAudioCommands.isEmpty()) { 85905f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia release_wake_lock(mName.string()); 86005f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia } 86165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 86265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return false; 86365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 86465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 86565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::dump(int fd) 86665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 86765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 86865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 86965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 87065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 87165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 87265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 87365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 87465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 87565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = tryLock(mLock); 87665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!locked) { 87765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result2(kCmdDeadlockedString); 87865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result2.string(), result2.size()); 87965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 88065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 88165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "- Commands:\n"); 88265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = String8(buffer); 88365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(" Command Time Wait pParam\n"); 8848d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten for (size_t i = 0; i < mAudioCommands.size(); i++) { 88565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands[i]->dump(buffer, SIZE); 88665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 88765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 88865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(" Last Command\n"); 8890ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (mLastCommand != 0) { 8900ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mLastCommand->dump(buffer, SIZE); 8910ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent result.append(buffer); 8920ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } else { 8930ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent result.append(" none\n"); 8940ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 89665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 89765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 89865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (locked) mLock.unlock(); 89965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 90165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 90265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 9033d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kastenvoid AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type, 9043d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kasten audio_stream_type_t stream) 90565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 9060ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 90765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = START_TONE; 9080ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ToneData> data = new ToneData(); 90965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mType = type; 91065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mStream = stream; 91148412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 9123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 9130ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 91665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::stopToneCommand() 91765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 9180ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 91965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = STOP_TONE; 9203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding tone stop"); 9210ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 92265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 92365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 924fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream, 925de070137f11d346fba77605bd76a44c040a618fcEric Laurent float volume, 92672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten audio_io_handle_t output, 927de070137f11d346fba77605bd76a44c040a618fcEric Laurent int delayMs) 92865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 9290ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 93065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_VOLUME; 9310ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<VolumeData> data = new VolumeData(); 93265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mStream = stream; 93365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mVolume = volume; 93465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mIO = output; 93565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 9360ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 9373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 938de070137f11d346fba77605bd76a44c040a618fcEric Laurent stream, volume, output); 9390ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 94065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 94165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 94272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle, 943fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin const char *keyValuePairs, 944de070137f11d346fba77605bd76a44c040a618fcEric Laurent int delayMs) 94565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 9460ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 94765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_PARAMETERS; 9480ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ParametersData> data = new ParametersData(); 94965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mIO = ioHandle; 950fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin data->mKeyValuePairs = String8(keyValuePairs); 95165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 9520ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 9533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 954fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin keyValuePairs, ioHandle, delayMs); 9550ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 95665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 95765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 95865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 95965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 9600ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 96165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_VOICE_VOLUME; 9620ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<VoiceVolumeData> data = new VoiceVolumeData(); 96365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mVolume = volume; 96465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 9650ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 9663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set voice volume volume %f", volume); 9670ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 96865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 96965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 970bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output, 971bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent audio_stream_type_t stream, 972e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_session_t session) 973bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 9740ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 975bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent command->mCommand = STOP_OUTPUT; 9760ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<StopOutputData> data = new StopOutputData(); 977bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO = output; 978bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mStream = stream; 979bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mSession = session; 98048412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 981bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() adding stop output %d", output); 9820ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 983bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 984bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 985e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentvoid AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output, 986e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_stream_type_t stream, 987e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_session_t session) 988bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 9890ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 990bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent command->mCommand = RELEASE_OUTPUT; 9910ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ReleaseOutputData> data = new ReleaseOutputData(); 992bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO = output; 993e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent data->mStream = stream; 994e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent data->mSession = session; 99548412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 996bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() adding release output %d", output); 9970ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 9980ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent} 9990ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent 1000951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand( 1001951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent const struct audio_patch *patch, 1002951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent audio_patch_handle_t *handle, 1003951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent int delayMs) 1004951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{ 1005951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent status_t status = NO_ERROR; 1006951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 1007951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<AudioCommand> command = new AudioCommand(); 1008951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mCommand = CREATE_AUDIO_PATCH; 1009951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent CreateAudioPatchData *data = new CreateAudioPatchData(); 1010951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mPatch = *patch; 1011951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mHandle = *handle; 1012951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mParam = data; 1013951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mWaitStatus = true; 1014951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() adding create patch delay %d", delayMs); 1015951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent status = sendCommand(command, delayMs); 1016951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (status == NO_ERROR) { 1017951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent *handle = data->mHandle; 1018951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 1019951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent return status; 1020951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent} 1021951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 1022951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle, 1023951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent int delayMs) 1024951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{ 1025951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<AudioCommand> command = new AudioCommand(); 1026951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mCommand = RELEASE_AUDIO_PATCH; 1027951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ReleaseAudioPatchData *data = new ReleaseAudioPatchData(); 1028951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mHandle = handle; 1029951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mParam = data; 1030951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mWaitStatus = true; 1031951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() adding release patch delay %d", delayMs); 1032951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent return sendCommand(command, delayMs); 1033951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent} 1034951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 1035b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPortListCommand() 1036b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 1037b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<AudioCommand> command = new AudioCommand(); 1038b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent command->mCommand = UPDATE_AUDIOPORT_LIST; 1039b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() adding update audio port list"); 1040b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sendCommand(command); 1041b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 1042b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 1043b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand() 1044b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 1045b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<AudioCommand>command = new AudioCommand(); 1046b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent command->mCommand = UPDATE_AUDIOPATCH_LIST; 1047b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() adding update audio patch list"); 1048b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sendCommand(command); 1049b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 1050b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 1051e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand( 1052e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent const struct audio_port_config *config, int delayMs) 1053e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{ 1054e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent sp<AudioCommand> command = new AudioCommand(); 1055e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mCommand = SET_AUDIOPORT_CONFIG; 1056e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent SetAudioPortConfigData *data = new SetAudioPortConfigData(); 1057e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent data->mConfig = *config; 1058e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mParam = data; 1059e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mWaitStatus = true; 1060e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("AudioCommandThread() adding set port config delay %d", delayMs); 1061e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return sendCommand(command, delayMs); 1062e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent} 1063e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 1064de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivivoid AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( 1065e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const String8& regId, int32_t state) 1066de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 1067de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi sp<AudioCommand> command = new AudioCommand(); 1068de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi command->mCommand = DYN_POLICY_MIX_STATE_UPDATE; 1069de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData(); 1070de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi data->mRegId = regId; 1071de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi data->mState = state; 1072de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi command->mParam = data; 1073de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d", 1074de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi regId.string(), state); 1075de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi sendCommand(command); 1076de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 1077de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 10782f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand( 1079ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi int event, const record_client_info_t *clientInfo, 10808c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, 10818c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi audio_patch_handle_t patchHandle) 10822f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 10832f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi sp<AudioCommand>command = new AudioCommand(); 10842f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi command->mCommand = RECORDING_CONFIGURATION_UPDATE; 10852f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData(); 10862f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi data->mEvent = event; 1087ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi data->mClientInfo = *clientInfo; 10887281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi data->mClientConfig = *clientConfig; 10897281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi data->mDeviceConfig = *deviceConfig; 10908c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi data->mPatchHandle = patchHandle; 10912f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi command->mParam = data; 1092ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u", 1093ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi event, clientInfo->source, clientInfo->uid); 10942f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi sendCommand(command); 10952f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 10962f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 10970ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatus_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) 10980ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent{ 10990ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent { 11000ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(mLock); 11010ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent insertCommand_l(command, delayMs); 11020ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mWaitWorkCV.signal(); 11030ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 11040ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(command->mLock); 11050ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent while (command->mWaitStatus) { 11060ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs); 11070ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) { 11080ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mStatus = TIMED_OUT; 11090ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = false; 11100ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 11110ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 11120ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return command->mStatus; 1113bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 1114bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 111565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// insertCommand_l() must be called with mLock held 11160ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentvoid AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs) 111765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 11188d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten ssize_t i; // not size_t because i will count down to -1 11190ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Vector < sp<AudioCommand> > removedCommands; 112065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mTime = systemTime() + milliseconds(delayMs); 112165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 112265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // acquire wake lock to make sure delayed commands are processed 1123bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mAudioCommands.isEmpty()) { 112465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 112565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 112665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 112765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // check same pending commands with later time stamps and eliminate them 11285ff158fd499f581bdc1c3e91bbc03ce15eeeb77cIvan Lozano for (i = (ssize_t)mAudioCommands.size()-1; i >= 0; i--) { 11290ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command2 = mAudioCommands[i]; 113065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 113165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (command2->mTime <= command->mTime) break; 1132e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 1133e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // create audio patch or release audio patch commands are equivalent 1134e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // with regard to filtering 1135e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if ((command->mCommand == CREATE_AUDIO_PATCH) || 1136e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command->mCommand == RELEASE_AUDIO_PATCH)) { 1137e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if ((command2->mCommand != CREATE_AUDIO_PATCH) && 1138e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command2->mCommand != RELEASE_AUDIO_PATCH)) { 1139e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent continue; 1140e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 1141e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else if (command2->mCommand != command->mCommand) continue; 114265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 114365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (command->mCommand) { 114465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_PARAMETERS: { 11450ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data = (ParametersData *)command->mParam.get(); 11460ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data2 = (ParametersData *)command2->mParam.get(); 114765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mIO != data2->mIO) break; 11483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Comparing parameter command %s to new command %s", 1149de070137f11d346fba77605bd76a44c040a618fcEric Laurent data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 115065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioParameter param = AudioParameter(data->mKeyValuePairs); 115165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 115265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t j = 0; j < param.size(); j++) { 1153e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 key; 1154e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 value; 1155e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param.getAt(j, key, value); 1156e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten for (size_t k = 0; k < param2.size(); k++) { 1157e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 key2; 1158e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 value2; 1159e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param2.getAt(k, key2, value2); 1160e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten if (key2 == key) { 1161e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param2.remove(key2); 1162e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten ALOGV("Filtering out parameter %s", key2.string()); 1163e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten break; 1164e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 1165e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 116665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 116765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // if all keys have been filtered out, remove the command. 116865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // otherwise, update the key value pairs 116965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (param2.size() == 0) { 117065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.add(command2); 117165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 117265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data2->mKeyValuePairs = param2.toString(); 117365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 117421e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent command->mTime = command2->mTime; 117521e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // force delayMs to non 0 so that code below does not request to wait for 117621e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // command status as the command is now delayed 117721e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent delayMs = 1; 117865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } break; 117965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 118065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOLUME: { 11810ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data = (VolumeData *)command->mParam.get(); 11820ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data2 = (VolumeData *)command2->mParam.get(); 118365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mIO != data2->mIO) break; 118465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mStream != data2->mStream) break; 11853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Filtering out volume command on output %d for stream %d", 1186de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mIO, data->mStream); 118765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.add(command2); 118821e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent command->mTime = command2->mTime; 118921e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // force delayMs to non 0 so that code below does not request to wait for 119021e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // command status as the command is now delayed 119121e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent delayMs = 1; 119265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } break; 1193e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 1194baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent case SET_VOICE_VOLUME: { 1195baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 1196baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get(); 1197baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent ALOGV("Filtering out voice volume command value %f replaced by %f", 1198baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent data2->mVolume, data->mVolume); 1199baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent removedCommands.add(command2); 1200baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent command->mTime = command2->mTime; 1201baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent // force delayMs to non 0 so that code below does not request to wait for 1202baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent // command status as the command is now delayed 1203baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent delayMs = 1; 1204baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent } break; 1205baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent 1206e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent case CREATE_AUDIO_PATCH: 1207e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent case RELEASE_AUDIO_PATCH: { 1208e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent audio_patch_handle_t handle; 1209a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George struct audio_patch patch; 1210e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (command->mCommand == CREATE_AUDIO_PATCH) { 1211e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle; 1212a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch; 1213e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else { 1214e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle; 1215e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 1216e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent audio_patch_handle_t handle2; 1217a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George struct audio_patch patch2; 1218e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (command2->mCommand == CREATE_AUDIO_PATCH) { 1219e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle; 1220a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch; 1221e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else { 1222e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle; 1223f60b6b6c776a762827874f6f635c0577359a7ee4Glenn Kasten memset(&patch2, 0, sizeof(patch2)); 1224e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 1225e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (handle != handle2) break; 1226a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George /* Filter CREATE_AUDIO_PATCH commands only when they are issued for 1227a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George same output. */ 1228a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if( (command->mCommand == CREATE_AUDIO_PATCH) && 1229a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George (command2->mCommand == CREATE_AUDIO_PATCH) ) { 1230a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George bool isOutputDiff = false; 1231a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if (patch.num_sources == patch2.num_sources) { 1232a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George for (unsigned count = 0; count < patch.num_sources; count++) { 1233a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if (patch.sources[count].id != patch2.sources[count].id) { 1234a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George isOutputDiff = true; 1235a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George break; 1236a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 1237a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 1238a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if (isOutputDiff) 1239a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George break; 1240a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 1241a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 1242e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent ALOGV("Filtering out %s audio patch command for handle %d", 1243e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle); 1244e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent removedCommands.add(command2); 1245e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent command->mTime = command2->mTime; 1246e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // force delayMs to non 0 so that code below does not request to wait for 1247e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // command status as the command is now delayed 1248e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent delayMs = 1; 1249e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } break; 1250e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 1251de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi case DYN_POLICY_MIX_STATE_UPDATE: { 1252de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 1253de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } break; 1254de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 12552f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi case RECORDING_CONFIGURATION_UPDATE: { 12562f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 12572f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } break; 12582f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 125965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case START_TONE: 126065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case STOP_TONE: 126165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 126265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 126365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 126465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 126565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 126665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // remove filtered commands 126765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t j = 0; j < removedCommands.size(); j++) { 126865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // removed commands always have time stamps greater than current command 126965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 12700ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (mAudioCommands[k].get() == removedCommands[j].get()) { 12713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 127265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.removeAt(k); 127365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 127465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 127565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 127665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 127765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.clear(); 127865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1279aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent // Disable wait for status if delay is not 0. 1280aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent // Except for create audio patch command because the returned patch handle 1281aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent // is needed by audio policy manager 1282aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) { 1283cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent command->mWaitStatus = false; 1284cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent } 1285cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent 128665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // insert command at the right place according to its time stamp 12871e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ALOGV("inserting command: %d at index %zd, num commands %zu", 12881e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent command->mCommand, i+1, mAudioCommands.size()); 128965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.insertAt(command, i + 1); 129065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 129165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 129265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::exit() 129365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 12943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread::exit"); 129565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 129665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AutoMutex _l(mLock); 129765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian requestExit(); 129865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mWaitWorkCV.signal(); 129965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 1300a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // Note that we can call it from the thread loop if all other references have been released 1301a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // but it will safely return WOULD_BLOCK in this case 130265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian requestExitAndWait(); 130365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 130465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 130565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 130665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 130765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 130865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCommand, 130965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian (int)ns2s(mTime), 131065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian (int)ns2ms(mTime)%1000, 131165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mWaitStatus, 13120ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mParam.get()); 131365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 131465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1315fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin/******* helpers for the service_ops callbacks defined below *********/ 1316fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 1317fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin const char *keyValuePairs, 1318fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int delayMs) 1319fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 132072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs, 1321fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin delayMs); 1322fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1323fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1324fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setStreamVolume(audio_stream_type_t stream, 1325fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin float volume, 1326fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t output, 1327fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int delayMs) 1328fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 1329fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten return (int)mAudioCommandThread->volumeCommand(stream, volume, 133072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten output, delayMs); 1331fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1332fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1333fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::startTone(audio_policy_tone_t tone, 1334fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_stream_type_t stream) 1335fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 13366e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) { 133729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("startTone: illegal tone requested (%d)", tone); 13386e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 13396e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (stream != AUDIO_STREAM_VOICE_CALL) { 134029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("startTone: illegal stream (%d) requested for tone %d", stream, 1341e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten tone); 13426e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 1343fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING, 1344fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin AUDIO_STREAM_VOICE_CALL); 1345fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return 0; 1346fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1347fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1348fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::stopTone() 1349fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 1350fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mTonePlaybackThread->stopToneCommand(); 1351fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return 0; 1352fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1353fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1354fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setVoiceVolume(float volume, int delayMs) 1355fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 1356fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 1357fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1358fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1359fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinextern "C" { 13602d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_module_handle_t aps_load_hw_module(void *service __unused, 13612d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *name); 13622d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output(void *service __unused, 1363a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1364a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1365a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 1366a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 1367a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pLatencyMs, 13682d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_output_flags_t flags); 1369fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 13702d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output_on_module(void *service __unused, 1371a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_module_handle_t module, 1372a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1373a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1374a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 1375a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 1376a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pLatencyMs, 1377ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald audio_output_flags_t flags, 13782d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const audio_offload_info_t *offloadInfo); 13792d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_dup_output(void *service __unused, 1380fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t output1, 13812d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_io_handle_t output2); 13822d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_output(void *service __unused, audio_io_handle_t output); 13832d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_suspend_output(void *service __unused, audio_io_handle_t output); 13842d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_restore_output(void *service __unused, audio_io_handle_t output); 13852d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input(void *service __unused, 1386a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1387a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1388a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 1389a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 13902d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_in_acoustics_t acoustics __unused); 13912d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input_on_module(void *service __unused, 1392a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_module_handle_t module, 1393a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1394a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1395a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 13962d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_channel_mask_t *pChannelMask); 13972d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_input(void *service __unused, audio_io_handle_t input); 13982d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_invalidate_stream(void *service __unused, audio_stream_type_t stream); 1399d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastenint aps_move_effects(void *service __unused, audio_session_t session, 1400fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t src_output, 14012d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_io_handle_t dst_output); 14022d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentchar * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle, 14032d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *keys); 14042d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentvoid aps_set_parameters(void *service, audio_io_handle_t io_handle, 14052d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *kv_pairs, int delay_ms); 14062d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_stream_volume(void *service, audio_stream_type_t stream, 1407fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin float volume, audio_io_handle_t output, 14082d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent int delay_ms); 14092d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_start_tone(void *service, audio_policy_tone_t tone, 14102d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_stream_type_t stream); 14112d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_stop_tone(void *service); 14122d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_voice_volume(void *service, float volume, int delay_ms); 14132d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent}; 1414fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 14151b2a794a27caab3a1320d22b872b04ef73e96555Mikhail Naganov} // namespace android 1416