AudioPolicyService.cpp revision a7e04803ffa0d8d4cc51a122f68bf5038422aabb
19258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org/* 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Copyright (C) 2009 The Android Open Source Project 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Licensed under the Apache License, Version 2.0 (the "License"); 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * you may not use this file except in compliance with the License. 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * You may obtain a copy of the License at 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * http://www.apache.org/licenses/LICENSE-2.0 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Unless required by applicable law or agreed to in writing, software 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * distributed under the License is distributed on an "AS IS" BASIS, 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * See the License for the specific language governing permissions and 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * limitations under the License. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen */ 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define LOG_TAG "AudioPolicyService" 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//#define LOG_NDEBUG 0 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "Configuration.h" 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef __STRICT_ANSI__ 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define __STDINT_LIMITS 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define __STDC_LIMIT_MACROS 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <stdint.h> 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <sys/time.h> 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <binder/IServiceManager.h> 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <utils/Log.h> 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <cutils/properties.h> 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <binder/IPCThreadState.h> 319d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com#include <utils/String16.h> 32ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#include <utils/threads.h> 339d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com#include "AudioPolicyService.h" 3471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#include "ServiceUtilities.h" 3571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#include <hardware_legacy/power.h> 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <media/AudioEffect.h> 37a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <media/EffectsFactoryApi.h> 38a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 39a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <hardware/hardware.h> 40a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <system/audio.h> 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <system/audio_policy.h> 4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <hardware/audio_policy.h> 4368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 4468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgnamespace android { 45c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 4668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgstatic const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n"; 47c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.orgstatic const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n"; 48c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 49bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic const int kDumpLockRetries = 50; 50bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic const int kDumpLockSleepUs = 20000; 5168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds 5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 549a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comnamespace { 559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com extern struct audio_policy_service_ops aps_ops; 5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenAudioPolicyService::AudioPolicyService() 6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL), 6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mAudioPolicyManager(NULL), mAudioPolicyClient(NULL) 6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen{ 648bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org char value[PROPERTY_VALUE_MAX]; 658bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org const struct hw_module_t *module; 668bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org int forced_val; 677be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org int rc; 6841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 6941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org Mutex::Autolock _l(mLock); 7041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 7143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // start tone playback thread 7243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this); 7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // start audio commands thread 7441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this); 7541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // start output activity command thread 767be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this); 777be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef USE_LEGACY_AUDIO_POLICY 798bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org ALOGI("AudioPolicyService CSTOR in legacy mode"); 80cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org 81cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org /* instantiate the audio policy manager */ 82cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module); 83cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org if (rc) { 84a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 85a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 867be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org rc = audio_policy_dev_open(module, &mpAudioPolicyDev); 877be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc)); 887be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org if (rc) { 897be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org return; 907be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org } 9141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 9241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this, 937be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org &mpAudioPolicy); 947be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc)); 9541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org if (rc) { 96cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org return; 97cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org } 98cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org 99cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org rc = mpAudioPolicy->init_check(mpAudioPolicy); 100cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc)); 101cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org if (rc) { 102cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org return; 103cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org } 104cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org ALOGI("Loaded audio policy from %s (%s)", module->name, module->id); 105cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org#else 106cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org ALOGI("AudioPolicyService CSTOR in new mode"); 107cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org 108cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org mAudioPolicyClient = new AudioPolicyClient(this); 109cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); 110cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org#endif 111cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org 112cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org // load audio processing modules 113cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org mAudioPolicyEffects = new AudioPolicyEffects(); 114cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org} 115cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org 116cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.orgAudioPolicyService::~AudioPolicyService() 117cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org{ 118cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org mTonePlaybackThread->exit(); 119a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mAudioCommandThread->exit(); 12041826e77311db718135ef6517b846933dfd275f3ager@chromium.org mOutputCommandThread->exit(); 12141826e77311db718135ef6517b846933dfd275f3ager@chromium.org 12241826e77311db718135ef6517b846933dfd275f3ager@chromium.org#ifdef USE_LEGACY_AUDIO_POLICY 123a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (mpAudioPolicy != NULL && mpAudioPolicyDev != NULL) { 124a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy); 1257be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org } 1267be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org if (mpAudioPolicyDev != NULL) { 127a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_policy_dev_close(mpAudioPolicyDev); 1280c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 1297be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org#else 1307be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org destroyAudioPolicyManager(mAudioPolicyManager); 1317be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org delete mAudioPolicyClient; 132bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#endif 1337be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 1347be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org mNotificationClients.clear(); 1350c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mAudioPolicyEffects.clear(); 1360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 1370c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 1380c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org// A notification client is always registered by AudioSystem when the client process 1390c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org// connects to AudioPolicyService. 1400c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgvoid AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client) 1410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org{ 1420c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 1430c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Mutex::Autolock _l(mLock); 1440c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 145bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org uid_t uid = IPCThreadState::self()->getCallingUid(); 1467be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org if (mNotificationClients.indexOfKey(uid) < 0) { 1477be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org sp<NotificationClient> notificationClient = new NotificationClient(this, 1487be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org client, 1497be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org uid); 1507be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org ALOGV("registerClient() client %p, uid %d", client.get(), uid); 1517be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 1527be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org mNotificationClients.add(uid, notificationClient); 1537be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 1547be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org sp<IBinder> binder = client->asBinder(); 155bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org binder->linkToDeath(notificationClient); 1567be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org } 1577be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 1587be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 159bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// removeNotificationClient() is called when the client process dies. 1607be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgvoid AudioPolicyService::removeNotificationClient(uid_t uid) 1617be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org{ 1627be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org Mutex::Autolock _l(mLock); 1637be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 1647be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org mNotificationClients.removeItem(uid); 165a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 166bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#ifndef USE_LEGACY_AUDIO_POLICY 167bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org if (mAudioPolicyManager) { 168bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org mAudioPolicyManager->clearAudioPatches(uid); 1697be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org } 170bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#endif 1717be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 1727be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 1737be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgvoid AudioPolicyService::onAudioPortListUpdate() 1747be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org{ 1757be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org mOutputCommandThread->updateAudioPortListCommand(); 1767be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 17743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 178bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgvoid AudioPolicyService::doOnAudioPortListUpdate() 179bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org{ 180bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org Mutex::Autolock _l(mLock); 181bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org for (size_t i = 0; i < mNotificationClients.size(); i++) { 18268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mNotificationClients.valueAt(i)->onAudioPortListUpdate(); 18368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 184bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 185bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 18643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid AudioPolicyService::onAudioPatchListUpdate() 18743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen{ 188a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mOutputCommandThread->updateAudioPatchListCommand(); 189a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 190a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 191a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatus_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch, 19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen audio_patch_handle_t *handle, 19343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int delayMs) 19443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen{ 19543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs); 19643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 19743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatus_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle, 19943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int delayMs) 20043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen{ 20143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs); 20243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 20343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2040c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgvoid AudioPolicyService::doOnAudioPatchListUpdate() 2050c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org{ 2060c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Mutex::Autolock _l(mLock); 2070c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org for (size_t i = 0; i < mNotificationClients.size(); i++) { 2080c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mNotificationClients.valueAt(i)->onAudioPatchListUpdate(); 2090c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 2100c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 2110c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 2120c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgstatus_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config, 2130c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org int delayMs) 2140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org{ 2150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); 2160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 2170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 2180c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgAudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service, 2190c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org const sp<IAudioPolicyServiceClient>& client, 2200c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org uid_t uid) 2210c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org : mService(service), mUid(uid), mAudioPolicyServiceClient(client) 2220c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org{ 2230c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 2240c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 2250c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgAudioPolicyService::NotificationClient::~NotificationClient() 2260c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org{ 2270c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 2280c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 2290c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgvoid AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused) 2300c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org{ 2310c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org sp<NotificationClient> keep(this); 2320c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org sp<AudioPolicyService> service = mService.promote(); 2330c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (service != 0) { 2340c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org service->removeNotificationClient(mUid); 2350c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 2360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 2370c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 2380c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgvoid AudioPolicyService::NotificationClient::onAudioPortListUpdate() 2390c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org{ 2400c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (mAudioPolicyServiceClient != 0) { 2410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mAudioPolicyServiceClient->onAudioPortListUpdate(); 2420c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 2430c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 2440c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 2450c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgvoid AudioPolicyService::NotificationClient::onAudioPatchListUpdate() 2460c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org{ 2470c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (mAudioPolicyServiceClient != 0) { 2480c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mAudioPolicyServiceClient->onAudioPatchListUpdate(); 2490c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 2500c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 2510c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 2520c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgvoid AudioPolicyService::binderDied(const wp<IBinder>& who) { 2530c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), 2540c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org IPCThreadState::self()->getCallingPid()); 255a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 256a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 257a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatic bool tryLock(Mutex& mutex) 258a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 259a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org bool locked = false; 260a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org for (int i = 0; i < kDumpLockRetries; ++i) { 261a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (mutex.tryLock() == NO_ERROR) { 262a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org locked = true; 263a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 264a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 265a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org usleep(kDumpLockSleepUs); 266a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 267a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return locked; 268a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 269a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 270a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatus_t AudioPolicyService::dumpInternals(int fd) 271a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 272a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org const size_t SIZE = 256; 273a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org char buffer[SIZE]; 274a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org String8 result; 275a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 276a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifdef USE_LEGACY_AUDIO_POLICY 277a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy); 278a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#else 2798bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager); 280a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif 28138e4c715e3a3df4ef11ccd3b86525be8f686ecb5ager@chromium.org result.append(buffer); 282a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); 283a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org result.append(buffer); 284a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); 285a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org result.append(buffer); 2860c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 2870c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org write(fd, result.string(), result.size()); 2880c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return NO_ERROR; 2890c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 2900c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 2910c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused) 2920c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org{ 2930c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (!dumpAllowed()) { 2940c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org dumpPermissionDenial(fd); 2950c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } else { 2960c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org bool locked = tryLock(mLock); 2970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (!locked) { 2980c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org String8 result(kDeadlockedString); 2990c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org write(fd, result.string(), result.size()); 3000c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 3010c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3020c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org dumpInternals(fd); 3030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (mAudioCommandThread != 0) { 3040c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mAudioCommandThread->dump(fd); 3050c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 3060c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (mTonePlaybackThread != 0) { 3070c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mTonePlaybackThread->dump(fd); 3080c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 3090c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3100c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org#ifdef USE_LEGACY_AUDIO_POLICY 3110c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (mpAudioPolicy) { 3120c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mpAudioPolicy->dump(mpAudioPolicy, fd); 3130c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 3140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org#else 3150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (mAudioPolicyManager) { 3160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mAudioPolicyManager->dump(fd); 3170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 3180c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org#endif 319a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 320a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (locked) mLock.unlock(); 321a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 322a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return NO_ERROR; 323a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 324a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 325a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatus_t AudioPolicyService::dumpPermissionDenial(int fd) 326a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 327a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org const size_t SIZE = 256; 328a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org char buffer[SIZE]; 329a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org String8 result; 330a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org snprintf(buffer, SIZE, "Permission Denial: " 331a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org "can't dump AudioPolicyService from pid=%d, uid=%d\n", 332a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org IPCThreadState::self()->getCallingPid(), 333a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org IPCThreadState::self()->getCallingUid()); 334a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org result.append(buffer); 335a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org write(fd, result.string(), result.size()); 336a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return NO_ERROR; 337a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 338a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 339a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatus_t AudioPolicyService::onTransact( 340a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 341a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 342a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return BnAudioPolicyService::onTransact(code, data, reply, flags); 343a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 344a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 345a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 346a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// ----------- AudioPolicyService::AudioCommandThread implementation ---------- 347a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 348a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name, 349a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org const wp<AudioPolicyService>& service) 350a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org : Thread(false), mName(name), mService(service) 351a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 352a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mpToneGenerator = NULL; 3533291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 354a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 355a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 356a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgAudioPolicyService::AudioCommandThread::~AudioCommandThread() 357a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 358a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!mAudioCommands.isEmpty()) { 359a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org release_wake_lock(mName.string()); 360a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 361a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mAudioCommands.clear(); 362a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org delete mpToneGenerator; 363a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 364a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 365a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid AudioPolicyService::AudioCommandThread::onFirstRef() 366a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 367a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org run(mName.string(), ANDROID_PRIORITY_AUDIO); 368a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 369a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 370a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool AudioPolicyService::AudioCommandThread::threadLoop() 371a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 372a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org nsecs_t waitTime = INT64_MAX; 373a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 374a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.lock(); 375a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (!exitPending()) 376a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org { 377a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org sp<AudioPolicyService> svc; 378a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (!mAudioCommands.isEmpty() && !exitPending()) { 379a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org nsecs_t curTime = systemTime(); 380a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // commands are sorted by increasing time stamp: execute them from index 0 and up 381a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (mAudioCommands[0]->mTime <= curTime) { 382a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org sp<AudioCommand> command = mAudioCommands[0]; 383a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mAudioCommands.removeAt(0); 384a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLastCommand = command; 385a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 386a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org switch (command->mCommand) { 387a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case START_TONE: { 388a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.unlock(); 389a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ToneData *data = (ToneData *)command->mParam.get(); 390a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() processing start tone %d on stream %d", 391a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org data->mType, data->mStream); 392a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org delete mpToneGenerator; 393a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mpToneGenerator = new ToneGenerator(data->mStream, 1.0); 394a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mpToneGenerator->startTone(data->mType); 395a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.lock(); 396a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org }break; 397a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case STOP_TONE: { 398a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.unlock(); 399a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() processing stop tone"); 400a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (mpToneGenerator != NULL) { 401a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mpToneGenerator->stopTone(); 402a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org delete mpToneGenerator; 403a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mpToneGenerator = NULL; 404a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 405a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.lock(); 406a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org }break; 407a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case SET_VOLUME: { 408a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org VolumeData *data = (VolumeData *)command->mParam.get(); 409a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() processing set volume stream %d, \ 410a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org volume %f, output %d", data->mStream, data->mVolume, data->mIO); 411a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mStatus = AudioSystem::setStreamVolume(data->mStream, 412a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org data->mVolume, 413a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org data->mIO); 414ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org }break; 415a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case SET_PARAMETERS: { 416a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ParametersData *data = (ParametersData *)command->mParam.get(); 417a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() processing set parameters string %s, io %d", 418a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org data->mKeyValuePairs.string(), data->mIO); 419a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); 420a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org }break; 421a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case SET_VOICE_VOLUME: { 422a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get(); 423a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() processing set voice volume volume %f", 424a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org data->mVolume); 425a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); 426a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org }break; 427a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case STOP_OUTPUT: { 428a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org StopOutputData *data = (StopOutputData *)command->mParam.get(); 429a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() processing stop output %d", 430a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org data->mIO); 431a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org svc = mService.promote(); 432a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (svc == 0) { 433a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 434a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 435a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.unlock(); 436a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org svc->doStopOutput(data->mIO, data->mStream, data->mSession); 437a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.lock(); 438a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org }break; 439a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case RELEASE_OUTPUT: { 440a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get(); 4418bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org ALOGV("AudioCommandThread() processing release output %d", 442a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org data->mIO); 443a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org svc = mService.promote(); 44437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (svc == 0) { 445a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 446a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 447a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.unlock(); 448a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org svc->doReleaseOutput(data->mIO); 449a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.lock(); 4508bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org }break; 451a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case CREATE_AUDIO_PATCH: { 452a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get(); 453a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() processing create audio patch"); 4543291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 4558bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org if (af == 0) { 4568bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org command->mStatus = PERMISSION_DENIED; 457a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 458a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle); 459a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 460a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } break; 461a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case RELEASE_AUDIO_PATCH: { 462a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get(); 463a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() processing release audio patch"); 464a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 465a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (af == 0) { 466a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mStatus = PERMISSION_DENIED; 467a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 468a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mStatus = af->releaseAudioPatch(data->mHandle); 469a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 470a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } break; 471a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case UPDATE_AUDIOPORT_LIST: { 472a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() processing update audio port list"); 47337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com svc = mService.promote(); 474a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (svc == 0) { 475a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 476a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 477a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.unlock(); 478a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org svc->doOnAudioPortListUpdate(); 479a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.lock(); 480a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org }break; 481a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case UPDATE_AUDIOPATCH_LIST: { 482a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() processing update audio patch list"); 483a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org svc = mService.promote(); 484a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (svc == 0) { 4858bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org break; 4868bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } 4878bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org mLock.unlock(); 4888bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org svc->doOnAudioPatchListUpdate(); 4898bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org mLock.lock(); 4908bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org }break; 491a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case SET_AUDIOPORT_CONFIG: { 492a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get(); 493a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() processing set port config"); 494a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 495a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (af == 0) { 496a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mStatus = PERMISSION_DENIED; 497a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 498a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mStatus = af->setAudioPortConfig(&data->mConfig); 499a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 500a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } break; 501a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 502a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGW("AudioCommandThread() unknown command %d", command->mCommand); 503a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 504a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org { 505a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Mutex::Autolock _l(command->mLock); 506a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (command->mWaitStatus) { 507a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mWaitStatus = false; 508a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mCond.signal(); 509a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 510a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 511a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org waitTime = INT64_MAX; 512a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 513a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org waitTime = mAudioCommands[0]->mTime - curTime; 514a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 515a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 516a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 517a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // release delayed commands wake lock 518a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (mAudioCommands.isEmpty()) { 519a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org release_wake_lock(mName.string()); 520a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 521a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // release mLock before releasing strong reference on the service as 522a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // AudioPolicyService destructor calls AudioCommandThread::exit() which acquires mLock. 523a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.unlock(); 524a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org svc.clear(); 525a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.lock(); 526a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!exitPending()) { 527a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() going to sleep"); 528a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mWaitWorkCV.waitRelative(mLock, waitTime); 529a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() waking up"); 530a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 531a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 532a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mLock.unlock(); 533a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 534a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 535a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 536a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatus_t AudioPolicyService::AudioCommandThread::dump(int fd) 53737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com{ 53837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com const size_t SIZE = 256; 53937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com char buffer[SIZE]; 54037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com String8 result; 54137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 54237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 54337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result.append(buffer); 544245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org write(fd, result.string(), result.size()); 545245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 54637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com bool locked = tryLock(mLock); 54737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (!locked) { 54837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com String8 result2(kCmdDeadlockedString); 549245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org write(fd, result2.string(), result2.size()); 550245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 55137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 55237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com snprintf(buffer, SIZE, "- Commands:\n"); 55337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result = String8(buffer); 55437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result.append(" Command Time Wait pParam\n"); 55537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com for (size_t i = 0; i < mAudioCommands.size(); i++) { 55637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com mAudioCommands[i]->dump(buffer, SIZE); 557245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org result.append(buffer); 558245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org } 55937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result.append(" Last Command\n"); 56037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (mLastCommand != 0) { 56137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com mLastCommand->dump(buffer, SIZE); 56237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result.append(buffer); 56337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } else { 56437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com result.append(" none\n"); 56537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 56637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 56737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com write(fd, result.string(), result.size()); 56837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 56937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (locked) mLock.unlock(); 57037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 57137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return NO_ERROR; 57237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com} 57337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 57437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type, 57537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com audio_stream_type_t stream) 57637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com{ 57737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com sp<AudioCommand> command = new AudioCommand(); 57837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com command->mCommand = START_TONE; 57937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com sp<ToneData> data = new ToneData(); 58037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com data->mType = type; 58137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com data->mStream = stream; 58237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com command->mParam = data; 583245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 584245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org sendCommand(command); 585245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org} 58637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 58737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid AudioPolicyService::AudioCommandThread::stopToneCommand() 58837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com{ 589a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org sp<AudioCommand> command = new AudioCommand(); 590a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mCommand = STOP_TONE; 5910c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org ALOGV("AudioCommandThread() adding tone stop"); 59237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com sendCommand(command); 593a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 594a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 595ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream, 59637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com float volume, 597ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org audio_io_handle_t output, 598ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org int delayMs) 599a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org{ 600a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org sp<AudioCommand> command = new AudioCommand(); 601a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org command->mCommand = SET_VOLUME; 602a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org sp<VolumeData> data = new VolumeData(); 603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->mStream = stream; 604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->mVolume = volume; 605a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->mIO = output; 60637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com command->mParam = data; 60737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com command->mWaitStatus = true; 60837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 60937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com stream, volume, output); 6103291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org return sendCommand(command, delayMs); 61137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com} 61237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 61337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle, 61437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com const char *keyValuePairs, 61537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com int delayMs) 61637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com{ 61737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com sp<AudioCommand> command = new AudioCommand(); 61837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com command->mCommand = SET_PARAMETERS; 61937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com sp<ParametersData> data = new ParametersData(); 62037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com data->mIO = ioHandle; 621245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org data->mKeyValuePairs = String8(keyValuePairs); 622245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org command->mParam = data; 6238bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org command->mWaitStatus = true; 6248bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 6258bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org keyValuePairs, ioHandle, delayMs); 6263291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org return sendCommand(command, delayMs); 6273291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 6283291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 6293291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 6303291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org{ 6313291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org sp<AudioCommand> command = new AudioCommand(); 632a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mCommand = SET_VOICE_VOLUME; 633a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org sp<VoiceVolumeData> data = new VoiceVolumeData(); 634a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org data->mVolume = volume; 635a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mParam = data; 636a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mWaitStatus = true; 637a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() adding set voice volume volume %f", volume); 638a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return sendCommand(command, delayMs); 639a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 640a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 641a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output, 642a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_stream_type_t stream, 643a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int session) 644a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 645a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org sp<AudioCommand> command = new AudioCommand(); 646a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mCommand = STOP_OUTPUT; 6470c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org sp<StopOutputData> data = new StopOutputData(); 6480c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org data->mIO = output; 6490c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org data->mStream = stream; 6500c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org data->mSession = session; 6510c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org command->mParam = data; 6520c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org ALOGV("AudioCommandThread() adding stop output %d", output); 6530c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org sendCommand(command); 6540c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 6550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 6560c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgvoid AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output) 6570c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org{ 6580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org sp<AudioCommand> command = new AudioCommand(); 6590c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org command->mCommand = RELEASE_OUTPUT; 6600c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org sp<ReleaseOutputData> data = new ReleaseOutputData(); 6610c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org data->mIO = output; 6620c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org command->mParam = data; 6630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org ALOGV("AudioCommandThread() adding release output %d", output); 6640c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org sendCommand(command); 6650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 666a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 667ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgstatus_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand( 6680c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org const struct audio_patch *patch, 6690c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org audio_patch_handle_t *handle, 6703291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org int delayMs) 671a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 672a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org status_t status = NO_ERROR; 673a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 674a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org sp<AudioCommand> command = new AudioCommand(); 675a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mCommand = CREATE_AUDIO_PATCH; 676a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org CreateAudioPatchData *data = new CreateAudioPatchData(); 677a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org data->mPatch = *patch; 678a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org data->mHandle = *handle; 679a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mParam = data; 680a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mWaitStatus = true; 681a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("AudioCommandThread() adding create patch delay %d", delayMs); 682a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org status = sendCommand(command, delayMs); 683a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (status == NO_ERROR) { 684a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *handle = data->mHandle; 685a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 6863291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org return status; 687a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 688a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 689a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatus_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle, 6900c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org int delayMs) 691a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 692a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org sp<AudioCommand> command = new AudioCommand(); 693a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mCommand = RELEASE_AUDIO_PATCH; 6940c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org ReleaseAudioPatchData *data = new ReleaseAudioPatchData(); 6953291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org data->mHandle = handle; 6963291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org command->mParam = data; 6973291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org command->mWaitStatus = true; 6983291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org ALOGV("AudioCommandThread() adding release patch delay %d", delayMs); 6993291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org return sendCommand(command, delayMs); 7003291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 7013291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 7023291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgvoid AudioPolicyService::AudioCommandThread::updateAudioPortListCommand() 7033291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org{ 7043291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org sp<AudioCommand> command = new AudioCommand(); 7053291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org command->mCommand = UPDATE_AUDIOPORT_LIST; 7063291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org ALOGV("AudioCommandThread() adding update audio port list"); 7073291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org sendCommand(command); 7083291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 7093291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 7103291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgvoid AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand() 7113291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org{ 7123291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org sp<AudioCommand>command = new AudioCommand(); 7133291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org command->mCommand = UPDATE_AUDIOPATCH_LIST; 7143291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org ALOGV("AudioCommandThread() adding update audio patch list"); 7153291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org sendCommand(command); 7163291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 7173291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 7183291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgstatus_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand( 7193291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org const struct audio_port_config *config, int delayMs) 7203291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org{ 7213291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org sp<AudioCommand> command = new AudioCommand(); 7223291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org command->mCommand = SET_AUDIOPORT_CONFIG; 7233291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org SetAudioPortConfigData *data = new SetAudioPortConfigData(); 7243291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org data->mConfig = *config; 7253291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org command->mParam = data; 7263291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org command->mWaitStatus = true; 7273291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org ALOGV("AudioCommandThread() adding set port config delay %d", delayMs); 728a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return sendCommand(command, delayMs); 729a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 730a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 731a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatus_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) 732a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 733a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org { 734a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Mutex::Autolock _l(mLock); 735a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org insertCommand_l(command, delayMs); 736a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mWaitWorkCV.signal(); 737a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 738a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Mutex::Autolock _l(command->mLock); 739a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (command->mWaitStatus) { 740a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs); 741a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) { 742a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mStatus = TIMED_OUT; 743a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mWaitStatus = false; 744a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 7458bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } 746a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return command->mStatus; 747a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 748a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 7493291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// insertCommand_l() must be called with mLock held 7503291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgvoid AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs) 7513291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org{ 752a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ssize_t i; // not size_t because i will count down to -1 7538bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org Vector < sp<AudioCommand> > removedCommands; 754a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org command->mTime = systemTime() + milliseconds(delayMs); 755ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 756ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // acquire wake lock to make sure delayed commands are processed 757ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org if (mAudioCommands.isEmpty()) { 7583291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 7593291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 7603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 7613291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // check same pending commands with later time stamps and eliminate them 7623291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org for (i = mAudioCommands.size()-1; i >= 0; i--) { 7633291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org sp<AudioCommand> command2 = mAudioCommands[i]; 764ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 765ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org if (command2->mTime <= command->mTime) break; 7663291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (command2->mCommand != command->mCommand) continue; 7673291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 7683291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org switch (command->mCommand) { 7693291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org case SET_PARAMETERS: { 7703291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org ParametersData *data = (ParametersData *)command->mParam.get(); 771a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ParametersData *data2 = (ParametersData *)command2->mParam.get(); 772ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org if (data->mIO != data2->mIO) break; 773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ALOGV("Comparing parameter command %s to new command %s", 774a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 775a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org AudioParameter param = AudioParameter(data->mKeyValuePairs); 77637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 77737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com for (size_t j = 0; j < param.size(); j++) { 778245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org String8 key; 779245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org String8 value; 780245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org param.getAt(j, key, value); 781245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org for (size_t k = 0; k < param2.size(); k++) { 78237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com String8 key2; 7838bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org String8 value2; 7848bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org param2.getAt(k, key2, value2); 7858bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org if (key2 == key) { 786a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org param2.remove(key2); 7870c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org ALOGV("Filtering out parameter %s", key2.string()); 788a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 789a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 790a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 791a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 792a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // if all keys have been filtered out, remove the command. 793a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // otherwise, update the key value pairs 794a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (param2.size() == 0) { 795a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org removedCommands.add(command2); 796a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 797a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org data2->mKeyValuePairs = param2.toString(); 798a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 799ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org command->mTime = command2->mTime; 800a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // force delayMs to non 0 so that code below does not request to wait for 801a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // command status as the command is now delayed 802a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org delayMs = 1; 803a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } break; 804ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 805ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org case SET_VOLUME: { 806a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org VolumeData *data = (VolumeData *)command->mParam.get(); 8073291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org VolumeData *data2 = (VolumeData *)command2->mParam.get(); 8083291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (data->mIO != data2->mIO) break; 8093291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (data->mStream != data2->mStream) break; 8103291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org ALOGV("Filtering out volume command on output %d for stream %d", 8113291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org data->mIO, data->mStream); 8123291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org removedCommands.add(command2); 8133291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org command->mTime = command2->mTime; 8143291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // force delayMs to non 0 so that code below does not request to wait for 8153291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // command status as the command is now delayed 816a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org delayMs = 1; 817a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } break; 818a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case START_TONE: 819a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org case STOP_TONE: 820a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org default: 821a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 822a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 823a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 824a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 825a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // remove filtered commands 826a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org for (size_t j = 0; j < removedCommands.size(); j++) { 827a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // removed commands always have time stamps greater than current command 8288bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 829a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (mAudioCommands[k].get() == removedCommands[j].get()) { 830a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 831a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mAudioCommands.removeAt(k); 8328bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org break; 833a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 834a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 835a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 836a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org removedCommands.clear(); 837a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 838ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // Disable wait for status if delay is not 0 839a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (delayMs != 0) { 840a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org command->mWaitStatus = false; 841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 84237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 84337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // insert command at the right place according to its time stamp 844245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org ALOGV("inserting command: %d at index %zd, num commands %zu", 845245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org command->mCommand, i+1, mAudioCommands.size()); 846a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mAudioCommands.insertAt(command, i + 1); 84738e4c715e3a3df4ef11ccd3b86525be8f686ecb5ager@chromium.org} 8488bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 8498bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgvoid AudioPolicyService::AudioCommandThread::exit() 8508bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org{ 8518bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org ALOGV("AudioCommandThread::exit"); 8528bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org { 8538bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org AutoMutex _l(mLock); 8548bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org requestExit(); 8550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mWaitWorkCV.signal(); 85637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 85737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com requestExitAndWait(); 858381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 859381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 860381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 861381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org{ 862381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 86337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com mCommand, 864381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org (int)ns2s(mTime), 865381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org (int)ns2ms(mTime)%1000, 866381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org mWaitStatus, 86737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com mParam.get()); 86837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com} 86937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 8703291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org/******* helpers for the service_ops callbacks defined below *********/ 87137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 87237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com const char *keyValuePairs, 87337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com int delayMs) 874a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org{ 875a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs, 876a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org delayMs); 877a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 878ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 879ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgint AudioPolicyService::setStreamVolume(audio_stream_type_t stream, 880ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org float volume, 881ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org audio_io_handle_t output, 882ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org int delayMs) 883ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org{ 884ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org return (int)mAudioCommandThread->volumeCommand(stream, volume, 8850c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org output, delayMs); 8860c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 8870c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 8880c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgint AudioPolicyService::startTone(audio_policy_tone_t tone, 8890c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org audio_stream_type_t stream) 8900c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org{ 891ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) { 892ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org ALOGE("startTone: illegal tone requested (%d)", tone); 893ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org } 894ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org if (stream != AUDIO_STREAM_VOICE_CALL) { 895ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org ALOGE("startTone: illegal stream (%d) requested for tone %d", stream, 896ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org tone); 897ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org } 898ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING, 899ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org AUDIO_STREAM_VOICE_CALL); 900ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org return 0; 901ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org} 902ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 903ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgint AudioPolicyService::stopTone() 904ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org{ 905ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org mTonePlaybackThread->stopToneCommand(); 906ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org return 0; 907ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org} 908ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 909a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint AudioPolicyService::setVoiceVolume(float volume, int delayMs) 910a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org{ 911a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 912ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org} 913ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 914245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgextern "C" { 915245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgaudio_module_handle_t aps_load_hw_module(void *service __unused, 9160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org const char *name); 917ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgaudio_io_handle_t aps_open_output(void *service __unused, 918ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org audio_devices_t *pDevices, 9190c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org uint32_t *pSamplingRate, 920ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org audio_format_t *pFormat, 921ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org audio_channel_mask_t *pChannelMask, 922ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org uint32_t *pLatencyMs, 923ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org audio_output_flags_t flags); 924ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 925ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgaudio_io_handle_t aps_open_output_on_module(void *service __unused, 926ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org audio_module_handle_t module, 927a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_devices_t *pDevices, 928a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uint32_t *pSamplingRate, 929a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_format_t *pFormat, 930a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_channel_mask_t *pChannelMask, 9318bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org uint32_t *pLatencyMs, 932a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_output_flags_t flags, 933a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org const audio_offload_info_t *offloadInfo); 934a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgaudio_io_handle_t aps_open_dup_output(void *service __unused, 935a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_io_handle_t output1, 936a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_io_handle_t output2); 937a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgint aps_close_output(void *service __unused, audio_io_handle_t output); 938ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgint aps_suspend_output(void *service __unused, audio_io_handle_t output); 939a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint aps_restore_output(void *service __unused, audio_io_handle_t output); 940a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgaudio_io_handle_t aps_open_input(void *service __unused, 941a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org audio_devices_t *pDevices, 94237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com uint32_t *pSamplingRate, 94337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com audio_format_t *pFormat, 944245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org audio_channel_mask_t *pChannelMask, 945245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org audio_in_acoustics_t acoustics __unused); 94637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comaudio_io_handle_t aps_open_input_on_module(void *service __unused, 94737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com audio_module_handle_t module, 948a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_devices_t *pDevices, 9490c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org uint32_t *pSamplingRate, 950a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_format_t *pFormat, 951a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_channel_mask_t *pChannelMask); 952a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgint aps_close_input(void *service __unused, audio_io_handle_t input); 953a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgint aps_invalidate_stream(void *service __unused, audio_stream_type_t stream); 954a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgint aps_move_effects(void *service __unused, int session, 955a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_io_handle_t src_output, 956a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org audio_io_handle_t dst_output); 957a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgchar * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle, 9588bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org const char *keys); 959a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid aps_set_parameters(void *service, audio_io_handle_t io_handle, 960a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org const char *kv_pairs, int delay_ms); 961ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgint aps_set_stream_volume(void *service, audio_stream_type_t stream, 962a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org float volume, audio_io_handle_t output, 963a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int delay_ms); 964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint aps_start_tone(void *service, audio_policy_tone_t tone, 96537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com audio_stream_type_t stream); 96637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comint aps_stop_tone(void *service); 967245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgint aps_set_voice_volume(void *service, float volume, int delay_ms); 968245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org}; 96937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 97037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comnamespace { 97137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com struct audio_policy_service_ops aps_ops = { 972a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org .open_output = aps_open_output, 973a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org .open_duplicate_output = aps_open_dup_output, 974a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org .close_output = aps_close_output, 975a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org .suspend_output = aps_suspend_output, 976a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org .restore_output = aps_restore_output, 977a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org .open_input = aps_open_input, 9788bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org .close_input = aps_close_input, 9798bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org .set_stream_volume = aps_set_stream_volume, 980ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org .invalidate_stream = aps_invalidate_stream, 981ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org .set_parameters = aps_set_parameters, 982ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org .get_parameters = aps_get_parameters, 983ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org .start_tone = aps_start_tone, 9848bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org .stop_tone = aps_stop_tone, 9858bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org .set_voice_volume = aps_set_voice_volume, 986ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org .move_effects = aps_move_effects, 987ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org .load_hw_module = aps_load_hw_module, 988ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org .open_output_on_module = aps_open_output_on_module, 989ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org .open_input_on_module = aps_open_input_on_module, 9908bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org }; 9918bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org}; // namespace <unnamed> 9928bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 9938bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org}; // namespace android 994ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org