AudioPolicyManagerBase.cpp revision ca0657a1ca087a6d474a75fcfedd6aac3901d587
1f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin/* 2f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * Copyright (C) 2009 The Android Open Source Project 3f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * 4f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * Licensed under the Apache License, Version 2.0 (the "License"); 5f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * you may not use this file except in compliance with the License. 6f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * You may obtain a copy of the License at 7f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * 8f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * http://www.apache.org/licenses/LICENSE-2.0 9f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * 10f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * Unless required by applicable law or agreed to in writing, software 11f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * distributed under the License is distributed on an "AS IS" BASIS, 12f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * See the License for the specific language governing permissions and 14f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * limitations under the License. 15f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin */ 16f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 17f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#define LOG_TAG "AudioPolicyManagerBase" 18f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin//#define LOG_NDEBUG 0 19f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <utils/Log.h> 20f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <hardware_legacy/AudioPolicyManagerBase.h> 211c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent#include <hardware/audio_effect.h> 22f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <math.h> 23f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinnamespace android_audio_legacy { 25f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 26f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 27f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyInterface implementation 28f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 29f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 30f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 31f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_devices device, 32f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state, 33f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 34f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 35f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 366a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); 37f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 38f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // connect/disconnect only 1 device at a time 39f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::popCount(device) != 1) return BAD_VALUE; 40f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 41f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { 425efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid address: %s", device_address); 43f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 44f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 45f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 46f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output devices 47f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isOutputDevice(device)) { 48f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 49f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifndef WITH_A2DP 50f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isA2dpDevice(device)) { 515efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid device: %x", device); 52f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 53f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 54f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 55f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 56f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 57f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 58f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device connection 59f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: 60f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableOutputDevices & device) { 6164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %x", device); 62f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 63f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 646a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() connecting device %x", device); 65f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 66f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // register new device as available 67f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableOutputDevices |= device; 68f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 69f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 70f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle A2DP device connection 71f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isA2dpDevice(device)) { 72f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin status_t status = handleA2dpConnection(device, device_address); 73f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (status != NO_ERROR) { 74f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableOutputDevices &= ~device; 75f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return status; 76f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 77f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else 78f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 79f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 80f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isBluetoothScoDevice(device)) { 816a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() BT SCO device, address %s", device_address); 82f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // keep track of SCO device address 83f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 84f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 85f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 86f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 87f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device disconnection 88f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 89f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableOutputDevices & device)) { 9064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %x", device); 91f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 92f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 93f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 94f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 956a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() disconnecting device %x", device); 96f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // remove device from available output devices 97f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableOutputDevices &= ~device; 98f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 99f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle A2DP device disconnection 101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isA2dpDevice(device)) { 102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin status_t status = handleA2dpDisconnection(device, device_address); 103f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (status != NO_ERROR) { 104f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableOutputDevices |= device; 105f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return status; 106f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 107f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else 108f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 109f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 110f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isBluetoothScoDevice(device)) { 111f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mScoDeviceAddress = ""; 112f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 114f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 115f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 116f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 1175efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 118f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 119f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 120f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 121f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // request routing change if necessary 122f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t newDevice = getNewDevice(mHardwareOutput, false); 123f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 124f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 125f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 126f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // A2DP outputs must be closed after checkOutputForAllStrategies() is executed 127f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && AudioSystem::isA2dpDevice(device)) { 128f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin closeA2dpOutputs(); 129f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 130f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 131f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 132f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(mHardwareOutput, newDevice); 133f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 134f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 135f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_WIRED_HEADSET; 136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO || 137f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET || 138f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 139f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; 140f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 141f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 143f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 144f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input devices 145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isInputDevice(device)) { 146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 147f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 148f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 149f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device connection 150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: { 151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableInputDevices & device) { 15264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %d", device); 153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableInputDevices |= device; 156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device disconnection 160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableInputDevices & device)) { 16264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %d", device); 163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableInputDevices &= ~device; 166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 1695efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 171f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 173f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (newDevice != inputDesc->mDevice) { 1786a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() changing device from %x to %x for input %d", 179f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 180f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 181f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 182f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 183f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 19064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() invalid device: %x", device); 191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(AudioSystem::audio_devices device, 195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 196f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE; 198f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 address = String8(device_address); 199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isOutputDevice(device)) { 200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableOutputDevices) { 201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isA2dpDevice(device) && 203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin address != "" && mA2dpDeviceAddress != address) { 204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 206f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isBluetoothScoDevice(device) && 208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin address != "" && mScoDeviceAddress != address) { 209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 211f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (AudioSystem::isInputDevice(device)) { 214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableInputDevices) { 215f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 219f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 222f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setPhoneState(int state) 223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2246a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() state %d", state); 225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t newDevice = 0; 226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state < 0 || state >= AudioSystem::NUM_MODES) { 22764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() invalid state %d", state); 228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == mPhoneState ) { 23264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() setting same state %d", state); 233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if leaving call state, handle special case of active streams 237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 2396a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, true); 242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store previous phone state for management of sonification strategy below 246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int oldState = mPhoneState; 247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mPhoneState = state; 248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool force = false; 249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // are we entering or starting a call 251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isStateInCall(oldState) && isStateInCall(state)) { 2526a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Entering call in setPhoneState()"); 253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when starting a call 254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(oldState) && !isStateInCall(state)) { 2576a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Exiting call in setPhoneState()"); 258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when exiting a call 259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(state) && (state != oldState)) { 2626a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 263f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when switching between telephony and VoIP 264f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 266f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 267f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check for device and output changes triggered by new phone state 269f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin newDevice = getNewDevice(mHardwareOutput, false); 270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 271f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 274f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 275f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput); 277f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when ending call 279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(oldState) && newDevice == 0) { 281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin newDevice = hwOutputDesc->device(); 282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 283f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 284f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when changing from ring tone to in call mode, mute the ringing tone 285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // immediately and delay the route change to avoid sending the ring tone 286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // tail into the earpiece or headset. 287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int delayMs = 0; 288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) { 289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // delay the device change command by twice the output latency to have some margin 290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and be sure that audio buffers not yet affected by the mute are out when 291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // we actually apply the route change 292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delayMs = hwOutputDesc->mLatency*2; 293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStreamMute(AudioSystem::RING, true, mHardwareOutput); 294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 295f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // change routing is necessary 297f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(mHardwareOutput, newDevice, force, delayMs); 298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if entering in call state, handle special case of active streams 300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(state)) { 3026a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // unmute the ringing tone after a sufficient delay if it was muted before 304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // setting output device above 305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (oldState == AudioSystem::MODE_RINGTONE) { 306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStreamMute(AudioSystem::RING, false, mHardwareOutput, MUTE_TIME_MS); 307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, true, true); 310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == AudioSystem::MODE_RINGTONE && 315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = true; 317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = false; 319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) 323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3246a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool forceVolumeReeval = false; 327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(usage) { 328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_COMMUNICATION: 329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO && 330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 33164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 333f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_MEDIA: 338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP && 339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE) { 34264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_RECORD: 348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY && 349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 35064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 353f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 354f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_DOCK: 356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK && 357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_BT_DESK_DOCK && 358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_DIGITAL_DOCK) { 36164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 364f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 36764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid usage %d", usage); 368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 370f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 371f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check for device and output changes triggered by new phone state 372f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t newDevice = getNewDevice(mHardwareOutput, false); 373f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(mHardwareOutput, newDevice); 379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (forceVolumeReeval) { 380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin applyStreamVolumes(mHardwareOutput, newDevice, 0, true); 381f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 382f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin newDevice = getDeviceForInputSource(inputDesc->mInputSource); 387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (newDevice != inputDesc->mDevice) { 3886a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() changing device from %x to %x for input %d", 389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage) 400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mForceUse[usage]; 402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setSystemProperty(const char* property, const char* value) 405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 4066a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setSystemProperty() property %s, value %s", property, value); 407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (strcmp(property, "ro.camera.sound.forced") == 0) { 408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (atoi(value)) { 4096a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("ENFORCED_AUDIBLE cannot be muted"); 410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false; 411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 4126a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("ENFORCED_AUDIBLE can be muted"); 413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true; 414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream, 419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t channels, 422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::output_flags flags) 423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t output = 0; 425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t latency = 0; 426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); 427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device = getDeviceForStrategy(strategy); 4286a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() stream %d, samplingRate %d, format %d, channels %x, flags %x", stream, samplingRate, format, channels, flags); 429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mCurOutput != 0) { 4326a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channels %x, mDirectOutput %d", 433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 434f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 435f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput] == 0) { 4366a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() opening test output"); 437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(); 438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = mTestDevice; 439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = mTestSamplingRate; 440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFormat = mTestFormat; 441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mChannels = mTestChannels; 442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = mTestLatencyMs; 443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags = (AudioSystem::output_flags)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0); 444f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[mCurOutput] = mpClientInterface->openOutput(&outputDesc->mDevice, 446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mChannels, 449f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 450f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 451f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput]) { 452f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 453f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"),mCurOutput); 454f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 455f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(mTestOutputs[mCurOutput], outputDesc); 456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mTestOutputs[mCurOutput]; 459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 461f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 462f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a direct output if required by specified parameters 463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (needsDirectOuput(stream, samplingRate, format, channels, flags, device)) { 464f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4656a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() opening direct output device %x", device); 466f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(); 467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = device; 468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = samplingRate; 469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFormat = format; 470f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mChannels = channels; 471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = 0; 472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT); 473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mStopTime[stream] = 0; 475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin output = mpClientInterface->openOutput(&outputDesc->mDevice, 476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mChannels, 479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // only accept an output with the requeted parameters 483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == 0 || 484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || 485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != 0 && format != outputDesc->mFormat) || 486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (channels != 0 && channels != outputDesc->mChannels)) { 4876a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() failed opening direct output: samplingRate %d, format %d, channels %d", 488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin samplingRate, format, channels); 489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output != 0) { 490f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete outputDesc; 493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 495f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(output, outputDesc); 496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 498f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 499f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO && 500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels != AudioSystem::CHANNEL_OUT_STEREO) { 501f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 502f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 503f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a non direct output 504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // get which output is suitable for the specified stream. The actual routing change will happen 506f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when startOutput() will be called 507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t a2dpDevice = device & AudioSystem::DEVICE_OUT_ALL_A2DP; 508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::popCount((AudioSystem::audio_devices)device) == 2) { 509f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 510f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (a2dpUsedForSonification() && a2dpDevice != 0) { 511f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if playing on 2 devices among which one is A2DP, use duplicated output 5126a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() using duplicated output"); 51364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device in multiple %x selected but A2DP output not opened", device); 514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin output = mDuplicatedOutput; 515f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else 516f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 518f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if playing on 2 devices among which none is A2DP, use hardware output 519f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin output = mHardwareOutput; 520f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 5216a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() using output %d for 2 devices %x", output, device); 522f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 523f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 524f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (a2dpDevice != 0) { 525f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if playing on A2DP device, use a2dp output 52664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device %x selected but A2DP output not opened", device); 527f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin output = mA2dpOutput; 528f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else 529f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 530f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 531f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if playing on not A2DP device, use hardware output 532f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin output = mHardwareOutput; 533f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 534f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 535f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 536f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 53764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d, format %d, channels %x, flags %x", 538f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, samplingRate, format, channels, flags); 539f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 540f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 541f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, 544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 5476a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 549f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 55064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startOutput() unknow output %d", output); 551f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 552f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 553f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 554f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 555f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); 556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 557f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 558c16ac09f510437e8340be691720177a490ae78f0Eric Laurent if (mA2dpOutput != 0 && !a2dpUsedForSonification() && 559c16ac09f510437e8340be691720177a490ae78f0Eric Laurent (strategy == STRATEGY_SONIFICATION || strategy == STRATEGY_ENFORCED_AUDIBLE)) { 560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput); 561f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 562f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 563f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 564f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // incremenent usage count for this stream on the requested output: 565f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE that the usage count is the same for duplicated output and hardware output which is 566f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // necassary for a correct control of hardware output routing by startOutput() and stopOutput() 567f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, 1); 568f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 569c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent uint32_t prevDevice = outputDesc->device(); 570f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(output, getNewDevice(output)); 571c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent uint32_t newDevice = outputDesc->device(); 572f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 573f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle special case for sonification while in call 574f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 575f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, true, false); 576f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 577f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 578f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // apply volume rules for current stream and device if necessary 579c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 580c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].getVolumeIndex((audio_devices_t)newDevice), 581c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 582c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent newDevice); 583f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 584c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // FIXME: need a delay to make sure that audio path switches to speaker before sound 585c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // starts. Should be platform specific? 586c16ac09f510437e8340be691720177a490ae78f0Eric Laurent if (stream == AudioSystem::ENFORCED_AUDIBLE && 587c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent prevDevice != newDevice) { 588c16ac09f510437e8340be691720177a490ae78f0Eric Laurent usleep(outputDesc->mLatency*4*1000); 589c16ac09f510437e8340be691720177a490ae78f0Eric Laurent } 590c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 591f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 592f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 593f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 594f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, 595f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 596f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 597f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 5986a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 599f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 600f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 60164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() unknow output %d", output); 602f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 603f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 604f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 605f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); 607f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 608f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle special case for sonification while in call 609f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 610f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, false); 611f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 612f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 613f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream] > 0) { 614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // decrement usage count of this stream on the output 615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, -1); 616f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store time at which the stream was stopped - see isStreamActive() 617f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mStopTime[stream] = systemTime(); 618f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 619f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(output, getNewDevice(output), false, outputDesc->mLatency*2); 620f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 621f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 622f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpOutput != 0 && !a2dpUsedForSonification() && 623c16ac09f510437e8340be691720177a490ae78f0Eric Laurent (strategy == STRATEGY_SONIFICATION || strategy == STRATEGY_ENFORCED_AUDIBLE)) { 624f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStrategyMute(STRATEGY_MEDIA, 625f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin false, 626f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpOutput, 627f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueFor(mHardwareOutput)->mLatency*2); 628f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 629f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output != mHardwareOutput) { 631f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(mHardwareOutput, getNewDevice(mHardwareOutput), true); 632f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 633f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 63564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() refcount is already 0 for output %d", output); 636f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 637f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 638f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 639f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 640f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output) 641f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 6426a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseOutput() %d", output); 643f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 644f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 64564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseOutput() releasing unknown output %d", output); 646f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 647f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 649f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 650f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int testIndex = testOutputIndex(output); 651f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (testIndex != 0) { 652f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 653f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->refCount() == 0) { 654f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 655f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(index); 656f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(output); 657f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[testIndex] = 0; 658f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 659f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 660f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 662f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) { 664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 665f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(index); 666f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(output); 667f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 668f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 669f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 670f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource, 671f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 673f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t channels, 674f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::audio_in_acoustics acoustics) 675f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 676f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t input = 0; 677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device = getDeviceForInputSource(inputSource); 678f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6796a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x", inputSource, samplingRate, format, channels, acoustics); 680f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 681f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 682f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 683f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 684f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 685f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // adapt channel selection to input source 686f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(inputSource) { 687f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 688f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_IN_VOICE_UPLINK; 689f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 690f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_IN_VOICE_DNLINK; 692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 693f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 694f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK); 695f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 696f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 697f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 698f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 699f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 700f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = new AudioInputDescriptor(); 701f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 702f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mInputSource = inputSource; 703f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = device; 704f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mSamplingRate = samplingRate; 705f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mFormat = format; 706f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mChannels = channels; 707f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mAcoustics = acoustics; 708f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 709f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin input = mpClientInterface->openInput(&inputDesc->mDevice, 710f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mSamplingRate, 711f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mFormat, 712f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mChannels, 713f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mAcoustics); 714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 715f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // only accept input with the exact requested set of parameters 716f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input == 0 || 717f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != inputDesc->mSamplingRate) || 718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != inputDesc->mFormat) || 719f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (channels != inputDesc->mChannels)) { 7206a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getInput() failed opening input: samplingRate %d, format %d, channels %d", 721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin samplingRate, format, channels); 722f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input != 0) { 723f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 724f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 725f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete inputDesc; 726f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 727f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 728f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.add(input, inputDesc); 729f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return input; 730f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 731f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 732f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startInput(audio_io_handle_t input) 733f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7346a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startInput() input %d", input); 735f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 736f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 73764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startInput() unknow input %d", input); 738f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 739f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 740f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 741f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 742f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 743f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestInput == 0) 744f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 745f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 746f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // refuse 2 active AudioRecord clients at the same time 747f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getActiveInput() != 0) { 74864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startInput() input %d failed: other input already started", input); 749f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 750f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 751f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 752f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 753f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 754f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice); 755f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 756f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource); 7576a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 760f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 761f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 1; 762f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 764f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopInput(audio_io_handle_t input) 766f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7676a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopInput() input %d", input); 768f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 769f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 77064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() unknow input %d", input); 771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 772f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 773f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 774f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 775f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (inputDesc->mRefCount == 0) { 77664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() input %d already stopped", input); 777f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 778f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 779f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), 0); 781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 782f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 783f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 784f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 785f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseInput(audio_io_handle_t input) 788f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7896a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() %d", input); 790f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 791f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 79264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseInput() releasing unknown input %d", input); 793f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 794f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 795f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 796f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(index); 797f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.removeItem(input); 7986a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() exit"); 799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 800f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 801f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream, 802f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMin, 803f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMax) 804f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8056a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 806f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (indexMin < 0 || indexMin >= indexMax) { 80764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 808f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 809f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMin = indexMin; 811f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMax = indexMax; 812f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 813f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 814c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, 815c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 816c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 819f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 820f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 821f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 822c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 823c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 824c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 825f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 826f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force max volume if stream cannot be muted 827f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 828f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 829c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d", 830c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent stream, device, index); 831c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 832c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 833c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // clear all device specific values 834c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 835c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.clear(); 836c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 837c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 838f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 839f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // compute and apply stream volume on all outputs according to connected device 840f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin status_t status = NO_ERROR; 841f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 842f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device()); 843f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volStatus != NO_ERROR) { 844f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin status = volStatus; 845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 847f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return status; 848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 850c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, 851c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int *index, 852c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 853f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 854c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (index == NULL) { 855f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 856f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 857c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 858c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 859c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 860c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 861c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // the strategy the stream belongs to. 862c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 863c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = (audio_devices_t)getDeviceForStrategy(getStrategy(stream), true); 864c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 865c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = getDeviceForVolume(device); 866c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 867c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 868c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 869f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 870f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 871f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 872f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(effect_descriptor_t *desc) 873f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8746a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutputForEffect()"); 875f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // apply simple rule where global effects are attached to the same output as MUSIC streams 876f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return getOutput(AudioSystem::MUSIC); 877f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 878f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 879f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::registerEffect(effect_descriptor_t *desc, 8801c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent audio_io_handle_t io, 881f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t strategy, 882f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session, 883f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int id) 884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8851c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 886f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 8871c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent index = mInputs.indexOfKey(io); 8881c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent if (index < 0) { 88964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() unknown io %d", io); 8901c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent return INVALID_OPERATION; 8911c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent } 892f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 893f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 894f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 89564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 896f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin desc->name, desc->memoryUsage); 897f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 898f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 899f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory += desc->memoryUsage; 9006a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 9011c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent desc->name, io, strategy, session, id); 9026a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 903f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 904f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = new EffectDescriptor(); 905f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t)); 9061c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent pDesc->mIo = io; 907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mStrategy = (routing_strategy)strategy; 908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mSession = session; 909582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = false; 910582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 911f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.add(id, pDesc); 912f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 913f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 914f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 915f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 916f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::unregisterEffect(int id) 917f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 918f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mEffects.indexOfKey(id); 919f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 92064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 921f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 922f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 923f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 924f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = mEffects.valueAt(index); 925f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 926582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent setEffectEnabled(pDesc, false); 927582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 928f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) { 92964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() memory %d too big for total %d", 930f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 931f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage = mTotalEffectsMemory; 932f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory -= pDesc->mDesc.memoryUsage; 9346a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 935582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 936f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 937f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.removeItem(id); 938f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete pDesc; 939f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 940f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 943582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(int id, bool enabled) 944582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 945582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent ssize_t index = mEffects.indexOfKey(id); 946582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (index < 0) { 94764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 948582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 949582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 950582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 951582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 952582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 953582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 954582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(EffectDescriptor *pDesc, bool enabled) 955582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 956582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled == pDesc->mEnabled) { 9576a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(%s) effect already %s", 958582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 959582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 960582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 961582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 962582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled) { 963582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 96464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 965582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10); 966582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 967582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 968582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad; 9696a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 970582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } else { 971582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) { 97264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 973582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 974582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 975582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 976582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad; 9776a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 978582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 979582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = enabled; 980582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return NO_ERROR; 981582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 982582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const 984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 985f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin nsecs_t sysTime = systemTime(); 986f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 987f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueAt(i)->mRefCount[stream] != 0 || 988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ns2ms(sysTime - mOutputs.valueAt(i)->mStopTime[stream]) < inPastMs) { 989f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return true; 990f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 992f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 994f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 995f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 996f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::dump(int fd) 997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 999f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1000f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 1001f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1002f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 1003f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1004f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Hardware Output: %d\n", mHardwareOutput); 1005f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1006f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 1007f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " A2DP Output: %d\n", mA2dpOutput); 1008f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1009f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Duplicated Output: %d\n", mDuplicatedOutput); 1010f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1011f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string()); 1012f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1013f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 1014f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string()); 1015f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1016f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices); 1017f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1018f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices); 1019f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1020f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 1021f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1022f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]); 1023f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1024f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]); 1025f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1026f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]); 1027f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1028f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]); 1029f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1030f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 1031f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1032f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nOutputs dump:\n"); 1033f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1034f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1035f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 1036f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1037f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueAt(i)->dump(fd); 1038f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1039f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1040f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nInputs dump:\n"); 1041f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1042f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1043f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 1044f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1045f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.valueAt(i)->dump(fd); 1046f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1047f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1048f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nStreams dump:\n"); 1049f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1050c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, 1051c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 1052f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1053f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 1054c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, " %02d ", i); 1055f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1056c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[i].dump(fd); 1057f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1058f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1059f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 1060f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 1061f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1062f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1063f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "Registered effects:\n"); 1064f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1065f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mEffects.size(); i++) { 1066f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 1067f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1068f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.valueAt(i)->dump(fd); 1069f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1070f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1071f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1072f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1073f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1074f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1075f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1076f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyManagerBase 1077f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1078f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1079f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface) 1080f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin : 1081f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1082f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Thread(false), 1083f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1084ca0657a1ca087a6d474a75fcfedd6aac3901d587Glenn Kasten mPhoneState(AudioSystem::MODE_NORMAL), 1085f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 1086f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 1087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended(false) 1088f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1089f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface = clientInterface; 1090f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1091f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) { 1092f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[i] = AudioSystem::FORCE_NONE; 1093f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1095f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin initializeVolumeCurves(); 1096f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1097f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // devices available by default are speaker, ear piece and microphone 1098f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableOutputDevices = AudioSystem::DEVICE_OUT_EARPIECE | 1099f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::DEVICE_OUT_SPEAKER; 1100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC; 1101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 1103f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpOutput = 0; 1104f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDuplicatedOutput = 0; 1105f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpDeviceAddress = String8(""); 1106f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 1107f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mScoDeviceAddress = String8(""); 1108f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1109f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open hardware output 1110f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(); 1111f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER; 1112f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice, 1113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 1114f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 1115f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mChannels, 1116f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 1117f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 1118f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1119f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mHardwareOutput == 0) { 11205efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("Failed to initialize hardware output stream, samplingRate: %d, format %d, channels %d", 1121f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels); 1122f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1123f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(mHardwareOutput, outputDesc); 1124f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, true); 1125f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin //TODO: configure audio effect output stage here 1126f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1127f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1128f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 1129f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1130f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mHardwareOutput != 0) { 1131f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1132f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1133f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString()); 1134f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1135f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER; 1136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = 44100; 1137f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = AudioSystem::PCM_16_BIT; 1138f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = AudioSystem::CHANNEL_OUT_STEREO; 1139f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestLatencyMs = 0; 1140f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = 0; 1141f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1143f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[i] = 0; 1144f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1147f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1148f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 1149f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin run(buffer, ANDROID_PRIORITY_AUDIO); 1150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::~AudioPolicyManagerBase() 1155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin exit(); 1158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(mOutputs.keyAt(i)); 1161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(i); 1162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.clear(); 1164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(mInputs.keyAt(i)); 1166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(i); 1167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.clear(); 1169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1171f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::initCheck() 1172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1173f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return (mHardwareOutput == 0) ? NO_INIT : NO_ERROR; 1174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::threadLoop() 1178f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 11796a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("entering threadLoop()"); 1180f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin while (!exitPending()) 1181f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1182f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 command; 1183f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int valueInt; 1184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 value; 1185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Mutex::Autolock _l(mLock); 1187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 1188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 1190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(command); 1191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 1193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin valueInt != 0) { 11946a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("Test command %s received", command.string()); 1195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 target; 1196f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("target"), target) != NO_ERROR) { 1197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin target = "Manager"; 1198f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 1200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_output")); 1201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = valueInt; 1202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 1204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_direct")); 1205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "false") { 1206f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "true") { 1208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = true; 1209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1211f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 1212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_input")); 1213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestInput = valueInt; 1214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1215f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 1217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_format")); 1218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int format = AudioSystem::INVALID_FORMAT; 1219f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "PCM 16 bits") { 1220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_16_BIT; 1221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "PCM 8 bits") { 1222f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_8_BIT; 1223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Compressed MP3") { 1224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::MP3; 1225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (format != AudioSystem::INVALID_FORMAT) { 1227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = format; 1229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("format"), format); 1232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 1237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_channels")); 1238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int channels = 0; 1239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "Channels Stereo") { 1241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_STEREO; 1242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Channels Mono") { 1243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_MONO; 1244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (channels != 0) { 1246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = channels; 1248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("channels"), channels); 1251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 1256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_sampleRate")); 1257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (valueInt >= 0 && valueInt <= 96000) { 1258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int samplingRate = valueInt; 1259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = samplingRate; 1261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1262f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1263f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("sampling_rate"), samplingRate); 1264f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1266f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1267f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1269f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 1270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_reopen")); 1271f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(mHardwareOutput); 1273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueFor(mHardwareOutput); 1274f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(mHardwareOutput); 1275f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(); 1277f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER; 1278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice, 1279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 1280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 1281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mChannels, 1282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 1283f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 1284f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mHardwareOutput == 0) { 12855efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d", 1286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels); 1287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString()); 1291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(mHardwareOutput, outputDesc); 1292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1295f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 1297f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::exit() 1303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AutoMutex _l(mLock); 1306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExit(); 1307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.signal(); 1308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExitAndWait(); 1310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinint AudioPolicyManagerBase::testOutputIndex(audio_io_handle_t output) 1313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == mTestOutputs[i]) return i; 1316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 1318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- 1322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc) 1324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mId = id; 1326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.add(id, outputDesc); 1327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 1331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::handleA2dpConnection(AudioSystem::audio_devices device, 1332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 1333f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when an A2DP device is connected, open an A2DP and a duplicated output 13356a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("opening A2DP output for device %s", device_address); 1336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(); 1337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = device; 1338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpOutput = mpClientInterface->openOutput(&outputDesc->mDevice, 1339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 1340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 1341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mChannels, 1342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 1343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 1344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpOutput) { 1345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // add A2DP output descriptor 1346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(mA2dpOutput, outputDesc); 1347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin //TODO: configure audio effect output stage here 1349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // set initial stream volume for A2DP device 1351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin applyStreamVolumes(mA2dpOutput, device); 1352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (a2dpUsedForSonification()) { 1353f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDuplicatedOutput = mpClientInterface->openDuplicateOutput(mA2dpOutput, mHardwareOutput); 1354f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mDuplicatedOutput != 0 || 1356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin !a2dpUsedForSonification()) { 1357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // If both A2DP and duplicated outputs are open, send device address to A2DP hardware 1358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // interface 1359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param; 1360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.add(String8("a2dp_sink_address"), String8(device_address)); 1361f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mA2dpOutput, param.toString()); 1362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 1363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1364f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (a2dpUsedForSonification()) { 1365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // add duplicated output descriptor 1366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(); 1367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mOutput1 = mOutputs.valueFor(mHardwareOutput); 1368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mOutput2 = mOutputs.valueFor(mA2dpOutput); 1369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mSamplingRate = outputDesc->mSamplingRate; 1370f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mFormat = outputDesc->mFormat; 1371f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mChannels = outputDesc->mChannels; 1372f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mLatency = outputDesc->mLatency; 1373f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(mDuplicatedOutput, dupOutputDesc); 1374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin applyStreamVolumes(mDuplicatedOutput, device); 1375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 137764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getOutput() could not open duplicated output for %d and %d", 1378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mHardwareOutput, mA2dpOutput); 1379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(mA2dpOutput); 1380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(mA2dpOutput); 1381f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpOutput = 0; 1382f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete outputDesc; 1383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_INIT; 1384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 138664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() could not open A2DP output for device %x", device); 1387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete outputDesc; 1388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_INIT; 1389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput); 1391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!a2dpUsedForSonification()) { 1393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // mute music on A2DP output if a notification or ringtone is playing 1394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t refCount = hwOutputDesc->strategyRefCount(STRATEGY_SONIFICATION); 1395c16ac09f510437e8340be691720177a490ae78f0Eric Laurent refCount += hwOutputDesc->strategyRefCount(STRATEGY_ENFORCED_AUDIBLE); 1396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (uint32_t i = 0; i < refCount; i++) { 1397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput); 1398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = false; 1402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::handleA2dpDisconnection(AudioSystem::audio_devices device, 1407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 1408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpOutput == 0) { 141064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() disconnecting A2DP and no A2DP output!"); 1411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpDeviceAddress != device_address) { 141564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() disconnecting unknow A2DP sink address %s", device_address); 1416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // mute media strategy to avoid outputting sound on hardware output while music stream 1420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // is switched from A2DP output and before music is paused by music application 1421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStrategyMute(STRATEGY_MEDIA, true, mHardwareOutput); 1422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStrategyMute(STRATEGY_MEDIA, false, mHardwareOutput, MUTE_TIME_MS); 1423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!a2dpUsedForSonification()) { 1425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // unmute music on A2DP output if a notification or ringtone is playing 1426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t refCount = mOutputs.valueFor(mHardwareOutput)->strategyRefCount(STRATEGY_SONIFICATION); 1427c16ac09f510437e8340be691720177a490ae78f0Eric Laurent refCount += mOutputs.valueFor(mHardwareOutput)->strategyRefCount(STRATEGY_ENFORCED_AUDIBLE); 1428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (uint32_t i = 0; i < refCount; i++) { 1429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStrategyMute(STRATEGY_MEDIA, false, mA2dpOutput); 1430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1432f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpDeviceAddress = ""; 1433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = false; 1434f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1435f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1436f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::closeA2dpOutputs() 1438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 14406a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() closing A2DP and duplicated output!"); 1441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mDuplicatedOutput != 0) { 1443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *dupOutputDesc = mOutputs.valueFor(mDuplicatedOutput); 1444f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput); 1445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // As all active tracks on duplicated output will be deleted, 1446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and as they were also referenced on hardware output, the reference 1447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // count for their stream type must be adjusted accordingly on 1448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // hardware output. 1449f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 1450f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int refCount = dupOutputDesc->mRefCount[i]; 1451f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin hwOutputDesc->changeRefCount((AudioSystem::stream_type)i,-refCount); 1452f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1453f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1454f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(mDuplicatedOutput); 1455f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueFor(mDuplicatedOutput); 1456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(mDuplicatedOutput); 1457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDuplicatedOutput = 0; 1458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpOutput != 0) { 1460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param; 1461f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.add(String8("closing"), String8("true")); 1462f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mA2dpOutput, param.toString()); 1463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1464f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(mA2dpOutput); 1465f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueFor(mA2dpOutput); 1466f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(mA2dpOutput); 1467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpOutput = 0; 1468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1470f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy) 1472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t prevDevice = getDeviceForStrategy(strategy); 1474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t curDevice = getDeviceForStrategy(strategy, false); 1475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool a2dpWasUsed = AudioSystem::isA2dpDevice((AudioSystem::audio_devices)(prevDevice & ~AudioSystem::DEVICE_OUT_SPEAKER)); 1476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool a2dpIsUsed = AudioSystem::isA2dpDevice((AudioSystem::audio_devices)(curDevice & ~AudioSystem::DEVICE_OUT_SPEAKER)); 1477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t srcOutput = 0; 1478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t dstOutput = 0; 1479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (a2dpWasUsed && !a2dpIsUsed) { 1481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool dupUsed = a2dpUsedForSonification() && a2dpWasUsed && (AudioSystem::popCount(prevDevice) == 2); 1482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dstOutput = mHardwareOutput; 1483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (dupUsed) { 14846a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkOutputForStrategy() moving strategy %d from duplicated", strategy); 1485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin srcOutput = mDuplicatedOutput; 1486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 14876a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkOutputForStrategy() moving strategy %d from a2dp", strategy); 1488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin srcOutput = mA2dpOutput; 1489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1490f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (a2dpIsUsed && !a2dpWasUsed) { 1492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool dupUsed = a2dpUsedForSonification() && a2dpIsUsed && (AudioSystem::popCount(curDevice) == 2); 1493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin srcOutput = mHardwareOutput; 1494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (dupUsed) { 14956a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkOutputForStrategy() moving strategy %d to duplicated", strategy); 1496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dstOutput = mDuplicatedOutput; 1497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 14986a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkOutputForStrategy() moving strategy %d to a2dp", strategy); 1499f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dstOutput = mA2dpOutput; 1500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1501f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1502f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1503f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (srcOutput != 0 && dstOutput != 0) { 1504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Move effects associated to this strategy from previous output to new output 1505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mEffects.size(); i++) { 1506f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *desc = mEffects.valueAt(i); 1507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (desc->mSession != AudioSystem::SESSION_OUTPUT_STAGE && 1508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin desc->mStrategy == strategy && 15091c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent desc->mIo == srcOutput) { 15106a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkOutputForStrategy() moving effect %d to output %d", mEffects.keyAt(i), dstOutput); 1511f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->moveEffects(desc->mSession, srcOutput, dstOutput); 15121c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent desc->mIo = dstOutput; 1513f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1515f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Move tracks associated to this strategy from previous output to new output 1516f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 1517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)i) == strategy) { 1518f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, dstOutput); 1519f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1520f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1521f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1522f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1523f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1524f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkOutputForAllStrategies() 1525f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1526c16ac09f510437e8340be691720177a490ae78f0Eric Laurent checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 1527f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_PHONE); 1528f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_SONIFICATION); 1529f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_MEDIA); 1530f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_DTMF); 1531f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1532f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1533f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkA2dpSuspend() 1534f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1535f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // suspend A2DP output if: 1536f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (NOT already suspended) && 1537f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is connected && 1538f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage for communication || for record is SCO))) || 1539f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is ringing || in call) 1540f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1541f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // restore A2DP output if: 1542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (Already suspended) && 1543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is NOT connected || 1544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage NOT for communication && NOT for record is SCO))) && 1545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is NOT ringing && NOT in call) 1546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1547f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpOutput == 0) { 1548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 1549f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1550f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1551f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpSuspended) { 1552f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress == "") || 1553f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) && 1554f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) && 1555f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState != AudioSystem::MODE_IN_CALL) && 1556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState != AudioSystem::MODE_RINGTONE))) { 1557f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1558f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->restoreOutput(mA2dpOutput); 1559f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = false; 1560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1561f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1562f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress != "") && 1563f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 1564f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) || 1565f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState == AudioSystem::MODE_IN_CALL) || 1566f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState == AudioSystem::MODE_RINGTONE))) { 1567f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1568f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->suspendOutput(mA2dpOutput); 1569f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = true; 1570f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1571f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1572f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1573f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1574f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1575f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 1576f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1577f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache) 1578f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1579f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device = 0; 1580f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1581f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 1582f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check the following by order of priority to request a routing change if necessary: 1583c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 1: the strategy enforced audible is active on the output: 1584c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // use device for strategy enforced audible 1585c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 2: we are in call or the strategy phone is active on the output: 1586f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy phone 1587c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 3: the strategy sonification is active on the output: 1588f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy sonification 1589c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 4: the strategy media is active on the output: 1590f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy media 1591c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 5: the strategy DTMF is active on the output: 1592f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy DTMF 1593c16ac09f510437e8340be691720177a490ae78f0Eric Laurent if (outputDesc->isUsedByStrategy(STRATEGY_ENFORCED_AUDIBLE)) { 1594c16ac09f510437e8340be691720177a490ae78f0Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 1595c16ac09f510437e8340be691720177a490ae78f0Eric Laurent } else if (isInCall() || 1596c16ac09f510437e8340be691720177a490ae78f0Eric Laurent outputDesc->isUsedByStrategy(STRATEGY_PHONE)) { 1597f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 1598f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) { 1599f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 1600f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) { 1601f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 1602f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) { 1603f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 1604f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1605f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 16066a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getNewDevice() selected device %x", device); 1607f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return device; 1608f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1609f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1610f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getStrategyForStream(AudioSystem::stream_type stream) { 1611f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return (uint32_t)getStrategy(stream); 1612f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1613f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getDevicesForStream(AudioSystem::stream_type stream) { 1615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t devices; 1616f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // By checking the range of stream before calling getStrategy, we avoid 16175efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 1618f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and then return STRATEGY_MEDIA, but we want to return the empty set. 1619f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream < (AudioSystem::stream_type) 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 1620f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin devices = 0; 1621f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1622f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioPolicyManagerBase::routing_strategy strategy = getStrategy(stream); 1623f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin devices = getDeviceForStrategy(strategy, true); 1624f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1625f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return devices; 1626f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1627f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1628f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy( 1629f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream) { 1630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // stream to strategy mapping 1631f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (stream) { 1632f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::VOICE_CALL: 1633f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::BLUETOOTH_SCO: 1634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_PHONE; 1635f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::RING: 1636f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::NOTIFICATION: 1637f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::ALARM: 1638f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_SONIFICATION; 1639f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DTMF: 1640f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_DTMF; 1641f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 16425efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("unknown stream type"); 1643f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::SYSTEM: 1644f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 1645f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // while key clicks are played produces a poor result 1646f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::TTS: 1647f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::MUSIC: 1648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_MEDIA; 1649c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case AudioSystem::ENFORCED_AUDIBLE: 1650c16ac09f510437e8340be691720177a490ae78f0Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 1651f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1652f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1653f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1654f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, bool fromCache) 1655f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1656f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device = 0; 1657f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1658f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (fromCache) { 16596a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForStrategy() from cache strategy %d, device %x", strategy, mDeviceForStrategy[strategy]); 1660f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mDeviceForStrategy[strategy]; 1661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1662f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (strategy) { 1664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_DTMF: 1665f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall()) { 1666f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when off call, DTMF strategy follows the same rules as MEDIA strategy 1667f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_MEDIA, false); 1668f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1669f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1670f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when in call, DTMF and PHONE strategies follow the same rules 1671f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 1672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1673f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_PHONE: 1674f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // for phone strategy, we first consider the forced use and then the available devices by order 1675f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // of priority 1676f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { 1677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_BT_SCO: 1678f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall() || strategy != STRATEGY_DTMF) { 1679f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 1680f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1681f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1682f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 1683f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1684f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO; 1685f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1686f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if SCO device is requested but no SCO device is available, fall back to default case 1687f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 1688f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1689f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: // FORCE_NONE 1690f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE; 1691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; 1693f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1694f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 1695f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 1696f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall() && !mA2dpSuspended) { 1697f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; 1698f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1699f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 1700f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1701f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1702f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 1703f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 1704f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 170555ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 170655ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent if (device) break; 1707f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 1708f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1709f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE; 1710f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 17115efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("getDeviceForStrategy() earpiece device not found"); 1712f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1713f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1715f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_SPEAKER: 1716f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 1717f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 1718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // A2DP speaker when forcing to speaker output 1719f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall() && !mA2dpSuspended) { 1720f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 1721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1722f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1723f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 1724f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 1725f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 172655ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 172755ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent if (device) break; 1728f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 1729f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1730f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 1731f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 17325efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("getDeviceForStrategy() speaker device not found"); 1733f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1734f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1735f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1736f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1737f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1738f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_SONIFICATION: 1739f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1740f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 1741f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handleIncallSonification(). 1742f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 1743f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_PHONE, false); 1744f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1745f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1746c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // FALL THROUGH 1747c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 1748c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 1749c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 1750c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // except when in call where it doesn't default to STRATEGY_PHONE behavior 1751c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 1752f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 1753f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 17545efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("getDeviceForStrategy() speaker device not found"); 1755f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1756f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // The second device used for sonification is the same as the device used by media strategy 1757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 1758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_MEDIA: { 1760f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE; 1761f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1762f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; 1763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1764f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 1765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((mA2dpOutput != 0) && !mA2dpSuspended && 1766c16ac09f510437e8340be691720177a490ae78f0Eric Laurent (strategy == STRATEGY_MEDIA || a2dpUsedForSonification())) { 1767f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1768f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; 1769f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1770f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 1772f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1773f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1774f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 1775f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1776f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1777f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 1778f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 177955ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 1780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 178255ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 1783f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1784f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1785f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 1786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1788f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 1789f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1790f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1791c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 1792c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, 0 otherwise 1793f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device |= device2; 1794f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 17955efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("getDeviceForStrategy() speaker device not found"); 1796f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1797f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 1798f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 180064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 1801f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1802f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1803f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 18046a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 1805f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return device; 1806f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1807f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1808f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::updateDeviceForStrategy() 1809f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_STRATEGIES; i++) { 1811f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false); 1812f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1813f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1814f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1815f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, uint32_t device, bool force, int delayMs) 1816f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 18176a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setOutputDevice() output %d device %x delayMs %d", output, device, delayMs); 1818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 1819f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1820f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1821f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->isDuplicated()) { 1822f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); 1823f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); 1824f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 1825f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1826f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef WITH_A2DP 1827f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // filter devices according to output selected 1828f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == mA2dpOutput) { 1829f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device &= AudioSystem::DEVICE_OUT_ALL_A2DP; 1830f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1831f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device &= ~AudioSystem::DEVICE_OUT_ALL_A2DP; 1832f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1833f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif 1834f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1835f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t prevDevice = (uint32_t)outputDesc->device(); 1836f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Do not change the routing if: 1837f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the requestede device is 0 1838f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the requested device is the same as current device and force is not specified. 1839f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Doing this check here allows the caller to call setOutputDevice() without conditions 1840f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((device == 0 || device == prevDevice) && !force) { 18416a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setOutputDevice() setting same device %x or null device for output %d", device, output); 1842f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 1843f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1844f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = device; 1846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // mute media streams if both speaker and headset are selected 1847f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == mHardwareOutput && AudioSystem::popCount(device) == 2) { 1848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStrategyMute(STRATEGY_MEDIA, true, output); 1849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // wait for the PCM output buffers to empty before proceeding with the rest of the command 1850497fb4566204c88bd247aafc2412ddef8f85e480Eric Laurent // FIXME: increased delay due to larger buffers used for low power audio mode. 1851497fb4566204c88bd247aafc2412ddef8f85e480Eric Laurent // remove when low power audio is controlled by policy manager. 1852497fb4566204c88bd247aafc2412ddef8f85e480Eric Laurent usleep(outputDesc->mLatency*8*1000); 1853f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1854f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1855f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do the routing 1856f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 1857f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)device); 1858f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mHardwareOutput, param.toString(), delayMs); 1859f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // update stream volumes according to new device 1860f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin applyStreamVolumes(output, device, delayMs); 1861f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if changing from a combined headset + speaker route, unmute media streams 1863f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == mHardwareOutput && AudioSystem::popCount(prevDevice) == 2) { 1864f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStrategyMute(STRATEGY_MEDIA, false, output, delayMs); 1865f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1866f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1867f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1868f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) 1869f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1870f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device; 1871f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1872f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(inputSource) { 1873f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_DEFAULT: 1874f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_MIC: 1875f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_RECOGNITION: 1876f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_COMMUNICATION: 1877f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO && 1878f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 1879f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; 1880f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 1881f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_WIRED_HEADSET; 1882f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1883f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BUILTIN_MIC; 1884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1885f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1886f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_CAMCORDER: 1887f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (hasBackMicrophone()) { 1888f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BACK_MIC; 1889f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1890f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BUILTIN_MIC; 1891f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1892f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1893f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 1894f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 1895f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 1896f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_VOICE_CALL; 1897f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1898f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 189964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 1900f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = 0; 1901f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1902f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 19036a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 1904f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return device; 1905f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1906f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getActiveInput() 1908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1910f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mInputs.valueAt(i)->mRefCount > 0) { 1911f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mInputs.keyAt(i); 1912f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1913f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1914f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 1915f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1916f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1917e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 1918c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForVolume(audio_devices_t device) 1919e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 1920e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent if (device == 0) { 1921e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // this happens when forcing a route update and no track is active on an output. 1922e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // In this case the returned category is not important. 1923c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 1924c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else if (AudioSystem::popCount(device) > 1) { 1925e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // Multiple device selection is either: 1926e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - speaker + one other device: give priority to speaker in this case. 1927e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 1928e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 1929e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // selection if not the speaker. 1930c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 1931c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 1932c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else { 1933c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 1934c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1935e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 1936e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 193764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW_IF(AudioSystem::popCount(device) != 1, 1938c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 1939e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device); 1940e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 1941c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return device; 1942c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 1943c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 1944c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric LaurentAudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(uint32_t device) 1945c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 1946c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent switch(getDeviceForVolume((audio_devices_t)device)) { 1947e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 1948e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_EARPIECE; 1949e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 1950e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 1951e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 1952e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 1953e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 1954e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 1955e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_HEADSET; 1956e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 1957e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 1958e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 1959c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent case AUDIO_DEVICE_OUT_AUX_DIGITAL: 1960e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent default: 1961e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_SPEAKER; 1962e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 1963e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent} 1964e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 1965f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinfloat AudioPolicyManagerBase::volIndexToAmpl(uint32_t device, const StreamDescriptor& streamDesc, 1966e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int indexInUi) 1967e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 1968e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device_category deviceCategory = getDeviceCategory(device); 1969e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 1970e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 1971f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // the volume index in the UI is relative to the min and max volume indices for this stream type 1972e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 1973e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[VOLMIN].mIndex; 1974f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 1975f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (streamDesc.mIndexMax - streamDesc.mIndexMin); 1976f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1977f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // find what part of the curve this index volume belongs to, or if it's out of bounds 1978f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int segment = 0; 1979e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 1980f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0.0f; 1981e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 1982f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 0; 1983e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 1984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 1; 1985e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 1986f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 2; 1987f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { // out of bounds 1988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0f; 1989f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1990f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // linear interpolation in the attenuation table in dB 1992e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent float decibels = curve[segment].mDBAttenuation + 1993e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 1994e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ( (curve[segment+1].mDBAttenuation - 1995e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation) / 1996e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(curve[segment+1].mIndex - 1997e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex)) ); 1998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1999f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 2000f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 20016a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 2002e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex, volIdx, 2003e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mIndex, 2004e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation, 2005cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent decibels, 2006e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mDBAttenuation, 2007f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin amplification); 2008f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2009f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return amplification; 2010f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2011f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2012cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2013e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2014e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 2015e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2016e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2017e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2018e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2019e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 2020cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent}; 2021cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent 2022e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2023e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2024e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 2025e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2026e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2027e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2028e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2029e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 2030e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2031e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2032e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2033e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2034e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent *AudioPolicyManagerBase::sVolumeProfiles[AudioPolicyManagerBase::NUM_STRATEGIES] 2035e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent [AudioPolicyManagerBase::DEVICE_CATEGORY_CNT] = { 2036e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent { // STRATEGY_MEDIA 2037e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 2038e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2039e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 2040e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2041e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent { // STRATEGY_PHONE 2042e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2043e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2044e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2045e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2046e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent { // STRATEGY_SONIFICATION 2047e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2048e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2049e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2050e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2051e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent { // STRATEGY_DTMF 2052e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2053e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2054e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2055c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2056c16ac09f510437e8340be691720177a490ae78f0Eric Laurent { // STRATEGY_ENFORCED_AUDIBLE 2057c16ac09f510437e8340be691720177a490ae78f0Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2058c16ac09f510437e8340be691720177a490ae78f0Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2059c16ac09f510437e8340be691720177a490ae78f0Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2060c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2061e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2062e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2063e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentvoid AudioPolicyManagerBase::initializeVolumeCurves() 2064e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2065e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 2066e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 2067cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent mStreams[i].mVolumeCurve[j] = 2068cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent sVolumeProfiles[getStrategy((AudioSystem::stream_type)i)][j]; 2069cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2070cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2071f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2072f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2073c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentfloat AudioPolicyManagerBase::computeVolume(int stream, 2074c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2075c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2076c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent uint32_t device) 2077f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2078f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = 1.0; 2079f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2080f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 2081f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2082f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 2083f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = outputDesc->device(); 2084f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2085f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2086f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if volume is not 0 (not muted), force media volume to max on digital output 2087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::MUSIC && 2088f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin index != mStreams[stream].mIndexMin && 208955ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent (device == AudioSystem::DEVICE_OUT_AUX_DIGITAL || 209055ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) { 2091f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0; 2092f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2093f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = volIndexToAmpl(device, streamDesc, index); 2095f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2096f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if a headset is connected, apply the following rules to ring tones and notifications 2097f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // to avoid sound level bursts in user's ears: 2098f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - always attenuate ring tones and notifications volume by 6dB 2099f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - if music is playing, always limit the volume to current music volume, 2100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // with a minimum threshold at -36dB so that notification is always perceived. 2101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((device & 2102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP | 2103f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 2104f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::DEVICE_OUT_WIRED_HEADSET | 2105f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) && 2106f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) || 2107f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (stream == AudioSystem::SYSTEM)) && 2108f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin streamDesc.mCanBeMuted) { 2109f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 2110f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when the phone is ringing we must consider that music could have been paused just before 2111f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // by the music application and behave as if music was active if the last music track was 2112f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // just stopped 2113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[AudioSystem::MUSIC] || mLimitRingtoneVolume) { 2114c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float musicVol = computeVolume(AudioSystem::MUSIC, 2115c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[AudioSystem::MUSIC].getVolumeIndex((audio_devices_t)device), 2116c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2117c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent (uint32_t)device); 2118c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 2119c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 2120f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume > minVol) { 2121f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = minVol; 21226a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 2123f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2124f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2125f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2126f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2127f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return volume; 2128f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2129f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2130c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::checkAndSetVolume(int stream, 2131c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2132c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2133c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent uint32_t device, 2134c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 2135c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 2136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2137f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2138f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change actual stream volume if the stream is muted 2139f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 21406a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkAndSetVolume() stream %d muted count %d", stream, mOutputs.valueFor(output)->mMuteCount[stream]); 2141f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2143f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2144f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change in call volume if bluetooth is connected and vice versa 2145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 2146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) { 21476a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 2148f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, mForceUse[AudioSystem::FOR_COMMUNICATION]); 2149f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 2150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = computeVolume(stream, index, output, device); 2153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // We actually change the volume if: 2154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the float value returned by computeVolume() changed 2155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the force flag is set 2156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 2157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force) { 2158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueFor(output)->mCurVolume[stream] = volume; 21596a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setStreamVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 2160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL || 2161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::DTMF || 2162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::BLUETOOTH_SCO) { 2163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // offset value to reflect actual hardware volume that never reaches 0 2164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java) 2165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = 0.01 + 0.99 * volume; 2166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 2167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // enabled 2168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::BLUETOOTH_SCO) { 2169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs); 2170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2171f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2173f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); 2174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL || 2177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::BLUETOOTH_SCO) { 2178f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float voiceVolume; 2179f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force voice volume to max for bluetooth SCO as volume is managed by the headset 2180f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL) { 2181f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 2182f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2183f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = 1.0; 2184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (voiceVolume != mLastVoiceVolume && output == mHardwareOutput) { 2187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 2188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLastVoiceVolume = voiceVolume; 2189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2195c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, 2196c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent uint32_t device, 2197c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 2198c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 2199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 22006a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("applyStreamVolumes() for output %d and device %x", output, device); 2201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 2203c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 2204c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].getVolumeIndex((audio_devices_t)device), 2205c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2206c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 2207c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs, 2208c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent force); 2209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2211f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output, int delayMs) 2213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 22146a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 2215f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 2216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)stream) == strategy) { 2217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStreamMute(stream, on, output, delayMs); 2218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2219f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2222f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs) 2223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 2225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2226c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent uint32_t device = outputDesc->device(); 2227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 22286a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, outputDesc->mMuteCount[stream]); 2229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (on) { 2231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 2232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (streamDesc.mCanBeMuted) { 2233c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 2234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 2237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mMuteCount[stream]++; 2238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 224064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setStreamMute() unmuting non muted stream!"); 2241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 2242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (--outputDesc->mMuteCount[stream] == 0) { 2244c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 2245c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent streamDesc.getVolumeIndex((audio_devices_t)device), 2246c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2247c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 2248c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs); 2249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, bool stateChange) 2254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if the stream pertains to sonification strategy and we are in call we must 2256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // mute the stream if it is low visibility. If it is high visibility, we must play a tone 2257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // in the device used for phone strategy and play the tone if the selected device does not 2258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // interfere with the device used for phone strategy 2259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 2260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // many times as there are active tracks on the output 2261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2262f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) { 2263f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mHardwareOutput); 22646a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 2265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, starting, outputDesc->mDevice, stateChange); 2266f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream]) { 2267f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int muteCount = 1; 2268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stateChange) { 2269f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin muteCount = outputDesc->mRefCount[stream]; 2270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2271f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) { 22726a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 2273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 2274f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStreamMute(stream, starting, mHardwareOutput); 2275f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 22776a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility"); 2278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->device() & getDeviceForStrategy(STRATEGY_PHONE)) { 22796a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 2280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 2281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStreamMute(stream, starting, mHardwareOutput); 2282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2283f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2284f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (starting) { 2285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL); 2286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->stopTone(); 2288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isInCall() 2295f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return isStateInCall(mPhoneState); 2297f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStateInCall(int state) { 2300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((state == AudioSystem::MODE_IN_CALL) || 2301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (state == AudioSystem::MODE_IN_COMMUNICATION)); 2302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream, 2305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 2306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 2307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t channels, 2308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::output_flags flags, 2309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device) 2310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) || 2312e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin (format !=0 && !AudioSystem::isLinearPCM(format))); 2313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsCpuLoad() 2316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_CPU_LOAD; 2318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsMemory() 2321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_MEMORY; 2323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioOutputDescriptor class implementation 2326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor() 2328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin : mId(0), mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0), 2329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mFlags((AudioSystem::output_flags)0), mDevice(0), mOutput1(0), mOutput2(0) 2330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // clear usage count for all stream types 2332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 2333f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[i] = 0; 2334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurVolume[i] = -1.0; 2335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mMuteCount[i] = 0; 2336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStopTime[i] = 0; 2337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::device() 2341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device = 0; 2343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 2344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mOutput1->mDevice | mOutput2->mDevice; 2345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mDevice; 2347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return device; 2349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta) 2352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2353f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // forward usage count change to attached outputs 2354f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 2355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput1->changeRefCount(stream, delta); 2356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput2->changeRefCount(stream, delta); 2357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((delta + (int)mRefCount[stream]) < 0) { 235964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]); 2360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] = 0; 2361f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 2362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] += delta; 23646a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 2365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::refCount() 2368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t refcount = 0; 2370f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 2371f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin refcount += mRefCount[i]; 2372f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2373f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return refcount; 2374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::strategyRefCount(routing_strategy strategy) 2377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t refCount = 0; 2379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 2380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)i) == strategy) { 2381f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin refCount += mRefCount[i]; 2382f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return refCount; 2385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd) 2388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 2390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 2391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 2392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 2394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 2396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Channels: %08x\n", mChannels); 2398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 2400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 2402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", device()); 2404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 2406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 2408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 2409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 2412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioInputDescriptor class implementation 2417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor() 2419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin : mSamplingRate(0), mFormat(0), mChannels(0), 24201c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0), 24211c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent mInputSource(0) 2422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd) 2426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 2428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 2429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 2430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 2432f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 2434f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2435f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Channels: %08x\n", mChannels); 2436f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics); 2438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 2440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 2442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 2444f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- StreamDescriptor class implementation 2449f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2450c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric LaurentAudioPolicyManagerBase::StreamDescriptor::StreamDescriptor() 2451c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 2452c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 2453c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 2454c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 2455c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2456c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentint AudioPolicyManagerBase::StreamDescriptor::getVolumeIndex(audio_devices_t device) 2457c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 2458c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AudioPolicyManagerBase::getDeviceForVolume(device); 2459c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 2460c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 2461c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 2462c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 2463c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return mIndexCur.valueFor(device); 2464c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 2465c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2466c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::StreamDescriptor::dump(int fd) 2467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2468c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent const size_t SIZE = 256; 2469c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent char buffer[SIZE]; 2470c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent String8 result; 2471c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2472c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 2473c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 2474c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 2475c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 2476c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 2477c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.keyAt(i), 2478c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.valueAt(i)); 2479c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 2480c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 2481c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append("\n"); 2482c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2483c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent write(fd, result.string(), result.size()); 2484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- EffectDescriptor class implementation 2487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::EffectDescriptor::dump(int fd) 2489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2490f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 2491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 2492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 2493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24941c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 2495f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 2497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2498f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Session: %d\n", mSession); 2499f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 2501f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2502582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 2503582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent result.append(buffer); 2504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 2505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2506f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2509f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2510f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2511f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin}; // namespace android 2512