AudioPolicyService.cpp revision 61a4fac2e3ec271241e3a4f405d7357b7f6ca4c2
165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian/* 265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Copyright (C) 2009 The Android Open Source Project 365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * 465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * you may not use this file except in compliance with the License. 665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * You may obtain a copy of the License at 765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * 865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * 1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Unless required by applicable law or agreed to in writing, software 1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * See the License for the specific language governing permissions and 1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * limitations under the License. 1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian */ 1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "AudioPolicyService" 1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//#define LOG_NDEBUG 0 1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 20153b9fe667e6e78e0218ff0159353097428c7657Glenn Kasten#include "Configuration.h" 2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#undef __STRICT_ANSI__ 2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define __STDINT_LIMITS 2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define __STDC_LIMIT_MACROS 2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <stdint.h> 2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/time.h> 2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h> 2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h> 2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/properties.h> 3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h> 3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h> 3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/threads.h> 3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioPolicyService.h" 3444deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten#include "ServiceUtilities.h" 3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware_legacy/power.h> 367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent#include <media/AudioEffect.h> 37c84d9d235679a4d48245b316b7b2e4c0b19413e7Chih-Hung Hsieh#include <media/AudioParameter.h> 3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3964760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h> 407394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin#include <system/audio_policy.h> 4161a4fac2e3ec271241e3a4f405d7357b7f6ca4c2Mikhail Naganov 4261a4fac2e3ec271241e3a4f405d7357b7f6ca4c2Mikhail Naganov#ifdef USE_LEGACY_AUDIO_POLICY 4361a4fac2e3ec271241e3a4f405d7357b7f6ca4c2Mikhail Naganov#include <hardware/hardware.h> 44fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <hardware/audio_policy.h> 4561a4fac2e3ec271241e3a4f405d7357b7f6ca4c2Mikhail Naganov#endif 46fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android { 4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 498dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n"; 508dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n"; 5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50; 5322ecc912a87099cff8cadc424cd12f85c118673fGlenn Kastenstatic const int kDumpLockSleepUs = 20000; 5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 550ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatic const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds 565fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher 57fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten#ifdef USE_LEGACY_AUDIO_POLICY 58fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinnamespace { 59fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin extern struct audio_policy_service_ops aps_ops; 60fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}; 61fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten#endif 62fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioPolicyService() 66dce54a1492c410ad0d93253b341fb33305337505Eric Laurent : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL), 67bb6c9a05840d924b502ce0f1868fca4881ada1edEric Laurent mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID) 6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 69f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent} 70f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent 71f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurentvoid AudioPolicyService::onFirstRef() 72f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent{ 738b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent { 748b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 75935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent 768b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start tone playback thread 778b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this); 788b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start audio commands thread 798b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this); 808b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent // start output activity command thread 818b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this); 82dce54a1492c410ad0d93253b341fb33305337505Eric Laurent 83dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#ifdef USE_LEGACY_AUDIO_POLICY 848b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGI("AudioPolicyService CSTOR in legacy mode"); 858b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent 868b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent /* instantiate the audio policy manager */ 87fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten const struct hw_module_t *module; 88fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten int rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module); 898b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent if (rc) { 908b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent return; 918b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 928b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent rc = audio_policy_dev_open(module, &mpAudioPolicyDev); 938b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc)); 948b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent if (rc) { 958b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent return; 968b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 978b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent 988b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this, 998b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent &mpAudioPolicy); 1008b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc)); 1018b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent if (rc) { 1028b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent return; 1038b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 1048b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent 1058b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent rc = mpAudioPolicy->init_check(mpAudioPolicy); 1068b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc)); 1078b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent if (rc) { 1088b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent return; 1098b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 1108b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGI("Loaded audio policy from %s (%s)", module->name, module->id); 111dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#else 1128b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent ALOGI("AudioPolicyService CSTOR in new mode"); 113dce54a1492c410ad0d93253b341fb33305337505Eric Laurent 1148b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyClient = new AudioPolicyClient(this); 1158b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); 116dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#endif 1178b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 118ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // load audio processing modules 1198b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects(); 1208b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent { 1218b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 1228b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mAudioPolicyEffects = audioPolicyEffects; 1238b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent } 12465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 12665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::~AudioPolicyService() 12765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 12865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mTonePlaybackThread->exit(); 12965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommandThread->exit(); 130657ff61389d7316f798d4abe03efac56fd528d91Eric Laurent mOutputCommandThread->exit(); 1317c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent 132dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#ifdef USE_LEGACY_AUDIO_POLICY 1336e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (mpAudioPolicy != NULL && mpAudioPolicyDev != NULL) { 134fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy); 1356e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 1366e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (mpAudioPolicyDev != NULL) { 137fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_policy_dev_close(mpAudioPolicyDev); 1386e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 139dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#else 140f269b8e0e9ab950fc6652b9594b7a3431c81630cEric Laurent destroyAudioPolicyManager(mAudioPolicyManager); 141dce54a1492c410ad0d93253b341fb33305337505Eric Laurent delete mAudioPolicyClient; 142dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#endif 143b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 144b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.clear(); 145ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mAudioPolicyEffects.clear(); 146b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 147b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 148b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// A notification client is always registered by AudioSystem when the client process 149b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// connects to AudioPolicyService. 150b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client) 151b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 152125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent if (client == 0) { 153125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent ALOGW("%s got NULL client", __FUNCTION__); 154125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent return; 155125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent } 1560ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 157b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 158b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid_t uid = IPCThreadState::self()->getCallingUid(); 159b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (mNotificationClients.indexOfKey(uid) < 0) { 160b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<NotificationClient> notificationClient = new NotificationClient(this, 161b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent client, 162b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid); 163b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("registerClient() client %p, uid %d", client.get(), uid); 164b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 165b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.add(uid, notificationClient); 166b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 167f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen sp<IBinder> binder = IInterface::asBinder(client); 168b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent binder->linkToDeath(notificationClient); 169b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 170b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 171b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 172e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurentvoid AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled) 173e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent{ 174e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent Mutex::Autolock _l(mNotificationClientsLock); 175e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 176e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent uid_t uid = IPCThreadState::self()->getCallingUid(); 177e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (mNotificationClients.indexOfKey(uid) < 0) { 178e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent return; 179e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent } 180e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled); 181e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent} 182e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 183b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// removeNotificationClient() is called when the client process dies. 184b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::removeNotificationClient(uid_t uid) 185b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 1860ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent { 1870ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 1880ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent mNotificationClients.removeItem(uid); 1890ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent } 190b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent#ifndef USE_LEGACY_AUDIO_POLICY 1910ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent { 1920ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mLock); 193b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (mAudioPolicyManager) { 1948c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent mAudioPolicyManager->releaseResourcesForUid(uid); 195b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 1960ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent } 197b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent#endif 198b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 199b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 200b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPortListUpdate() 201b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 202b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mOutputCommandThread->updateAudioPortListCommand(); 203b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 204b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 205b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPortListUpdate() 206b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 2070ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 208b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent for (size_t i = 0; i < mNotificationClients.size(); i++) { 209b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.valueAt(i)->onAudioPortListUpdate(); 210b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 211b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 212b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 213b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPatchListUpdate() 214b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 215b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mOutputCommandThread->updateAudioPatchListCommand(); 21665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 21765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 218b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPatchListUpdate() 219b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 2200ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent Mutex::Autolock _l(mNotificationClientsLock); 221b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent for (size_t i = 0; i < mNotificationClients.size(); i++) { 222b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mNotificationClients.valueAt(i)->onAudioPatchListUpdate(); 223b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 224b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 225b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 226e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state) 227de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 228de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)", 229de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi regId.string(), state); 230de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state); 231de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 232de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 233e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state) 234de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 235de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi Mutex::Autolock _l(mNotificationClientsLock); 236de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi for (size_t i = 0; i < mNotificationClients.size(); i++) { 237de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state); 238de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 239de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 240de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 2412f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::onRecordingConfigurationUpdate(int event, audio_session_t session, 2427281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi audio_source_t source, const audio_config_base_t *clientConfig, 2438c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) 2442f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 2457281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi mOutputCommandThread->recordingConfigurationUpdateCommand(event, session, source, 2468c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi clientConfig, deviceConfig, patchHandle); 2472f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2482f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 2492f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::doOnRecordingConfigurationUpdate(int event, audio_session_t session, 2507281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi audio_source_t source, const audio_config_base_t *clientConfig, 2518c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) 2522f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 2532f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi Mutex::Autolock _l(mNotificationClientsLock); 2542f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi for (size_t i = 0; i < mNotificationClients.size(); i++) { 2557281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, session, source, 2568c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi clientConfig, deviceConfig, patchHandle); 2572f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } 2582f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2592f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 2602f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivistatus_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch, 2612f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi audio_patch_handle_t *handle, 2622f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi int delayMs) 2632f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 2642f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs); 2652f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2662f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 2672f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivistatus_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle, 2682f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi int delayMs) 2692f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 2702f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs); 2712f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 2722f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 273e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config, 274e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent int delayMs) 275e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{ 276e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); 277e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent} 278e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 279b52c152d553556b2d227ffc943489de0c60b4b02Eric LaurentAudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service, 280b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent const sp<IAudioPolicyServiceClient>& client, 281b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent uid_t uid) 282e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent : mService(service), mUid(uid), mAudioPolicyServiceClient(client), 283e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mAudioPortCallbacksEnabled(false) 284b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 285b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 286b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 287b52c152d553556b2d227ffc943489de0c60b4b02Eric LaurentAudioPolicyService::NotificationClient::~NotificationClient() 288b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 289b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 290b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 291b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused) 292b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 293b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<NotificationClient> keep(this); 294b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<AudioPolicyService> service = mService.promote(); 295b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (service != 0) { 296b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent service->removeNotificationClient(mUid); 297b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 298b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 299b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 300b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::onAudioPortListUpdate() 301b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 302e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 303b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mAudioPolicyServiceClient->onAudioPortListUpdate(); 304b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 305b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 306b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 307b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::onAudioPatchListUpdate() 308b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 309e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { 310b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mAudioPolicyServiceClient->onAudioPatchListUpdate(); 311b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 312b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 31357dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent 314de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivivoid AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( 315e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const String8& regId, int32_t state) 316de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 317de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi if (mAudioPolicyServiceClient != 0) { 3182f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state); 3192f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } 3202f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 3212f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 3222f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate( 3237281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi int event, audio_session_t session, audio_source_t source, 3248c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, 3258c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi audio_patch_handle_t patchHandle) 3262f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 3272f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi if (mAudioPolicyServiceClient != 0) { 3287281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, session, source, 3298c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi clientConfig, deviceConfig, patchHandle); 330de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 331de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 332de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 333e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurentvoid AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled) 334e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent{ 335e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mAudioPortCallbacksEnabled = enabled; 336e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent} 337e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 338e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent 33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::binderDied(const wp<IBinder>& who) { 340411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), 341de070137f11d346fba77605bd76a44c040a618fcEric Laurent IPCThreadState::self()->getCallingPid()); 34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex) 34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 34665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = false; 34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < kDumpLockRetries; ++i) { 34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mutex.tryLock() == NO_ERROR) { 34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian locked = true; 35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 35222ecc912a87099cff8cadc424cd12f85c118673fGlenn Kasten usleep(kDumpLockSleepUs); 35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return locked; 35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpInternals(int fd) 35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 363dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#ifdef USE_LEGACY_AUDIO_POLICY 364fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy); 365dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#else 366dce54a1492c410ad0d93253b341fb33305337505Eric Laurent snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager); 367dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#endif 36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); 37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); 37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3780f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused) 37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 38044deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten if (!dumpAllowed()) { 38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dumpPermissionDenial(fd); 38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = tryLock(mLock); 38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!locked) { 38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result(kDeadlockedString); 38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dumpInternals(fd); 3909d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten if (mAudioCommandThread != 0) { 39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommandThread->dump(fd); 39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 3939d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten if (mTonePlaybackThread != 0) { 39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mTonePlaybackThread->dump(fd); 39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 39665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 397dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#ifdef USE_LEGACY_AUDIO_POLICY 398fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mpAudioPolicy) { 399fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mpAudioPolicy->dump(mpAudioPolicy, fd); 40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 401dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#else 402dce54a1492c410ad0d93253b341fb33305337505Eric Laurent if (mAudioPolicyManager) { 403dce54a1492c410ad0d93253b341fb33305337505Eric Laurent mAudioPolicyManager->dump(fd); 404dce54a1492c410ad0d93253b341fb33305337505Eric Laurent } 405dce54a1492c410ad0d93253b341fb33305337505Eric Laurent#endif 40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (locked) mLock.unlock(); 40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 40965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 41265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpPermissionDenial(int fd) 41365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 41465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 41765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Permission Denial: " 41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian "can't dump AudioPolicyService from pid=%d, uid=%d\n", 41965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState::self()->getCallingPid(), 42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState::self()->getCallingUid()); 42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::onTransact( 42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return BnAudioPolicyService::onTransact(code, data, reply, flags); 43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 43165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 43265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 43365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------- AudioPolicyService::AudioCommandThread implementation ---------- 43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 435bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name, 436bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent const wp<AudioPolicyService>& service) 437bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent : Thread(false), mName(name), mService(service) 43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 43965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = NULL; 44065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 44165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioCommandThread::~AudioCommandThread() 44465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 445bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (!mAudioCommands.isEmpty()) { 44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian release_wake_lock(mName.string()); 44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 44865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.clear(); 449e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten delete mpToneGenerator; 45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 45165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::onFirstRef() 45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 454bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent run(mName.string(), ANDROID_PRIORITY_AUDIO); 45565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 45665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioPolicyService::AudioCommandThread::threadLoop() 45865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 459d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent nsecs_t waitTime = -1; 46065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 46165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 46265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian while (!exitPending()) 46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 46459a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent sp<AudioPolicyService> svc; 46559a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent while (!mAudioCommands.isEmpty() && !exitPending()) { 46665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian nsecs_t curTime = systemTime(); 46765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // commands are sorted by increasing time stamp: execute them from index 0 and up 46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mAudioCommands[0]->mTime <= curTime) { 4690ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = mAudioCommands[0]; 47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.removeAt(0); 4710ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mLastCommand = command; 47265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 47365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (command->mCommand) { 47465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case START_TONE: { 47565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 4760ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ToneData *data = (ToneData *)command->mParam.get(); 4773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing start tone %d on stream %d", 47865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mType, data->mStream); 479e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten delete mpToneGenerator; 48065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = new ToneGenerator(data->mStream, 1.0); 48165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator->startTone(data->mType); 48265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 48365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 48465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case STOP_TONE: { 48565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 4863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing stop tone"); 48765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mpToneGenerator != NULL) { 48865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator->stopTone(); 48965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian delete mpToneGenerator; 49065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mpToneGenerator = NULL; 49165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 49265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.lock(); 49365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 49465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOLUME: { 4950ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data = (VolumeData *)command->mParam.get(); 4963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing set volume stream %d, \ 497de070137f11d346fba77605bd76a44c040a618fcEric Laurent volume %f, output %d", data->mStream, data->mVolume, data->mIO); 498de070137f11d346fba77605bd76a44c040a618fcEric Laurent command->mStatus = AudioSystem::setStreamVolume(data->mStream, 499de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mVolume, 500de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mIO); 50165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 50265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_PARAMETERS: { 5030ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data = (ParametersData *)command->mParam.get(); 504e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten ALOGV("AudioCommandThread() processing set parameters string %s, io %d", 505e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten data->mKeyValuePairs.string(), data->mIO); 506e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); 507e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten }break; 50865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOICE_VOLUME: { 5090ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 5103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() processing set voice volume volume %f", 511de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mVolume); 51265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); 51365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }break; 514bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent case STOP_OUTPUT: { 5150ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent StopOutputData *data = (StopOutputData *)command->mParam.get(); 516bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() processing stop output %d", 517bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO); 51859a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 519bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (svc == 0) { 520bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 521bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 522bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 523bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent svc->doStopOutput(data->mIO, data->mStream, data->mSession); 524bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 525bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent }break; 526bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent case RELEASE_OUTPUT: { 5270ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get(); 528bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() processing release output %d", 529bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO); 53059a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 531bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (svc == 0) { 532bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 533bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 534bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 535e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent svc->doReleaseOutput(data->mIO, data->mStream, data->mSession); 536bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 537bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent }break; 538951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent case CREATE_AUDIO_PATCH: { 539951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get(); 540951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() processing create audio patch"); 541951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 542951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (af == 0) { 543951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = PERMISSION_DENIED; 544951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } else { 545951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle); 546951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 547951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } break; 548951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent case RELEASE_AUDIO_PATCH: { 549951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get(); 550951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() processing release audio patch"); 551951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 552951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (af == 0) { 553951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = PERMISSION_DENIED; 554951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } else { 555951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mStatus = af->releaseAudioPatch(data->mHandle); 556951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 557951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } break; 558b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent case UPDATE_AUDIOPORT_LIST: { 559b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() processing update audio port list"); 56059a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 561b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (svc == 0) { 562b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent break; 563b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 564b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.unlock(); 565b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent svc->doOnAudioPortListUpdate(); 566b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.lock(); 567b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent }break; 568b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent case UPDATE_AUDIOPATCH_LIST: { 569b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() processing update audio patch list"); 57059a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent svc = mService.promote(); 571b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent if (svc == 0) { 572b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent break; 573b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent } 574b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.unlock(); 575b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent svc->doOnAudioPatchListUpdate(); 576b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mLock.lock(); 577b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent }break; 578e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent case SET_AUDIOPORT_CONFIG: { 579e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get(); 580e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("AudioCommandThread() processing set port config"); 581e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 582e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (af == 0) { 583e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mStatus = PERMISSION_DENIED; 584e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 585e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mStatus = af->setAudioPortConfig(&data->mConfig); 586e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 587e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } break; 588de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi case DYN_POLICY_MIX_STATE_UPDATE: { 589de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi DynPolicyMixStateUpdateData *data = 590de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi (DynPolicyMixStateUpdateData *)command->mParam.get(); 591de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d", 592de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi data->mRegId.string(), data->mState); 593de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi svc = mService.promote(); 594de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi if (svc == 0) { 595de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi break; 596de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 597de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mLock.unlock(); 598de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState); 599de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mLock.lock(); 600de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } break; 6012f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi case RECORDING_CONFIGURATION_UPDATE: { 6022f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi RecordingConfigurationUpdateData *data = 6032f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi (RecordingConfigurationUpdateData *)command->mParam.get(); 6042f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi ALOGV("AudioCommandThread() processing recording configuration update"); 6052f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi svc = mService.promote(); 6062f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi if (svc == 0) { 6072f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi break; 6082f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } 6092f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi mLock.unlock(); 6102f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi svc->doOnRecordingConfigurationUpdate(data->mEvent, data->mSession, 6118c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi data->mSource, &data->mClientConfig, &data->mDeviceConfig, 6128c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi data->mPatchHandle); 6132f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi mLock.lock(); 6142f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } break; 61565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 6165ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AudioCommandThread() unknown command %d", command->mCommand); 61765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 6180ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent { 6190ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(command->mLock); 6200ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (command->mWaitStatus) { 6210ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = false; 6220ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mCond.signal(); 6230ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 6240ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 625d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent waitTime = -1; 626a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // release mLock before releasing strong reference on the service as 627a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // AudioPolicyService destructor calls AudioCommandThread::exit() which 628a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // acquires mLock. 629a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang mLock.unlock(); 630a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang svc.clear(); 631a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang mLock.lock(); 63265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 63365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian waitTime = mAudioCommands[0]->mTime - curTime; 63465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 63565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 637a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang 638a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // release delayed commands wake lock if the queue is empty 639a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang if (mAudioCommands.isEmpty()) { 64005f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia release_wake_lock(mName.string()); 641a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang } 642a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang 643a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // At this stage we have either an empty command queue or the first command in the queue 644a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // has a finite delay. So unless we are exiting it is safe to wait. 645a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang if (!exitPending()) { 64659a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent ALOGV("AudioCommandThread() going to sleep"); 647d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent if (waitTime == -1) { 648d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent mWaitWorkCV.wait(mLock); 649d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent } else { 650d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent mWaitWorkCV.waitRelative(mLock, waitTime); 651d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent } 65259a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent } 65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 65405f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia // release delayed commands wake lock before quitting 65505f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia if (!mAudioCommands.isEmpty()) { 65605f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia release_wake_lock(mName.string()); 65705f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia } 65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return false; 66065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 66165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 66265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::dump(int fd) 66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 66565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 66765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 66865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 67265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = tryLock(mLock); 67365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!locked) { 67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result2(kCmdDeadlockedString); 67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result2.string(), result2.size()); 67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "- Commands:\n"); 67965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = String8(buffer); 68065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(" Command Time Wait pParam\n"); 6818d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten for (size_t i = 0; i < mAudioCommands.size(); i++) { 68265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands[i]->dump(buffer, SIZE); 68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(" Last Command\n"); 6860ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (mLastCommand != 0) { 6870ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mLastCommand->dump(buffer, SIZE); 6880ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent result.append(buffer); 6890ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } else { 6900ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent result.append(" none\n"); 6910ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 69465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (locked) mLock.unlock(); 69665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 69765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 69865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 69965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 7003d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kastenvoid AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type, 7013d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kasten audio_stream_type_t stream) 70265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 7030ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 70465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = START_TONE; 7050ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ToneData> data = new ToneData(); 70665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mType = type; 70765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mStream = stream; 70848412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 7093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 7100ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 71165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 71265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 71365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::stopToneCommand() 71465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 7150ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 71665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = STOP_TONE; 7173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding tone stop"); 7180ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 71965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 72065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 721fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream, 722de070137f11d346fba77605bd76a44c040a618fcEric Laurent float volume, 72372ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten audio_io_handle_t output, 724de070137f11d346fba77605bd76a44c040a618fcEric Laurent int delayMs) 72565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 7260ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 72765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_VOLUME; 7280ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<VolumeData> data = new VolumeData(); 72965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mStream = stream; 73065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mVolume = volume; 73165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mIO = output; 73265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 7330ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 7343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 735de070137f11d346fba77605bd76a44c040a618fcEric Laurent stream, volume, output); 7360ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 73765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 73865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 73972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle, 740fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin const char *keyValuePairs, 741de070137f11d346fba77605bd76a44c040a618fcEric Laurent int delayMs) 74265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 7430ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 74465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_PARAMETERS; 7450ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ParametersData> data = new ParametersData(); 74665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mIO = ioHandle; 747fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin data->mKeyValuePairs = String8(keyValuePairs); 74865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 7490ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 7503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 751fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin keyValuePairs, ioHandle, delayMs); 7520ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 75365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 75465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 75565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 75665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 7570ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 75865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mCommand = SET_VOICE_VOLUME; 7590ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<VoiceVolumeData> data = new VoiceVolumeData(); 76065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data->mVolume = volume; 76165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mParam = data; 7620ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = true; 7633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread() adding set voice volume volume %f", volume); 7640ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return sendCommand(command, delayMs); 76565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 76665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 767bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output, 768bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent audio_stream_type_t stream, 769e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_session_t session) 770bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 7710ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 772bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent command->mCommand = STOP_OUTPUT; 7730ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<StopOutputData> data = new StopOutputData(); 774bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO = output; 775bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mStream = stream; 776bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mSession = session; 77748412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 778bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() adding stop output %d", output); 7790ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 780bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 781bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 782e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentvoid AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output, 783e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_stream_type_t stream, 784e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_session_t session) 785bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 7860ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command = new AudioCommand(); 787bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent command->mCommand = RELEASE_OUTPUT; 7880ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<ReleaseOutputData> data = new ReleaseOutputData(); 789bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent data->mIO = output; 790e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent data->mStream = stream; 791e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent data->mSession = session; 79248412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh command->mParam = data; 793bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AudioCommandThread() adding release output %d", output); 7940ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sendCommand(command); 7950ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent} 7960ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent 797951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand( 798951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent const struct audio_patch *patch, 799951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent audio_patch_handle_t *handle, 800951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent int delayMs) 801951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{ 802951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent status_t status = NO_ERROR; 803951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 804951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<AudioCommand> command = new AudioCommand(); 805951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mCommand = CREATE_AUDIO_PATCH; 806951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent CreateAudioPatchData *data = new CreateAudioPatchData(); 807951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mPatch = *patch; 808951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mHandle = *handle; 809951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mParam = data; 810951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mWaitStatus = true; 811951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() adding create patch delay %d", delayMs); 812951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent status = sendCommand(command, delayMs); 813951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent if (status == NO_ERROR) { 814951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent *handle = data->mHandle; 815951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent } 816951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent return status; 817951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent} 818951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 819951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle, 820951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent int delayMs) 821951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{ 822951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent sp<AudioCommand> command = new AudioCommand(); 823951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mCommand = RELEASE_AUDIO_PATCH; 824951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ReleaseAudioPatchData *data = new ReleaseAudioPatchData(); 825951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent data->mHandle = handle; 826951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mParam = data; 827951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent command->mWaitStatus = true; 828951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent ALOGV("AudioCommandThread() adding release patch delay %d", delayMs); 829951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent return sendCommand(command, delayMs); 830951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent} 831951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent 832b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPortListCommand() 833b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 834b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<AudioCommand> command = new AudioCommand(); 835b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent command->mCommand = UPDATE_AUDIOPORT_LIST; 836b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() adding update audio port list"); 837b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sendCommand(command); 838b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 839b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 840b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand() 841b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{ 842b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sp<AudioCommand>command = new AudioCommand(); 843b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent command->mCommand = UPDATE_AUDIOPATCH_LIST; 844b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent ALOGV("AudioCommandThread() adding update audio patch list"); 845b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent sendCommand(command); 846b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent} 847b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent 848e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand( 849e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent const struct audio_port_config *config, int delayMs) 850e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{ 851e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent sp<AudioCommand> command = new AudioCommand(); 852e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mCommand = SET_AUDIOPORT_CONFIG; 853e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent SetAudioPortConfigData *data = new SetAudioPortConfigData(); 854e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent data->mConfig = *config; 855e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mParam = data; 856e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent command->mWaitStatus = true; 857e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("AudioCommandThread() adding set port config delay %d", delayMs); 858e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return sendCommand(command, delayMs); 859e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent} 860e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 861de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivivoid AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( 862e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const String8& regId, int32_t state) 863de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{ 864de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi sp<AudioCommand> command = new AudioCommand(); 865de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi command->mCommand = DYN_POLICY_MIX_STATE_UPDATE; 866de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData(); 867de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi data->mRegId = regId; 868de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi data->mState = state; 869de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi command->mParam = data; 870de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d", 871de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi regId.string(), state); 872de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi sendCommand(command); 873de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi} 874de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 8752f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand( 8767281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi int event, audio_session_t session, audio_source_t source, 8778c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, 8788c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi audio_patch_handle_t patchHandle) 8792f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{ 8802f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi sp<AudioCommand>command = new AudioCommand(); 8812f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi command->mCommand = RECORDING_CONFIGURATION_UPDATE; 8822f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData(); 8832f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi data->mEvent = event; 8842f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi data->mSession = session; 8852f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi data->mSource = source; 8867281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi data->mClientConfig = *clientConfig; 8877281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi data->mDeviceConfig = *deviceConfig; 8888c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi data->mPatchHandle = patchHandle; 8892f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi command->mParam = data; 8902f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d", 8912f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi event, source); 8922f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi sendCommand(command); 8932f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi} 8942f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 8950ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatus_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) 8960ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent{ 8970ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent { 8980ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(mLock); 8990ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent insertCommand_l(command, delayMs); 9000ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mWaitWorkCV.signal(); 9010ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 9020ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Mutex::Autolock _l(command->mLock); 9030ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent while (command->mWaitStatus) { 9040ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs); 9050ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) { 9060ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mStatus = TIMED_OUT; 9070ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent command->mWaitStatus = false; 9080ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 9090ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent } 9100ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent return command->mStatus; 911bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 912bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// insertCommand_l() must be called with mLock held 9140ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentvoid AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs) 91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 9168d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten ssize_t i; // not size_t because i will count down to -1 9170ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent Vector < sp<AudioCommand> > removedCommands; 91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian command->mTime = systemTime() + milliseconds(delayMs); 91965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 92065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // acquire wake lock to make sure delayed commands are processed 921bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mAudioCommands.isEmpty()) { 92265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 92365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 92465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 92565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // check same pending commands with later time stamps and eliminate them 92665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (i = mAudioCommands.size()-1; i >= 0; i--) { 9270ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent sp<AudioCommand> command2 = mAudioCommands[i]; 92865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 92965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (command2->mTime <= command->mTime) break; 930e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 931e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // create audio patch or release audio patch commands are equivalent 932e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // with regard to filtering 933e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if ((command->mCommand == CREATE_AUDIO_PATCH) || 934e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command->mCommand == RELEASE_AUDIO_PATCH)) { 935e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if ((command2->mCommand != CREATE_AUDIO_PATCH) && 936e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command2->mCommand != RELEASE_AUDIO_PATCH)) { 937e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent continue; 938e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 939e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else if (command2->mCommand != command->mCommand) continue; 94065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 94165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (command->mCommand) { 94265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_PARAMETERS: { 9430ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data = (ParametersData *)command->mParam.get(); 9440ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent ParametersData *data2 = (ParametersData *)command2->mParam.get(); 94565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mIO != data2->mIO) break; 9463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Comparing parameter command %s to new command %s", 947de070137f11d346fba77605bd76a44c040a618fcEric Laurent data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 94865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioParameter param = AudioParameter(data->mKeyValuePairs); 94965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 95065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t j = 0; j < param.size(); j++) { 951e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 key; 952e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 value; 953e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param.getAt(j, key, value); 954e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten for (size_t k = 0; k < param2.size(); k++) { 955e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 key2; 956e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten String8 value2; 957e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param2.getAt(k, key2, value2); 958e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten if (key2 == key) { 959e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten param2.remove(key2); 960e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten ALOGV("Filtering out parameter %s", key2.string()); 961e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten break; 962e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 963e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 96465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 96565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // if all keys have been filtered out, remove the command. 96665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // otherwise, update the key value pairs 96765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (param2.size() == 0) { 96865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.add(command2); 96965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 97065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data2->mKeyValuePairs = param2.toString(); 97165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 97221e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent command->mTime = command2->mTime; 97321e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // force delayMs to non 0 so that code below does not request to wait for 97421e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // command status as the command is now delayed 97521e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent delayMs = 1; 97665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } break; 97765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 97865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case SET_VOLUME: { 9790ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data = (VolumeData *)command->mParam.get(); 9800ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent VolumeData *data2 = (VolumeData *)command2->mParam.get(); 98165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mIO != data2->mIO) break; 98265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (data->mStream != data2->mStream) break; 9833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Filtering out volume command on output %d for stream %d", 984de070137f11d346fba77605bd76a44c040a618fcEric Laurent data->mIO, data->mStream); 98565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.add(command2); 98621e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent command->mTime = command2->mTime; 98721e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // force delayMs to non 0 so that code below does not request to wait for 98821e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent // command status as the command is now delayed 98921e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent delayMs = 1; 99065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } break; 991e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 992baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent case SET_VOICE_VOLUME: { 993baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 994baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get(); 995baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent ALOGV("Filtering out voice volume command value %f replaced by %f", 996baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent data2->mVolume, data->mVolume); 997baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent removedCommands.add(command2); 998baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent command->mTime = command2->mTime; 999baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent // force delayMs to non 0 so that code below does not request to wait for 1000baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent // command status as the command is now delayed 1001baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent delayMs = 1; 1002baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent } break; 1003baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent 1004e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent case CREATE_AUDIO_PATCH: 1005e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent case RELEASE_AUDIO_PATCH: { 1006e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent audio_patch_handle_t handle; 1007a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George struct audio_patch patch; 1008e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (command->mCommand == CREATE_AUDIO_PATCH) { 1009e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle; 1010a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch; 1011e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else { 1012e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle; 1013e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 1014e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent audio_patch_handle_t handle2; 1015a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George struct audio_patch patch2; 1016e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (command2->mCommand == CREATE_AUDIO_PATCH) { 1017e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle; 1018a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch; 1019e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } else { 1020e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle; 1021f60b6b6c776a762827874f6f635c0577359a7ee4Glenn Kasten memset(&patch2, 0, sizeof(patch2)); 1022e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } 1023e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent if (handle != handle2) break; 1024a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George /* Filter CREATE_AUDIO_PATCH commands only when they are issued for 1025a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George same output. */ 1026a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if( (command->mCommand == CREATE_AUDIO_PATCH) && 1027a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George (command2->mCommand == CREATE_AUDIO_PATCH) ) { 1028a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George bool isOutputDiff = false; 1029a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if (patch.num_sources == patch2.num_sources) { 1030a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George for (unsigned count = 0; count < patch.num_sources; count++) { 1031a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if (patch.sources[count].id != patch2.sources[count].id) { 1032a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George isOutputDiff = true; 1033a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George break; 1034a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 1035a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 1036a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George if (isOutputDiff) 1037a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George break; 1038a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 1039a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George } 1040e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent ALOGV("Filtering out %s audio patch command for handle %d", 1041e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle); 1042e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent removedCommands.add(command2); 1043e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent command->mTime = command2->mTime; 1044e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // force delayMs to non 0 so that code below does not request to wait for 1045e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent // command status as the command is now delayed 1046e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent delayMs = 1; 1047e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent } break; 1048e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent 1049de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi case DYN_POLICY_MIX_STATE_UPDATE: { 1050de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 1051de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } break; 1052de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 10532f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi case RECORDING_CONFIGURATION_UPDATE: { 10542f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 10552f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi } break; 10562f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi 105765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case START_TONE: 105865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case STOP_TONE: 105965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 106065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 106165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 106265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 106365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 106465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // remove filtered commands 106565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t j = 0; j < removedCommands.size(); j++) { 106665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // removed commands always have time stamps greater than current command 106765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 10680ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent if (mAudioCommands[k].get() == removedCommands[j].get()) { 10693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 107065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.removeAt(k); 107165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 107265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 107365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 107465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 107565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian removedCommands.clear(); 107665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1077aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent // Disable wait for status if delay is not 0. 1078aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent // Except for create audio patch command because the returned patch handle 1079aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent // is needed by audio policy manager 1080aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) { 1081cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent command->mWaitStatus = false; 1082cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent } 1083cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent 108465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // insert command at the right place according to its time stamp 10851e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ALOGV("inserting command: %d at index %zd, num commands %zu", 10861e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent command->mCommand, i+1, mAudioCommands.size()); 108765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mAudioCommands.insertAt(command, i + 1); 108865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 108965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 109065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::exit() 109165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 10923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioCommandThread::exit"); 109365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 109465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AutoMutex _l(mLock); 109565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian requestExit(); 109665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mWaitWorkCV.signal(); 109765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 1098a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // Note that we can call it from the thread loop if all other references have been released 1099a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang // but it will safely return WOULD_BLOCK in this case 110065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian requestExitAndWait(); 110165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 110265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 110365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 110465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 110565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 110665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCommand, 110765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian (int)ns2s(mTime), 110865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian (int)ns2ms(mTime)%1000, 110965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mWaitStatus, 11100ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent mParam.get()); 111165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 111265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1113fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin/******* helpers for the service_ops callbacks defined below *********/ 1114fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 1115fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin const char *keyValuePairs, 1116fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int delayMs) 1117fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 111872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs, 1119fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin delayMs); 1120fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1121fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1122fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setStreamVolume(audio_stream_type_t stream, 1123fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin float volume, 1124fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t output, 1125fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int delayMs) 1126fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 1127fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten return (int)mAudioCommandThread->volumeCommand(stream, volume, 112872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten output, delayMs); 1129fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1130fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1131fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::startTone(audio_policy_tone_t tone, 1132fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_stream_type_t stream) 1133fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 11346e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) { 113529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("startTone: illegal tone requested (%d)", tone); 11366e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 11376e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten if (stream != AUDIO_STREAM_VOICE_CALL) { 113829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("startTone: illegal stream (%d) requested for tone %d", stream, 1139e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten tone); 11406e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten } 1141fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING, 1142fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin AUDIO_STREAM_VOICE_CALL); 1143fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return 0; 1144fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1145fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1146fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::stopTone() 1147fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 1148fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mTonePlaybackThread->stopToneCommand(); 1149fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return 0; 1150fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1151fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1152fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setVoiceVolume(float volume, int delayMs) 1153fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{ 1154fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 1155fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin} 1156fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1157fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinextern "C" { 11582d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_module_handle_t aps_load_hw_module(void *service __unused, 11592d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *name); 11602d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output(void *service __unused, 1161a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1162a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1163a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 1164a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 1165a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pLatencyMs, 11662d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_output_flags_t flags); 1167fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 11682d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output_on_module(void *service __unused, 1169a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_module_handle_t module, 1170a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1171a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1172a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 1173a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 1174a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pLatencyMs, 1175ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald audio_output_flags_t flags, 11762d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const audio_offload_info_t *offloadInfo); 11772d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_dup_output(void *service __unused, 1178fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t output1, 11792d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_io_handle_t output2); 11802d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_output(void *service __unused, audio_io_handle_t output); 11812d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_suspend_output(void *service __unused, audio_io_handle_t output); 11822d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_restore_output(void *service __unused, audio_io_handle_t output); 11832d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input(void *service __unused, 1184a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1185a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1186a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 1187a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_channel_mask_t *pChannelMask, 11882d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_in_acoustics_t acoustics __unused); 11892d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input_on_module(void *service __unused, 1190a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_module_handle_t module, 1191a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_devices_t *pDevices, 1192a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent uint32_t *pSamplingRate, 1193a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent audio_format_t *pFormat, 11942d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_channel_mask_t *pChannelMask); 11952d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_input(void *service __unused, audio_io_handle_t input); 11962d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_invalidate_stream(void *service __unused, audio_stream_type_t stream); 1197d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastenint aps_move_effects(void *service __unused, audio_session_t session, 1198fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin audio_io_handle_t src_output, 11992d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_io_handle_t dst_output); 12002d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentchar * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle, 12012d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *keys); 12022d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentvoid aps_set_parameters(void *service, audio_io_handle_t io_handle, 12032d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent const char *kv_pairs, int delay_ms); 12042d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_stream_volume(void *service, audio_stream_type_t stream, 1205fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin float volume, audio_io_handle_t output, 12062d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent int delay_ms); 12072d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_start_tone(void *service, audio_policy_tone_t tone, 12082d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent audio_stream_type_t stream); 12092d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_stop_tone(void *service); 12102d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_voice_volume(void *service, float volume, int delay_ms); 12112d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent}; 1212fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 1213fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten#ifdef USE_LEGACY_AUDIO_POLICY 1214fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinnamespace { 1215fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin struct audio_policy_service_ops aps_ops = { 121601d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .open_output = aps_open_output, 121701d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .open_duplicate_output = aps_open_dup_output, 121801d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .close_output = aps_close_output, 121901d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .suspend_output = aps_suspend_output, 122001d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .restore_output = aps_restore_output, 122101d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .open_input = aps_open_input, 122201d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .close_input = aps_close_input, 122301d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .set_stream_volume = aps_set_stream_volume, 1224d2304db2fcb5112292105a0949a55986a4c9875fGlenn Kasten .invalidate_stream = aps_invalidate_stream, 122501d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .set_parameters = aps_set_parameters, 122601d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .get_parameters = aps_get_parameters, 122701d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .start_tone = aps_start_tone, 122801d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .stop_tone = aps_stop_tone, 122901d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .set_voice_volume = aps_set_voice_volume, 123001d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .move_effects = aps_move_effects, 123101d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .load_hw_module = aps_load_hw_module, 123201d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .open_output_on_module = aps_open_output_on_module, 123301d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten .open_input_on_module = aps_open_input_on_module, 1234fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin }; 1235fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}; // namespace <unnamed> 1236fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten#endif 1237fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 123865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android 1239