AudioPolicyService.cpp revision de070137f11d346fba77605bd76a44c040a618fc
1f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project/* 2f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project 3a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * 4f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * you may not use this file except in compliance with the License. 6f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * You may obtain a copy of the License at 7f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * 8f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * 10f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * See the License for the specific language governing permissions and 14f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * limitations under the License. 15f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project */ 16f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 17f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#define LOG_TAG "AudioPolicyService" 18f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project//#define LOG_NDEBUG 0 19f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 20f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#undef __STRICT_ANSI__ 21f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#define __STDINT_LIMITS 22f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#define __STDC_LIMIT_MACROS 23f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <stdint.h> 24f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 25f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <sys/time.h> 26f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <binder/IServiceManager.h> 27f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <utils/Log.h> 28f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <cutils/properties.h> 29f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <binder/IPCThreadState.h> 30f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <utils/String16.h> 31f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <utils/threads.h> 32f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "AudioPolicyService.h" 33f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <hardware_legacy/AudioPolicyManagerBase.h> 34f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <cutils/properties.h> 35f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <dlfcn.h> 36f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <hardware_legacy/power.h> 37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 38e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt// ---------------------------------------------------------------------------- 39e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt// the sim build doesn't have gettid 40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#ifndef HAVE_GETTID 42f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project# define gettid getpid 43a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#endif 44a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt 45a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidtnamespace android { 46a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt 47a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt 48a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidtstatic const char *kDeadlockedString = "AudioPolicyService may be deadlocked\n"; 49a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidtstatic const char *kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n"; 50f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 51e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic const int kDumpLockRetries = 50; 52f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatic const int kDumpLockSleep = 20000; 53f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 54f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatic bool checkPermission() { 55f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#ifndef HAVE_ANDROID_OS 56f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return true; 57f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#endif 58f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (getpid() == IPCThreadState::self()->getCallingPid()) return true; 59f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")); 60e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS"); 61f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return ok; 62f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 63f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 64e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt// ---------------------------------------------------------------------------- 65e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 66e86eee143ed21592f88a46623a81f71002430459Dmitry ShmidtAudioPolicyService::AudioPolicyService() 67e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt : BnAudioPolicyService() , mpPolicyManager(NULL) 68e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char value[PROPERTY_VALUE_MAX]; 70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt // start tone playback thread 72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mTonePlaybackThread = new AudioCommandThread(String8("")); 73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt // start audio commands thread 74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread")); 75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST) 77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mpPolicyManager = new AudioPolicyManagerBase(this); 78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt LOGV("build for GENERIC_AUDIO - using generic audio policy"); 79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#else 80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt // if running in emulation - use the emulator driver 81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (property_get("ro.kernel.qemu", value, 0)) { 82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt LOGV("Running in emulation - using generic audio policy"); 83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mpPolicyManager = new AudioPolicyManagerBase(this); 84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 85e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else { 86e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt LOGV("Using hardware specific audio policy"); 87e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mpPolicyManager = createAudioPolicyManager(this); 88e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 89e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif 90e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 91e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt // load properties 92f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project property_get("ro.camera.sound.forced", value, "0"); 93f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value); 94e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 95e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 96e86eee143ed21592f88a46623a81f71002430459Dmitry ShmidtAudioPolicyService::~AudioPolicyService() 97e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 98e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mTonePlaybackThread->exit(); 99e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mTonePlaybackThread.clear(); 100e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mAudioCommandThread->exit(); 101e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mAudioCommandThread.clear(); 102e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 103e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager) { 104e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt delete mpPolicyManager; 105e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 106e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 107e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 108e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 109e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatus_t AudioPolicyService::setDeviceConnectionState(AudioSystem::audio_devices device, 110e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt AudioSystem::device_connection_state state, 111e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt const char *device_address) 112e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 113e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 114e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_INIT; 115f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 116f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (!checkPermission()) { 117f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return PERMISSION_DENIED; 118f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 119f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (!AudioSystem::isOutputDevice(device) && !AudioSystem::isInputDevice(device)) { 120e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return BAD_VALUE; 121e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 122f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (state != AudioSystem::DEVICE_STATE_AVAILABLE && 123f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project state != AudioSystem::DEVICE_STATE_UNAVAILABLE) { 124e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return BAD_VALUE; 125e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 126e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 127e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt LOGV("setDeviceConnectionState() tid %d", gettid()); 128e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt Mutex::Autolock _l(mLock); 129e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return mpPolicyManager->setDeviceConnectionState(device, state, device_address); 130e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 131e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 132e86eee143ed21592f88a46623a81f71002430459Dmitry ShmidtAudioSystem::device_connection_state AudioPolicyService::getDeviceConnectionState( 133e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt AudioSystem::audio_devices device, 134e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt const char *device_address) 135e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 136e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 137e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return AudioSystem::DEVICE_STATE_UNAVAILABLE; 138e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 139e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!checkPermission()) { 140e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return AudioSystem::DEVICE_STATE_UNAVAILABLE; 141e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 142e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return mpPolicyManager->getDeviceConnectionState(device, device_address); 143e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 144e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 145e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatus_t AudioPolicyService::setPhoneState(int state) 146f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 147f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (mpPolicyManager == NULL) { 148f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return NO_INIT; 149f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 150e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!checkPermission()) { 151f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return PERMISSION_DENIED; 152e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 153e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (state < 0 || state >= AudioSystem::NUM_MODES) { 154f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return BAD_VALUE; 155f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 156f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 157f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project LOGV("setPhoneState() tid %d", gettid()); 158e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 159e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt // TODO: check if it is more appropriate to do it in platform specific policy manager 160f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project AudioSystem::setMode(state); 161f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 162f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project Mutex::Autolock _l(mLock); 163f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project mpPolicyManager->setPhoneState(state); 164f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return NO_ERROR; 165f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 166f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 167f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatus_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask) 168e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 169e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 170e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_INIT; 171e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 172e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!checkPermission()) { 173e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return PERMISSION_DENIED; 174f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 175e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 176e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mpPolicyManager->setRingerMode(mode, mask); 177e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_ERROR; 178e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 179e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 180e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatus_t AudioPolicyService::setForceUse(AudioSystem::force_use usage, 181e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt AudioSystem::forced_config config) 182e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 183e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 184e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_INIT; 185e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 186e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!checkPermission()) { 187e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return PERMISSION_DENIED; 188e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 189e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) { 190e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return BAD_VALUE; 191e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 192e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (config < 0 || config >= AudioSystem::NUM_FORCE_CONFIG) { 193e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return BAD_VALUE; 194f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 195f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project LOGV("setForceUse() tid %d", gettid()); 196f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project Mutex::Autolock _l(mLock); 197e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mpPolicyManager->setForceUse(usage, config); 198f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return NO_ERROR; 199f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 200f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 201f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source ProjectAudioSystem::forced_config AudioPolicyService::getForceUse(AudioSystem::force_use usage) 202f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 203f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (mpPolicyManager == NULL) { 204e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return AudioSystem::FORCE_NONE; 205f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 206f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (!checkPermission()) { 207f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return AudioSystem::FORCE_NONE; 208f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 209e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) { 210f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return AudioSystem::FORCE_NONE; 211f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 212f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return mpPolicyManager->getForceUse(usage); 213f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 214f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 215f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectaudio_io_handle_t AudioPolicyService::getOutput(AudioSystem::stream_type stream, 216f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project uint32_t samplingRate, 217f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project uint32_t format, 218f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project uint32_t channels, 219f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project AudioSystem::output_flags flags) 220f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 221f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (mpPolicyManager == NULL) { 222f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return 0; 223f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 224f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project LOGV("getOutput() tid %d", gettid()); 225f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project Mutex::Autolock _l(mLock); 226f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return mpPolicyManager->getOutput(stream, samplingRate, format, channels, flags); 227f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 228f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 229e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatus_t AudioPolicyService::startOutput(audio_io_handle_t output, 230e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt AudioSystem::stream_type stream, 231e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int session) 232e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 233e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 234e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_INIT; 235e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 236e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt LOGV("startOutput() tid %d", gettid()); 237e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt Mutex::Autolock _l(mLock); 238e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return mpPolicyManager->startOutput(output, stream, session); 239e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 240e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 241e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatus_t AudioPolicyService::stopOutput(audio_io_handle_t output, 242e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt AudioSystem::stream_type stream, 243e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int session) 244e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 245e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 246e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_INIT; 247e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 248e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt LOGV("stopOutput() tid %d", gettid()); 249e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt Mutex::Autolock _l(mLock); 250e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return mpPolicyManager->stopOutput(output, stream, session); 251e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 252e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 253e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtvoid AudioPolicyService::releaseOutput(audio_io_handle_t output) 254e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 255e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 256e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return; 257e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 258e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt LOGV("releaseOutput() tid %d", gettid()); 259e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt Mutex::Autolock _l(mLock); 260e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mpPolicyManager->releaseOutput(output); 261e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 262e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 263e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtaudio_io_handle_t AudioPolicyService::getInput(int inputSource, 264e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint32_t samplingRate, 265e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint32_t format, 266e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint32_t channels, 267e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt AudioSystem::audio_in_acoustics acoustics) 268e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 269e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 270e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 0; 271e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 272e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt Mutex::Autolock _l(mLock); 273e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return mpPolicyManager->getInput(inputSource, samplingRate, format, channels, acoustics); 274e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 275e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 276e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatus_t AudioPolicyService::startInput(audio_io_handle_t input) 277e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 278e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 279e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_INIT; 280e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 281e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt Mutex::Autolock _l(mLock); 282e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return mpPolicyManager->startInput(input); 283e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 284e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 285e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatus_t AudioPolicyService::stopInput(audio_io_handle_t input) 286e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 287e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 288e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_INIT; 289e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 290e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt Mutex::Autolock _l(mLock); 291e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return mpPolicyManager->stopInput(input); 292e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 293e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 294e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtvoid AudioPolicyService::releaseInput(audio_io_handle_t input) 295e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 296e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 297e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return; 298e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 299e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt Mutex::Autolock _l(mLock); 300e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mpPolicyManager->releaseInput(input); 301e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 302e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 303e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatus_t AudioPolicyService::initStreamVolume(AudioSystem::stream_type stream, 304e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int indexMin, 305e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int indexMax) 306e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 307e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 308e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_INIT; 309e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 310e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!checkPermission()) { 311e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return PERMISSION_DENIED; 312e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 313e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 314e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return BAD_VALUE; 315e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 316e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mpPolicyManager->initStreamVolume(stream, indexMin, indexMax); 317e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_ERROR; 318e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 319e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 320e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatus_t AudioPolicyService::setStreamVolumeIndex(AudioSystem::stream_type stream, int index) 321e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 322e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 323e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_INIT; 324e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 325e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!checkPermission()) { 326e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return PERMISSION_DENIED; 327e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 328e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 329e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return BAD_VALUE; 330e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 331e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 332e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return mpPolicyManager->setStreamVolumeIndex(stream, index); 333e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 334e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 335e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatus_t AudioPolicyService::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index) 336e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 337e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 338e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_INIT; 339e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 340e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!checkPermission()) { 341f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return PERMISSION_DENIED; 342f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 343f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 344f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return BAD_VALUE; 345f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 346f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return mpPolicyManager->getStreamVolumeIndex(stream, index); 347e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 348e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 349e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtuint32_t AudioPolicyService::getStrategyForStream(AudioSystem::stream_type stream) 350e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 351e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 352e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 0; 353e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 354f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return mpPolicyManager->getStrategyForStream(stream); 355f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 356f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 357f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectaudio_io_handle_t AudioPolicyService::getOutputForEffect(effect_descriptor_t *desc) 358f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 359f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (mpPolicyManager == NULL) { 360f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return NO_INIT; 361f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 362f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project Mutex::Autolock _l(mLock); 363e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return mpPolicyManager->getOutputForEffect(desc); 364f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 365f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 366f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatus_t AudioPolicyService::registerEffect(effect_descriptor_t *desc, 367f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project audio_io_handle_t output, 368f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project uint32_t strategy, 369f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project int session, 370f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project int id) 371f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 372e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (mpPolicyManager == NULL) { 373e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NO_INIT; 374f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 375f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return mpPolicyManager->registerEffect(desc, output, strategy, session, id); 376f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 377f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 378f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatus_t AudioPolicyService::unregisterEffect(int id) 379f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 380f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (mpPolicyManager == NULL) { 381a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt return NO_INIT; 382a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt } 383a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt return mpPolicyManager->unregisterEffect(id); 384a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt} 385a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt 386a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidtvoid AudioPolicyService::binderDied(const wp<IBinder>& who) { 387a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), 388a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt IPCThreadState::self()->getCallingPid()); 389a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt} 390a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt 391a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidtstatic bool tryLock(Mutex& mutex) 392a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt{ 393a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt bool locked = false; 394a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt for (int i = 0; i < kDumpLockRetries; ++i) { 395a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (mutex.tryLock() == NO_ERROR) { 396a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt locked = true; 397a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt break; 398e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 399f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project usleep(kDumpLockSleep); 400f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 401f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return locked; 402e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 403f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 404e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatus_t AudioPolicyService::dumpInternals(int fd) 405f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 406f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project const size_t SIZE = 256; 407f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project char buffer[SIZE]; 408f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project String8 result; 409f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 410e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager); 411f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project result.append(buffer); 412f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); 413f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project result.append(buffer); 414f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); 415f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project result.append(buffer); 416f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 417f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project write(fd, result.string(), result.size()); 418f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return NO_ERROR; 419e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 420e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 421f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args) 422f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 423f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 424f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project dumpPermissionDenial(fd); 425f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } else { 426f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project bool locked = tryLock(mLock); 427e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!locked) { 428e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt String8 result(kDeadlockedString); 429f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project write(fd, result.string(), result.size()); 430f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 431f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 432f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project dumpInternals(fd); 433f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (mAudioCommandThread != NULL) { 434e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt mAudioCommandThread->dump(fd); 435f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 436f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (mTonePlaybackThread != NULL) { 437f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project mTonePlaybackThread->dump(fd); 438f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 439e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 440f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (mpPolicyManager) { 441f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project mpPolicyManager->dump(fd); 442f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 443f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 444f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (locked) mLock.unlock(); 445f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 446f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return NO_ERROR; 447f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 448f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 449f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatus_t AudioPolicyService::dumpPermissionDenial(int fd) 450f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 451f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project const size_t SIZE = 256; 452f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project char buffer[SIZE]; 453f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project String8 result; 454f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 455f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project "can't dump AudioPolicyService from pid=%d, uid=%d\n", 456f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project IPCThreadState::self()->getCallingPid(), 457f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project IPCThreadState::self()->getCallingUid()); 458f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project result.append(buffer); 459f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project write(fd, result.string(), result.size()); 460f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return NO_ERROR; 461f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 462f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 463f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatus_t AudioPolicyService::onTransact( 464f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 465f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 466f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return BnAudioPolicyService::onTransact(code, data, reply, flags); 467f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 468f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 469f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 470f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project// ---------------------------------------------------------------------------- 471f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectvoid AudioPolicyService::instantiate() { 472f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project defaultServiceManager()->addService( 473f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project String16("media.audio_policy"), new AudioPolicyService()); 474f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 475f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 476f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 477f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project// ---------------------------------------------------------------------------- 478f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project// AudioPolicyClientInterface implementation 479f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project// ---------------------------------------------------------------------------- 480f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 481f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 482f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectaudio_io_handle_t AudioPolicyService::openOutput(uint32_t *pDevices, 483f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project uint32_t *pSamplingRate, 484f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project uint32_t *pFormat, 485f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project uint32_t *pChannels, 486f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project uint32_t *pLatencyMs, 487f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project AudioSystem::output_flags flags) 488f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 489f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 490f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (af == 0) { 491f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project LOGW("openOutput() could not get AudioFlinger"); 492f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return 0; 493e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 494e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 495e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return af->openOutput(pDevices, 496f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project pSamplingRate, 497f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project (uint32_t *)pFormat, 498f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project pChannels, 499f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project pLatencyMs, 500f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project flags); 501f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 502f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 503f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectaudio_io_handle_t AudioPolicyService::openDuplicateOutput(audio_io_handle_t output1, 504f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project audio_io_handle_t output2) 505f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 506f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 507f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (af == 0) { 508e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt LOGW("openDuplicateOutput() could not get AudioFlinger"); 509f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return 0; 510f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 511f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return af->openDuplicateOutput(output1, output2); 512f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 513f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 514f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatus_t AudioPolicyService::closeOutput(audio_io_handle_t output) 515f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 516f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 517e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (af == 0) return PERMISSION_DENIED; 518f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 519e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return af->closeOutput(output); 520e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 521f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 522e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 523f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatus_t AudioPolicyService::suspendOutput(audio_io_handle_t output) 524f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 525f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 526f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (af == 0) { 527f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project LOGW("suspendOutput() could not get AudioFlinger"); 528f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return PERMISSION_DENIED; 529f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 530f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 531a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt return af->suspendOutput(output); 532f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 533f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 534f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatus_t AudioPolicyService::restoreOutput(audio_io_handle_t output) 535f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 536f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 537a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (af == 0) { 538f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project LOGW("restoreOutput() could not get AudioFlinger"); 539f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return PERMISSION_DENIED; 540f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 541f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 542f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return af->restoreOutput(output); 543f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 544f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 545f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectaudio_io_handle_t AudioPolicyService::openInput(uint32_t *pDevices, 546938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt uint32_t *pSamplingRate, 547938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt uint32_t *pFormat, 5480545fad98723550607287a86bfee3807c7d26e91Dmitry Shmidt uint32_t *pChannels, 549f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project uint32_t acoustics) 550f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 551f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 552f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (af == 0) { 553f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project LOGW("openInput() could not get AudioFlinger"); 554f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return 0; 555938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt } 556f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 557f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return af->openInput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, acoustics); 5580545fad98723550607287a86bfee3807c7d26e91Dmitry Shmidt} 559938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt 560a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidtstatus_t AudioPolicyService::closeInput(audio_io_handle_t input) 561a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt{ 562a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 563938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt if (af == 0) return PERMISSION_DENIED; 564938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt 565938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt return af->closeInput(input); 566a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt} 567a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt 568a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidtstatus_t AudioPolicyService::setStreamVolume(AudioSystem::stream_type stream, 569f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project float volume, 570f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project audio_io_handle_t output, 571f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project int delayMs) 572f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 573f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return mAudioCommandThread->volumeCommand((int)stream, volume, (int)output, delayMs); 574f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 575a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt 576f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatus_t AudioPolicyService::setStreamOutput(AudioSystem::stream_type stream, 577a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt audio_io_handle_t output) 578938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt{ 579938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 580a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (af == 0) return PERMISSION_DENIED; 581938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt 582938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt return af->setStreamOutput(stream, output); 583a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt} 584a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt 585938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidtstatus_t AudioPolicyService::moveEffects(int session, audio_io_handle_t srcOutput, 586a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt audio_io_handle_t dstOutput) 587f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 588f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); 589a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (af == 0) return PERMISSION_DENIED; 590f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 591f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return af->moveEffects(session, (int)srcOutput, (int)dstOutput); 592f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 593f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 594f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle, 595f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project const String8& keyValuePairs, 596 int delayMs) 597{ 598 mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs, delayMs); 599} 600 601String8 AudioPolicyService::getParameters(audio_io_handle_t ioHandle, const String8& keys) 602{ 603 String8 result = AudioSystem::getParameters(ioHandle, keys); 604 return result; 605} 606 607status_t AudioPolicyService::startTone(ToneGenerator::tone_type tone, 608 AudioSystem::stream_type stream) 609{ 610 mTonePlaybackThread->startToneCommand(tone, stream); 611 return NO_ERROR; 612} 613 614status_t AudioPolicyService::stopTone() 615{ 616 mTonePlaybackThread->stopToneCommand(); 617 return NO_ERROR; 618} 619 620status_t AudioPolicyService::setVoiceVolume(float volume, int delayMs) 621{ 622 return mAudioCommandThread->voiceVolumeCommand(volume, delayMs); 623} 624 625// ----------- AudioPolicyService::AudioCommandThread implementation ---------- 626 627AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name) 628 : Thread(false), mName(name) 629{ 630 mpToneGenerator = NULL; 631} 632 633 634AudioPolicyService::AudioCommandThread::~AudioCommandThread() 635{ 636 if (mName != "" && !mAudioCommands.isEmpty()) { 637 release_wake_lock(mName.string()); 638 } 639 mAudioCommands.clear(); 640 if (mpToneGenerator != NULL) delete mpToneGenerator; 641} 642 643void AudioPolicyService::AudioCommandThread::onFirstRef() 644{ 645 if (mName != "") { 646 run(mName.string(), ANDROID_PRIORITY_AUDIO); 647 } else { 648 run("AudioCommandThread", ANDROID_PRIORITY_AUDIO); 649 } 650} 651 652bool AudioPolicyService::AudioCommandThread::threadLoop() 653{ 654 nsecs_t waitTime = INT64_MAX; 655 656 mLock.lock(); 657 while (!exitPending()) 658 { 659 while(!mAudioCommands.isEmpty()) { 660 nsecs_t curTime = systemTime(); 661 // commands are sorted by increasing time stamp: execute them from index 0 and up 662 if (mAudioCommands[0]->mTime <= curTime) { 663 AudioCommand *command = mAudioCommands[0]; 664 mAudioCommands.removeAt(0); 665 mLastCommand = *command; 666 667 switch (command->mCommand) { 668 case START_TONE: { 669 mLock.unlock(); 670 ToneData *data = (ToneData *)command->mParam; 671 LOGV("AudioCommandThread() processing start tone %d on stream %d", 672 data->mType, data->mStream); 673 if (mpToneGenerator != NULL) 674 delete mpToneGenerator; 675 mpToneGenerator = new ToneGenerator(data->mStream, 1.0); 676 mpToneGenerator->startTone(data->mType); 677 delete data; 678 mLock.lock(); 679 }break; 680 case STOP_TONE: { 681 mLock.unlock(); 682 LOGV("AudioCommandThread() processing stop tone"); 683 if (mpToneGenerator != NULL) { 684 mpToneGenerator->stopTone(); 685 delete mpToneGenerator; 686 mpToneGenerator = NULL; 687 } 688 mLock.lock(); 689 }break; 690 case SET_VOLUME: { 691 VolumeData *data = (VolumeData *)command->mParam; 692 LOGV("AudioCommandThread() processing set volume stream %d, \ 693 volume %f, output %d", data->mStream, data->mVolume, data->mIO); 694 command->mStatus = AudioSystem::setStreamVolume(data->mStream, 695 data->mVolume, 696 data->mIO); 697 if (command->mWaitStatus) { 698 command->mCond.signal(); 699 mWaitWorkCV.wait(mLock); 700 } 701 delete data; 702 }break; 703 case SET_PARAMETERS: { 704 ParametersData *data = (ParametersData *)command->mParam; 705 LOGV("AudioCommandThread() processing set parameters string %s, io %d", 706 data->mKeyValuePairs.string(), data->mIO); 707 command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); 708 if (command->mWaitStatus) { 709 command->mCond.signal(); 710 mWaitWorkCV.wait(mLock); 711 } 712 delete data; 713 }break; 714 case SET_VOICE_VOLUME: { 715 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam; 716 LOGV("AudioCommandThread() processing set voice volume volume %f", 717 data->mVolume); 718 command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); 719 if (command->mWaitStatus) { 720 command->mCond.signal(); 721 mWaitWorkCV.wait(mLock); 722 } 723 delete data; 724 }break; 725 default: 726 LOGW("AudioCommandThread() unknown command %d", command->mCommand); 727 } 728 delete command; 729 waitTime = INT64_MAX; 730 } else { 731 waitTime = mAudioCommands[0]->mTime - curTime; 732 break; 733 } 734 } 735 // release delayed commands wake lock 736 if (mName != "" && mAudioCommands.isEmpty()) { 737 release_wake_lock(mName.string()); 738 } 739 LOGV("AudioCommandThread() going to sleep"); 740 mWaitWorkCV.waitRelative(mLock, waitTime); 741 LOGV("AudioCommandThread() waking up"); 742 } 743 mLock.unlock(); 744 return false; 745} 746 747status_t AudioPolicyService::AudioCommandThread::dump(int fd) 748{ 749 const size_t SIZE = 256; 750 char buffer[SIZE]; 751 String8 result; 752 753 snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); 754 result.append(buffer); 755 write(fd, result.string(), result.size()); 756 757 bool locked = tryLock(mLock); 758 if (!locked) { 759 String8 result2(kCmdDeadlockedString); 760 write(fd, result2.string(), result2.size()); 761 } 762 763 snprintf(buffer, SIZE, "- Commands:\n"); 764 result = String8(buffer); 765 result.append(" Command Time Wait pParam\n"); 766 for (int i = 0; i < (int)mAudioCommands.size(); i++) { 767 mAudioCommands[i]->dump(buffer, SIZE); 768 result.append(buffer); 769 } 770 result.append(" Last Command\n"); 771 mLastCommand.dump(buffer, SIZE); 772 result.append(buffer); 773 774 write(fd, result.string(), result.size()); 775 776 if (locked) mLock.unlock(); 777 778 return NO_ERROR; 779} 780 781void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream) 782{ 783 AudioCommand *command = new AudioCommand(); 784 command->mCommand = START_TONE; 785 ToneData *data = new ToneData(); 786 data->mType = type; 787 data->mStream = stream; 788 command->mParam = (void *)data; 789 command->mWaitStatus = false; 790 Mutex::Autolock _l(mLock); 791 insertCommand_l(command); 792 LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); 793 mWaitWorkCV.signal(); 794} 795 796void AudioPolicyService::AudioCommandThread::stopToneCommand() 797{ 798 AudioCommand *command = new AudioCommand(); 799 command->mCommand = STOP_TONE; 800 command->mParam = NULL; 801 command->mWaitStatus = false; 802 Mutex::Autolock _l(mLock); 803 insertCommand_l(command); 804 LOGV("AudioCommandThread() adding tone stop"); 805 mWaitWorkCV.signal(); 806} 807 808status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, 809 float volume, 810 int output, 811 int delayMs) 812{ 813 status_t status = NO_ERROR; 814 815 AudioCommand *command = new AudioCommand(); 816 command->mCommand = SET_VOLUME; 817 VolumeData *data = new VolumeData(); 818 data->mStream = stream; 819 data->mVolume = volume; 820 data->mIO = output; 821 command->mParam = data; 822 if (delayMs == 0) { 823 command->mWaitStatus = true; 824 } else { 825 command->mWaitStatus = false; 826 } 827 Mutex::Autolock _l(mLock); 828 insertCommand_l(command, delayMs); 829 LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", 830 stream, volume, output); 831 mWaitWorkCV.signal(); 832 if (command->mWaitStatus) { 833 command->mCond.wait(mLock); 834 status = command->mStatus; 835 mWaitWorkCV.signal(); 836 } 837 return status; 838} 839 840status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, 841 const String8& keyValuePairs, 842 int delayMs) 843{ 844 status_t status = NO_ERROR; 845 846 AudioCommand *command = new AudioCommand(); 847 command->mCommand = SET_PARAMETERS; 848 ParametersData *data = new ParametersData(); 849 data->mIO = ioHandle; 850 data->mKeyValuePairs = keyValuePairs; 851 command->mParam = data; 852 if (delayMs == 0) { 853 command->mWaitStatus = true; 854 } else { 855 command->mWaitStatus = false; 856 } 857 Mutex::Autolock _l(mLock); 858 insertCommand_l(command, delayMs); 859 LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", 860 keyValuePairs.string(), ioHandle, delayMs); 861 mWaitWorkCV.signal(); 862 if (command->mWaitStatus) { 863 command->mCond.wait(mLock); 864 status = command->mStatus; 865 mWaitWorkCV.signal(); 866 } 867 return status; 868} 869 870status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) 871{ 872 status_t status = NO_ERROR; 873 874 AudioCommand *command = new AudioCommand(); 875 command->mCommand = SET_VOICE_VOLUME; 876 VoiceVolumeData *data = new VoiceVolumeData(); 877 data->mVolume = volume; 878 command->mParam = data; 879 if (delayMs == 0) { 880 command->mWaitStatus = true; 881 } else { 882 command->mWaitStatus = false; 883 } 884 Mutex::Autolock _l(mLock); 885 insertCommand_l(command, delayMs); 886 LOGV("AudioCommandThread() adding set voice volume volume %f", volume); 887 mWaitWorkCV.signal(); 888 if (command->mWaitStatus) { 889 command->mCond.wait(mLock); 890 status = command->mStatus; 891 mWaitWorkCV.signal(); 892 } 893 return status; 894} 895 896// insertCommand_l() must be called with mLock held 897void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs) 898{ 899 ssize_t i; 900 Vector <AudioCommand *> removedCommands; 901 902 command->mTime = systemTime() + milliseconds(delayMs); 903 904 // acquire wake lock to make sure delayed commands are processed 905 if (mName != "" && mAudioCommands.isEmpty()) { 906 acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string()); 907 } 908 909 // check same pending commands with later time stamps and eliminate them 910 for (i = mAudioCommands.size()-1; i >= 0; i--) { 911 AudioCommand *command2 = mAudioCommands[i]; 912 // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands 913 if (command2->mTime <= command->mTime) break; 914 if (command2->mCommand != command->mCommand) continue; 915 916 switch (command->mCommand) { 917 case SET_PARAMETERS: { 918 ParametersData *data = (ParametersData *)command->mParam; 919 ParametersData *data2 = (ParametersData *)command2->mParam; 920 if (data->mIO != data2->mIO) break; 921 LOGV("Comparing parameter command %s to new command %s", 922 data2->mKeyValuePairs.string(), data->mKeyValuePairs.string()); 923 AudioParameter param = AudioParameter(data->mKeyValuePairs); 924 AudioParameter param2 = AudioParameter(data2->mKeyValuePairs); 925 for (size_t j = 0; j < param.size(); j++) { 926 String8 key; 927 String8 value; 928 param.getAt(j, key, value); 929 for (size_t k = 0; k < param2.size(); k++) { 930 String8 key2; 931 String8 value2; 932 param2.getAt(k, key2, value2); 933 if (key2 == key) { 934 param2.remove(key2); 935 LOGV("Filtering out parameter %s", key2.string()); 936 break; 937 } 938 } 939 } 940 // if all keys have been filtered out, remove the command. 941 // otherwise, update the key value pairs 942 if (param2.size() == 0) { 943 removedCommands.add(command2); 944 } else { 945 data2->mKeyValuePairs = param2.toString(); 946 } 947 } break; 948 949 case SET_VOLUME: { 950 VolumeData *data = (VolumeData *)command->mParam; 951 VolumeData *data2 = (VolumeData *)command2->mParam; 952 if (data->mIO != data2->mIO) break; 953 if (data->mStream != data2->mStream) break; 954 LOGV("Filtering out volume command on output %d for stream %d", 955 data->mIO, data->mStream); 956 removedCommands.add(command2); 957 } break; 958 case START_TONE: 959 case STOP_TONE: 960 default: 961 break; 962 } 963 } 964 965 // remove filtered commands 966 for (size_t j = 0; j < removedCommands.size(); j++) { 967 // removed commands always have time stamps greater than current command 968 for (size_t k = i + 1; k < mAudioCommands.size(); k++) { 969 if (mAudioCommands[k] == removedCommands[j]) { 970 LOGV("suppressing command: %d", mAudioCommands[k]->mCommand); 971 mAudioCommands.removeAt(k); 972 break; 973 } 974 } 975 } 976 removedCommands.clear(); 977 978 // insert command at the right place according to its time stamp 979 LOGV("inserting command: %d at index %d, num commands %d", 980 command->mCommand, (int)i+1, mAudioCommands.size()); 981 mAudioCommands.insertAt(command, i + 1); 982} 983 984void AudioPolicyService::AudioCommandThread::exit() 985{ 986 LOGV("AudioCommandThread::exit"); 987 { 988 AutoMutex _l(mLock); 989 requestExit(); 990 mWaitWorkCV.signal(); 991 } 992 requestExitAndWait(); 993} 994 995void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) 996{ 997 snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", 998 mCommand, 999 (int)ns2s(mTime), 1000 (int)ns2ms(mTime)%1000, 1001 mWaitStatus, 1002 mParam); 1003} 1004 1005}; // namespace android 1006