AudioPolicyManagerBase.cpp revision 01e6272f0a3a7d1d53e826012377ff9269b03b06
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> 2208b014d9e509c9163db6b33a63852e73db4d07ccEric Laurent#include <hardware/audio.h> 23f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <math.h> 245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#include <hardware_legacy/audio_policy_conf.h> 25f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 26e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinnamespace android_audio_legacy { 27f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 28f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 29f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyInterface implementation 30f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 31f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 32f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 33f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_devices device, 34f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state, 35f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 36f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 37b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t output = 0; 38f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 396a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); 40f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 41f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // connect/disconnect only 1 device at a time 42f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::popCount(device) != 1) return BAD_VALUE; 43f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 44f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { 455efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid address: %s", device_address); 46f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 47f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 48f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 49f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output devices 50f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isOutputDevice(device)) { 51f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp && AudioSystem::isA2dpDevice(device)) { 535efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid device: %x", device); 54f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 55f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 56599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (!mHasUsb && audio_is_usb_device((audio_devices_t)device)) { 57599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent ALOGE("setDeviceConnectionState() invalid device: %x", device); 58599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent return BAD_VALUE; 59599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 60f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 61f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 62f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 63f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device connection 64f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: 65f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableOutputDevices & device) { 6664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %x", device); 67f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 68f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 696a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() connecting device %x", device); 70f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 71f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // register new device as available 72f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device); 73f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 74f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent output = checkOutputForDevice((audio_devices_t)device, state); 75b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (output == 0) { 76f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device); 77b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return INVALID_OPERATION; 78b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 79f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle A2DP device connection 805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mHasA2dp && AudioSystem::isA2dpDevice(device)) { 81b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioParameter param; 8208b014d9e509c9163db6b33a63852e73db4d07ccEric Laurent param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), String8(device_address)); 83b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(output, param.toString()); 84b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 85b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpSuspended = false; 86b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else if (AudioSystem::isBluetoothScoDevice(device)) { 87b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("setDeviceConnectionState() BT SCO device, address %s", device_address); 88b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // keep track of SCO device address 89b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 90599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } else if (mHasUsb && audio_is_usb_device((audio_devices_t)device)) { 91599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mUsbCardAndDevice = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 92599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mpClientInterface->setParameters(output, mUsbCardAndDevice); 93f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 94f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 95f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device disconnection 96f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 97f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableOutputDevices & device)) { 9864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %x", device); 99f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1036a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() disconnecting device %x", device); 104f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // remove device from available output devices 105f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device); 106f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 107f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent output = checkOutputForDevice((audio_devices_t)device, state); 108f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle A2DP device disconnection 1095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mHasA2dp && AudioSystem::isA2dpDevice(device)) { 110b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpDeviceAddress = ""; 111b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpSuspended = false; 112b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else if (AudioSystem::isBluetoothScoDevice(device)) { 113b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mScoDeviceAddress = ""; 114599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } else if (mHasUsb && audio_is_usb_device((audio_devices_t)device)) { 115599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mUsbCardAndDevice = ""; 116f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 117f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 118f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 119f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 1205efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 121f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 122f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 123f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 124f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 125f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 126b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // outputs must be closed after checkOutputForAllStrategies() is executed 127b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && output != 0) { 128b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent closeOutput(output); 129f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 131f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 1325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(mOutputs.keyAt(i), getNewDevice(mOutputs.keyAt(i), true /*fromCache*/)); 1345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 135f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 137f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_WIRED_HEADSET; 138f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO || 139f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET || 140f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 141f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; 142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 143f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 144f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input devices 147f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isInputDevice(device)) { 148f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 149f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device connection 152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: { 153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableInputDevices & device) { 15464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %d", device); 155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAvailableInputDevices = (audio_devices_t)(mAvailableInputDevices | device); 158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device disconnection 162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableInputDevices & device)) { 16464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %d", device); 165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAvailableInputDevices = (audio_devices_t) (mAvailableInputDevices & ~device); 168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 1715efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 173f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 178f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 1795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if ((newDevice != 0) && (newDevice != inputDesc->mDevice)) { 1806a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() changing device from %x to %x for input %d", 181f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 182f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 183f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 19264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() invalid device: %x", device); 193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 196f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(AudioSystem::audio_devices device, 197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 198f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE; 200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 address = String8(device_address); 201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isOutputDevice(device)) { 202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableOutputDevices) { 203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isA2dpDevice(device) && 2045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (!mHasA2dp || (address != "" && mA2dpDeviceAddress != address))) { 205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 206f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isBluetoothScoDevice(device) && 208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin address != "" && mScoDeviceAddress != address) { 209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 211599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (audio_is_usb_device((audio_devices_t)device) && 212599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent (!mHasUsb || (address != "" && mUsbCardAndDevice != address))) { 213599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent ALOGE("setDeviceConnectionState() invalid device: %x", device); 214599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent return state; 215599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (AudioSystem::isInputDevice(device)) { 219f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableInputDevices) { 220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 222f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setPhoneState(int state) 228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2296a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() state %d", state); 230f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t newDevice = (audio_devices_t)0; 231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state < 0 || state >= AudioSystem::NUM_MODES) { 23264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() invalid state %d", state); 233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == mPhoneState ) { 23764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() setting same state %d", state); 238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if leaving call state, handle special case of active streams 242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 2446a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, true); 247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store previous phone state for management of sonification strategy below 251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int oldState = mPhoneState; 252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mPhoneState = state; 253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool force = false; 254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // are we entering or starting a call 256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isStateInCall(oldState) && isStateInCall(state)) { 2576a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Entering call in setPhoneState()"); 258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when starting a call 259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(oldState) && !isStateInCall(state)) { 2626a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Exiting call in setPhoneState()"); 263f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when exiting a call 264f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 266f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(state) && (state != oldState)) { 2676a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when switching between telephony and VoIP 269f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 271f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check for device and output changes triggered by new phone state 2745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/); 275f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 277f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 279b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when ending call 282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 283f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(oldState) && newDevice == 0) { 284f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin newDevice = hwOutputDesc->device(); 285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when changing from ring tone to in call mode, mute the ringing tone 288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // immediately and delay the route change to avoid sending the ring tone 289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // tail into the earpiece or headset. 290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int delayMs = 0; 291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) { 292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // delay the device change command by twice the output latency to have some margin 293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and be sure that audio buffers not yet affected by the mute are out when 294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // we actually apply the route change 295f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delayMs = hwOutputDesc->mLatency*2; 296b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(AudioSystem::RING, true, mPrimaryOutput); 297f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // change routing is necessary 300b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setOutputDevice(mPrimaryOutput, newDevice, force, delayMs); 301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if entering in call state, handle special case of active streams 303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(state)) { 3056a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // unmute the ringing tone after a sufficient delay if it was muted before 307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // setting output device above 308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (oldState == AudioSystem::MODE_RINGTONE) { 309b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(AudioSystem::RING, false, mPrimaryOutput, MUTE_TIME_MS); 310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, true, true); 313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == AudioSystem::MODE_RINGTONE && 318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = true; 320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = false; 322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) 326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3276a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool forceVolumeReeval = false; 330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(usage) { 331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_COMMUNICATION: 332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO && 333f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 33464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_MEDIA: 341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP && 342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE) { 34564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_RECORD: 351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY && 352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 35364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 354f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_DOCK: 359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK && 360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_BT_DESK_DOCK && 361f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_DIGITAL_DOCK) { 36464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 37064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid usage %d", usage); 371f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 372f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 373f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // check for device and output changes triggered by new force usage 375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 3785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 3795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 3805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, true /*fromCache*/); 3815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(output, newDevice, true); 3825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (forceVolumeReeval) { 3835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent applyStreamVolumes(output, newDevice, 0, true); 3845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 3905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 3915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if ((newDevice != 0) && (newDevice != inputDesc->mDevice)) { 3926a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() changing device from %x to %x for input %d", 393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage) 404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mForceUse[usage]; 406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setSystemProperty(const char* property, const char* value) 409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 4106a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setSystemProperty() property %s, value %s", property, value); 411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (strcmp(property, "ro.camera.sound.forced") == 0) { 412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (atoi(value)) { 4136a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("ENFORCED_AUDIBLE cannot be muted"); 414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false; 415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 4166a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("ENFORCED_AUDIBLE can be muted"); 417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true; 418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 42270c236c9290732782d5267935af1475b8d5ae602Eric Laurentaudio_module_handle_t AudioPolicyManagerBase::getModuleForDirectoutput(audio_devices_t device, 42370c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 42470c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t format, 42570c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 4260977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags) 42770c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 42870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 42970c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 43070c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 43170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 43270c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { 43370c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->isCompatibleProfile(device, samplingRate, format, 43470c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask, flags)) { 43570c236c9290732782d5267935af1475b8d5ae602Eric Laurent return mHwModules[i]->mHandle; 43670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 43770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 43870c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 43970c236c9290732782d5267935af1475b8d5ae602Eric Laurent return 0; 44070c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 44170c236c9290732782d5267935af1475b8d5ae602Eric Laurent 442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream, 443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 444f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 44570c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::output_flags flags) 447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t output = 0; 449f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t latency = 0; 450f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); 4515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 45270c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getOutput() stream %d, samplingRate %d, format %d, channelMask %x, flags %x", 45370c236c9290732782d5267935af1475b8d5ae602Eric Laurent stream, samplingRate, format, channelMask, flags); 454f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 455f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mCurOutput != 0) { 45770c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", 458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput] == 0) { 4616a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() opening test output"); 462f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(); 463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = mTestDevice; 464f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = mTestSamplingRate; 465f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFormat = mTestFormat; 46670c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mChannelMask = mTestChannels; 467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = mTestLatencyMs; 4680977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent outputDesc->mFlags = (audio_output_flags_t)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0); 469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 47070c236c9290732782d5267935af1475b8d5ae602Eric Laurent mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice, 471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 47370c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput]) { 477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"),mCurOutput); 479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(mTestOutputs[mCurOutput], outputDesc); 481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mTestOutputs[mCurOutput]; 484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a direct output if required by specified parameters 48870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (needsDirectOuput((audio_stream_type_t)stream, 48970c236c9290732782d5267935af1475b8d5ae602Eric Laurent samplingRate, 49070c236c9290732782d5267935af1475b8d5ae602Eric Laurent (audio_format_t)format, 49170c236c9290732782d5267935af1475b8d5ae602Eric Laurent (audio_channel_mask_t)channelMask, 4920977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent (audio_output_flags_t)flags, 49370c236c9290732782d5267935af1475b8d5ae602Eric Laurent device)) { 494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4956a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() opening direct output device %x", device); 49670c236c9290732782d5267935af1475b8d5ae602Eric Laurent 49770c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_module_handle_t module = getModuleForDirectoutput(device, 49870c236c9290732782d5267935af1475b8d5ae602Eric Laurent samplingRate, 49970c236c9290732782d5267935af1475b8d5ae602Eric Laurent format, 50070c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask, 5010977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent (audio_output_flags_t)flags); 50270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (module == 0) { 50370c236c9290732782d5267935af1475b8d5ae602Eric Laurent return 0; 50470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 505b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 506f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = device; 507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = samplingRate; 50870c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mFormat = (audio_format_t)format; 50970c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mChannelMask = (audio_channel_mask_t)channelMask; 510f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = 0; 5110977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent outputDesc->mFlags = (audio_output_flags_t)(flags | AudioSystem::OUTPUT_FLAG_DIRECT); 512f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 513f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mStopTime[stream] = 0; 51470c236c9290732782d5267935af1475b8d5ae602Eric Laurent output = mpClientInterface->openOutput(module, 51570c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 516f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 51870c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 519f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 520f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 521f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5229f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi // only accept an output with the requested parameters 523f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == 0 || 524f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || 525f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != 0 && format != outputDesc->mFormat) || 52670c236c9290732782d5267935af1475b8d5ae602Eric Laurent (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { 52770c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getOutput() failed opening direct output: samplingRate %d," 52870c236c9290732782d5267935af1475b8d5ae602Eric Laurent "format %d, channelMask %d", samplingRate, format, channelMask); 529f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output != 0) { 530f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 531f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 532f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete outputDesc; 533f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 534f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 535f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(output, outputDesc); 536f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 537f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 538f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5399f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi // ignoring channel mask due to downmix capability in mixer 5409f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi 541f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a non direct output 542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // get which output is suitable for the specified stream. The actual routing change will happen 544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when startOutput() will be called 545b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device); 546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent output = selectOutput(outputs, flags); 548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 54970c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d," 55070c236c9290732782d5267935af1475b8d5ae602Eric Laurent "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); 551f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("getOutput() returns output %d", output); 5535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 554f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 555f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::selectOutput(const SortedVector<audio_io_handle_t>& outputs, 5585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioSystem::output_flags flags) 5595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 5605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // select one output among several that provide a path to a particular device or set of 5615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // devices (the list was previously build by getOutputsForDevice()). 5625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // The priority is as follows: 5635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 1: the output with the highest number of requested policy flags 5645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 2: the primary output 5655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 3: the first output in the list 5665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 5675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputs.size() == 0) { 5685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 5695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 5705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputs.size() == 1) { 5715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputs[0]; 5725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 5735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 5745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent int maxCommonFlags = 0; 5755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t outputFlags = 0; 5765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t outputPrimary = 0; 5775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 5785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 5795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]); 5805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!outputDesc->isDuplicated()) { 5815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent int commonFlags = (int)AudioSystem::popCount(outputDesc->mProfile->mFlags & flags); 5825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (commonFlags > maxCommonFlags) { 5835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputFlags = outputs[i]; 5845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent maxCommonFlags = commonFlags; 5855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); 5865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 5870977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 5885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputPrimary = outputs[i]; 5895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 5905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 5915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 5925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 5935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputFlags != 0) { 5945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputFlags; 5955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 5965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputPrimary != 0) { 5975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputPrimary; 5985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 5995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputs[0]; 6015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 6025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 603f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, 604f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 605f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 6076a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 608f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 609f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 61064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startOutput() unknow output %d", output); 611f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 612f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 613f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // increment usage count for this stream on the requested output: 617f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE that the usage count is the same for duplicated output and hardware output which is 6185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // necessary for a correct control of hardware output routing by startOutput() and stopOutput() 619f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, 1); 620f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->mRefCount[stream] == 1) { 6225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t prevDevice = outputDesc->device(); 6235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 624b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent routing_strategy strategy = getStrategy(stream); 625b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent bool shouldWait = (strategy == STRATEGY_SONIFICATION) || 626b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent (strategy == STRATEGY_SONIFICATION_RESPECTFUL); 627b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t waitMs = 0; 6285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool force = false; 6295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 6305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 631b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (desc != outputDesc) { 632b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // force a device change if any other output is managed by the same hw 633b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // module and has a current device selection that differs from selected device. 634b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // In this case, the audio HAL must receive the new device selection so that it can 635b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // change the device currently selected by the other active output. 636b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (outputDesc->sharesHwModuleWith(desc) && 6375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent desc->device() != newDevice) { 638b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent force = true; 639b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 640b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // wait for audio on other active outputs to be presented when starting 641b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // a notification so that audio focus effect can propagate. 642b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (shouldWait && (desc->refCount() != 0) && (waitMs < desc->latency())) { 643b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent waitMs = desc->latency(); 644b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 6455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 647b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); 648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // handle special case for sonification while in call 6505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isInCall()) { 6515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleIncallSonification(stream, true, false); 6525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 653c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 6545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // apply volume rules for current stream and device if necessary 6555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent checkAndSetVolume(stream, 6565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mStreams[stream].getVolumeIndex((audio_devices_t)newDevice), 6575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent output, 6585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice); 65912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 6605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // update the outputs if starting an output with a stream that can affect notification 6615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // routing 6625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleNotificationRoutingForStream(stream); 663b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (waitMs > muteWaitMs) { 664b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent usleep((waitMs - muteWaitMs) * 2 * 1000); 665b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 6665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 667f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 668f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 669f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 671f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, 672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 673f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 674f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 6756a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 676f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 67864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() unknow output %d", output); 679f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 680f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 681f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 682f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 683f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 684f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle special case for sonification while in call 685f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 686f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, false); 687f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 688f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 689f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream] > 0) { 690f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // decrement usage count of this stream on the output 691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, -1); 692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store time at which the stream was stopped - see isStreamActive() 6935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->mRefCount[stream] == 0) { 6945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStopTime[stream] = systemTime(); 6955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 6965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // delay the device switch by twice the latency because stopOutput() is executed when 6975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // the track stop() command is received and at that time the audio track buffer can 6985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // still contain data that needs to be drained. The latency only covers the audio HAL 6995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // and kernel buffers. Also the latency does not always include additional delay in the 7005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // audio path (audio DSP, CODEC ...) 7015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); 7025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 7035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // force restoring the device selection on other active outputs if it differs from the 7045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // one being selected for this output 7055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 7065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(i); 7075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 7085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (curOutput != output && 7095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent desc->refCount() != 0 && 7105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->sharesHwModuleWith(desc) && 7115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice != desc->device()) { 7125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(curOutput, 7135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent getNewDevice(curOutput, false /*fromCache*/), 7145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent true, 7155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mLatency*2); 7165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // update the outputs if stopping one with a stream that can affect notification routing 7195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleNotificationRoutingForStream(stream); 720f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 722f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 72364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() refcount is already 0 for output %d", output); 724f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 725f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 726f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 727f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 728f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output) 729f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7306a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseOutput() %d", output); 731f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 732f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 73364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseOutput() releasing unknown output %d", output); 734f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 735f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 736f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 737f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 738f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int testIndex = testOutputIndex(output); 739f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (testIndex != 0) { 740f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 741f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->refCount() == 0) { 742f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 743f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(index); 744f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(output); 745f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[testIndex] = 0; 746f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 747f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 748f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 749f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 750f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 751f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) { 752f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 753f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(index); 754f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(output); 755f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 75612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource, 760f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 761f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 76270c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::audio_in_acoustics acoustics) 764f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t input = 0; 766f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device = getDeviceForInputSource(inputSource); 767f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 76870c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x", 76970c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputSource, samplingRate, format, channelMask, acoustics); 770f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 7725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW("getInput() could not find device for inputSource %d", inputSource); 773f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 774f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 775f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 776f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // adapt channel selection to input source 777f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(inputSource) { 778f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 77970c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = AudioSystem::CHANNEL_IN_VOICE_UPLINK; 780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 78270c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = AudioSystem::CHANNEL_IN_VOICE_DNLINK; 783f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 784f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 78570c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK); 786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 788f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 789f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 790f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = getInputProfile(device, 7925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent samplingRate, 7935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent format, 79470c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask); 7955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (profile == NULL) { 7965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d," 79770c236c9290732782d5267935af1475b8d5ae602Eric Laurent "channelMask %04x", 79870c236c9290732782d5267935af1475b8d5ae602Eric Laurent device, samplingRate, format, channelMask); 79970c236c9290732782d5267935af1475b8d5ae602Eric Laurent return 0; 80070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 80170c236c9290732782d5267935af1475b8d5ae602Eric Laurent 80270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (profile->mModule->mHandle == 0) { 80370c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGE("checkOutputForDevice(): could not open HW module %s", 80470c236c9290732782d5267935af1475b8d5ae602Eric Laurent profile->mModule->mName); 8055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 8065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 8075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 8085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile); 809f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mInputSource = inputSource; 811f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = device; 812f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mSamplingRate = samplingRate; 81370c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputDesc->mFormat = (audio_format_t)format; 81470c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputDesc->mChannelMask = (audio_channel_mask_t)channelMask; 815f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 81670c236c9290732782d5267935af1475b8d5ae602Eric Laurent input = mpClientInterface->openInput(profile->mModule->mHandle, 81770c236c9290732782d5267935af1475b8d5ae602Eric Laurent &inputDesc->mDevice, 818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mSamplingRate, 819f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mFormat, 82070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &inputDesc->mChannelMask); 821f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 822f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // only accept input with the exact requested set of parameters 823f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input == 0 || 824f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != inputDesc->mSamplingRate) || 825f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != inputDesc->mFormat) || 82670c236c9290732782d5267935af1475b8d5ae602Eric Laurent (channelMask != inputDesc->mChannelMask)) { 82770c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getInput() failed opening input: samplingRate %d, format %d, channelMask %d", 82870c236c9290732782d5267935af1475b8d5ae602Eric Laurent samplingRate, format, channelMask); 829f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input != 0) { 830f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 831f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 832f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete inputDesc; 833f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 834f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 835f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.add(input, inputDesc); 836f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return input; 837f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 838f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 839f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startInput(audio_io_handle_t input) 840f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8416a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startInput() input %d", input); 842f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 843f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 84464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startInput() unknow input %d", input); 845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 847f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 850f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestInput == 0) 851f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 852f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 853f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // refuse 2 active AudioRecord clients at the same time 854f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getActiveInput() != 0) { 85564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startInput() input %d failed: other input already started", input); 856f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 857f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 858f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 859f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 860f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 861f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice); 862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 863f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource); 8646a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 865f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 866f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 867f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 868f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 1; 869f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 870f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 871f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 872f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopInput(audio_io_handle_t input) 873f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8746a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopInput() input %d", input); 875f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 876f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 87764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() unknow input %d", input); 878f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 879f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 880f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 881f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 882f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (inputDesc->mRefCount == 0) { 88364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() input %d already stopped", input); 884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 885f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 886f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 887f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), 0); 888f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 889f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 890f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 891f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 892f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 893f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 894f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseInput(audio_io_handle_t input) 895f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8966a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() %d", input); 897f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 898f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 89964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseInput() releasing unknown input %d", input); 900f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 901f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 902f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 903f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(index); 904f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.removeItem(input); 9056a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() exit"); 906f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream, 909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMin, 910f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMax) 911f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 9126a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 913f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (indexMin < 0 || indexMin >= indexMax) { 91464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 915f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 916f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 917f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMin = indexMin; 918f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMax = indexMax; 919f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 920f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 921c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, 922c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 923c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 924f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 925f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 926f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 928f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 929c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 930c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 931c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 932f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force max volume if stream cannot be muted 934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 936b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", 937c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent stream, device, index); 938c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 939c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 940c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // clear all device specific values 941c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 942c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.clear(); 943c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 944c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 945f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 946f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // compute and apply stream volume on all outputs according to connected device 947f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin status_t status = NO_ERROR; 948f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 949c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent audio_devices_t curDevice = 950c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent getDeviceForVolume((audio_devices_t)mOutputs.valueAt(i)->device()); 951c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent if (device == curDevice) { 952c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); 953c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent if (volStatus != NO_ERROR) { 954c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status = volStatus; 955c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent } 956f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 957f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 958f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return status; 959f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 960f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 961c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, 962c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int *index, 963c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 964f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 965c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (index == NULL) { 966f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 967f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 968c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 969c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 970c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 971c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 972c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // the strategy the stream belongs to. 973c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 9745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = (audio_devices_t)getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); 975c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 976c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = getDeviceForVolume(device); 977c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 978c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 979c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 980f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 981f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 982f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(effect_descriptor_t *desc) 984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 9856a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutputForEffect()"); 986f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // apply simple rule where global effects are attached to the same output as MUSIC streams 987f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return getOutput(AudioSystem::MUSIC); 988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 989f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 990f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::registerEffect(effect_descriptor_t *desc, 9911c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent audio_io_handle_t io, 992f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t strategy, 993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session, 994f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int id) 995f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 9961c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 9981c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent index = mInputs.indexOfKey(io); 9991c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent if (index < 0) { 100064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() unknown io %d", io); 10011c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent return INVALID_OPERATION; 10021c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent } 1003f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1004f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1005f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 100664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 1007f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin desc->name, desc->memoryUsage); 1008f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1009f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1010f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory += desc->memoryUsage; 10116a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 10121c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent desc->name, io, strategy, session, id); 10136a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 1014f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1015f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = new EffectDescriptor(); 1016f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t)); 10171c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent pDesc->mIo = io; 1018f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mStrategy = (routing_strategy)strategy; 1019f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mSession = session; 1020582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = false; 1021582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1022f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.add(id, pDesc); 1023f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1024f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1025f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1026f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1027f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::unregisterEffect(int id) 1028f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1029f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mEffects.indexOfKey(id); 1030f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 103164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 1032f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1033f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1034f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1035f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = mEffects.valueAt(index); 1036f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1037582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent setEffectEnabled(pDesc, false); 1038582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1039f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) { 104064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() memory %d too big for total %d", 1041f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1042f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage = mTotalEffectsMemory; 1043f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1044f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory -= pDesc->mDesc.memoryUsage; 10456a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 1046582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1047f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1048f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.removeItem(id); 1049f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete pDesc; 1050f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1051f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1052f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1053f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1054582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(int id, bool enabled) 1055582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 1056582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1057582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (index < 0) { 105864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 1059582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1060582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1061582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1062582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 1063582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 1064582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1065582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(EffectDescriptor *pDesc, bool enabled) 1066582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 1067582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled == pDesc->mEnabled) { 10686a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(%s) effect already %s", 1069582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 1070582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1071582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1072582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1073582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled) { 1074582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 107564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 1076582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10); 1077582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1078582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1079582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad; 10806a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 1081582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } else { 1082582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) { 108364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 1084582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 1085582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 1086582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1087582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad; 10886a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 1089582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1090582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = enabled; 1091582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return NO_ERROR; 1092582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 1093582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const 1095f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1096f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin nsecs_t sysTime = systemTime(); 1097f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1098f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueAt(i)->mRefCount[stream] != 0 || 1099f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ns2ms(sysTime - mOutputs.valueAt(i)->mStopTime[stream]) < inPastMs) { 1100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return true; 1101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1103f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1104f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1105f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1106f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1107f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::dump(int fd) 1108f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1109f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1110f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1111f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 1112f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 1114f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1115b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 111670c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput); 1117f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1118f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string()); 1119f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1120f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string()); 1121f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1122599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " USB audio ALSA %s\n", mUsbCardAndDevice.string()); 1123599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent result.append(buffer); 1124f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices); 1125f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1126f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices); 1127f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1128f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 1129f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1130f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]); 1131f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1132f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]); 1133f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1134f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]); 1135f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]); 1137f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1138f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 1139f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 11405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 114170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 11425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, buffer, strlen(buffer)); 114370c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 114470c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, "- HW Module %d:\n", i + 1); 11455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, buffer, strlen(buffer)); 114670c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules[i]->dump(fd); 11475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 11485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 1149f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nOutputs dump:\n"); 1150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 1153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueAt(i)->dump(fd); 1155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nInputs dump:\n"); 1158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 1161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.valueAt(i)->dump(fd); 1163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nStreams dump:\n"); 1166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1167c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, 1168c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 1169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 1171c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, " %02d ", i); 1172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1173c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[i].dump(fd); 1174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 1177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 1178f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1179f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1180f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "Registered effects:\n"); 1181f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1182f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mEffects.size(); i++) { 1183f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 1184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.valueAt(i)->dump(fd); 1186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyManagerBase 1194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1196f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface) 1197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin : 1198f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Thread(false), 1200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 120170c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput((audio_io_handle_t)0), 1202f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices((audio_devices_t)0), 1203ca0657a1ca087a6d474a75fcfedd6aac3901d587Glenn Kasten mPhoneState(AudioSystem::MODE_NORMAL), 1204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 1205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 1206599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mA2dpSuspended(false), mHasA2dp(false), mHasUsb(false) 1207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface = clientInterface; 1209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) { 1211f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[i] = AudioSystem::FORCE_NONE; 1212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin initializeVolumeCurves(); 1215f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpDeviceAddress = String8(""); 1217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mScoDeviceAddress = String8(""); 1218599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mUsbCardAndDevice = String8(""); 1219f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 12205ec145df7708564d385fd3fb764085321cf4c253Dima Zavin if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { 12215ec145df7708564d385fd3fb764085321cf4c253Dima Zavin if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { 1222739022f26a7127ba76a98dda65411496086114a7Dima Zavin ALOGE("could not load audio policy configuration file, setting defaults"); 1223739022f26a7127ba76a98dda65411496086114a7Dima Zavin defaultAudioPolicyConfig(); 12245ec145df7708564d385fd3fb764085321cf4c253Dima Zavin } 12255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 12265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 1227b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // open all output streams needed to access attached devices 122870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 122970c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 123070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 123170c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGW("could not open HW module %s", mHwModules[i]->mName); 123270c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 123370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 123470c236c9290732782d5267935af1475b8d5ae602Eric Laurent // open all output streams needed to access attached devices 123570c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 123670c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 123770c236c9290732782d5267935af1475b8d5ae602Eric Laurent const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j]; 123870c236c9290732782d5267935af1475b8d5ae602Eric Laurent 123970c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (outProfile->mSupportedDevices & mAttachedOutputDevices) { 124070c236c9290732782d5267935af1475b8d5ae602Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile); 124170c236c9290732782d5267935af1475b8d5ae602Eric Laurent 124270c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice & 124370c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mSupportedDevices); 124470c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mSamplingRate = outProfile->mSamplingRates[0]; 124570c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mFormat = outProfile->mFormats[0]; 124670c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mChannelMask = outProfile->mChannelMasks[0]; 124770c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mFlags = outProfile->mFlags; 124870c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput( 124970c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mModule->mHandle, 125070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 125170c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mSamplingRate, 125270c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mFormat, 125370c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 125470c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mLatency, 125570c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mFlags); 125670c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (output == 0) { 125770c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete outputDesc; 125870c236c9290732782d5267935af1475b8d5ae602Eric Laurent } else { 125970c236c9290732782d5267935af1475b8d5ae602Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | 126070c236c9290732782d5267935af1475b8d5ae602Eric Laurent (outProfile->mSupportedDevices & mAttachedOutputDevices)); 126170c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mPrimaryOutput == 0 && 12620977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 126370c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput = output; 126470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 126570c236c9290732782d5267935af1475b8d5ae602Eric Laurent addOutput(output, outputDesc); 126670c236c9290732782d5267935af1475b8d5ae602Eric Laurent setOutputDevice(output, 126770c236c9290732782d5267935af1475b8d5ae602Eric Laurent (audio_devices_t)(mDefaultOutputDevice & 126870c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mSupportedDevices), 126970c236c9290732782d5267935af1475b8d5ae602Eric Laurent true); 1270b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1271b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1272b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1274f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 12755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE_IF((mAttachedOutputDevices & ~mAvailableOutputDevices), 1276b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent "Not output found for attached devices %08x", 12775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (mAttachedOutputDevices & ~mAvailableOutputDevices)); 1278b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1279b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 1280b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 1282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1283b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput != 0) { 1284f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1286b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER; 1289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = 44100; 1290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = AudioSystem::PCM_16_BIT; 1291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = AudioSystem::CHANNEL_OUT_STEREO; 1292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestLatencyMs = 0; 1293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = 0; 1294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1295f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[i] = 0; 1297f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 1302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin run(buffer, ANDROID_PRIORITY_AUDIO); 1303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::~AudioPolicyManagerBase() 1308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin exit(); 1311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(mOutputs.keyAt(i)); 1314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(i); 1315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(mInputs.keyAt(i)); 1318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(i); 1319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 132070c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 132170c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mHwModules[i]; 13225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 1323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::initCheck() 1326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1327b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; 1328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::threadLoop() 1332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 13336a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("entering threadLoop()"); 1334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin while (!exitPending()) 1335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 command; 1337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int valueInt; 1338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 value; 1339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Mutex::Autolock _l(mLock); 1341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 1342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 1344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(command); 1345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 1347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin valueInt != 0) { 13486a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("Test command %s received", command.string()); 1349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 target; 1350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("target"), target) != NO_ERROR) { 1351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin target = "Manager"; 1352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1353f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 1354f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_output")); 1355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = valueInt; 1356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 1358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_direct")); 1359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "false") { 1360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1361f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "true") { 1362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = true; 1363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1364f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 1366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_input")); 1367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestInput = valueInt; 1368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1370f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 1371f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_format")); 1372f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int format = AudioSystem::INVALID_FORMAT; 1373f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "PCM 16 bits") { 1374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_16_BIT; 1375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "PCM 8 bits") { 1376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_8_BIT; 1377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Compressed MP3") { 1378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::MP3; 1379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (format != AudioSystem::INVALID_FORMAT) { 1381f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1382f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = format; 1383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("format"), format); 1386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 1391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_channels")); 1392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int channels = 0; 1393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "Channels Stereo") { 1395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_STEREO; 1396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Channels Mono") { 1397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_MONO; 1398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (channels != 0) { 1400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = channels; 1402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("channels"), channels); 1405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 1410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_sampleRate")); 1411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (valueInt >= 0 && valueInt <= 96000) { 1412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int samplingRate = valueInt; 1413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = samplingRate; 1415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("sampling_rate"), samplingRate); 1418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 1424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_reopen")); 1425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 142670c236c9290732782d5267935af1475b8d5ae602Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 1427b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(mPrimaryOutput); 142870c236c9290732782d5267935af1475b8d5ae602Eric Laurent 142970c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; 143070c236c9290732782d5267935af1475b8d5ae602Eric Laurent 1431b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(mPrimaryOutput); 1432b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(mPrimaryOutput); 1433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1434b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 1435f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER; 143670c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput = mpClientInterface->openOutput(moduleHandle, 143770c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 1438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 1439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 144070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 1441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 1442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 1443b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput == 0) { 14445efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d", 144570c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); 1446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1449b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1450b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent addOutput(mPrimaryOutput, outputDesc); 1451f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1452f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1453f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1454f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1455f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 1456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1461f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::exit() 1462f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1464f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AutoMutex _l(mLock); 1465f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExit(); 1466f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.signal(); 1467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExitAndWait(); 1469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1470f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinint AudioPolicyManagerBase::testOutputIndex(audio_io_handle_t output) 1472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == mTestOutputs[i]) return i; 1475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 1477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- 1481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc) 1483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mId = id; 1485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.add(id, outputDesc); 1486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1489b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::checkOutputForDevice( 1490f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 1491b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioSystem::device_connection_state state) 1492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1493b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t output = 0; 1494b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc; 1495b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1496b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // TODO handle multiple outputs supporting overlapping sets of devices. 1497b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1498b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (state == AudioSystem::DEVICE_STATE_AVAILABLE) { 1499b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // first check if one output already open can be routed to this device 1500b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1501b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 1502b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputDesc->mProfile && outputDesc->mProfile->mSupportedDevices & device) { 1503b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mOutputs.keyAt(i); 1504b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1505b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1506b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // then look for one available output that can be routed to this device 15075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const IOProfile *outProfile = NULL; 150870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 1509b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent { 151070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 151170c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 151270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 151370c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 151470c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 151570c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices & device) { 151670c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile = mHwModules[i]->mOutputProfiles[j]; 151770c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 151870c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 151970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 152070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (outProfile != NULL) { 1521b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent break; 1522b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1523b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 152470c236c9290732782d5267935af1475b8d5ae602Eric Laurent 15255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outProfile == NULL) { 152670c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGW("checkOutputForDevice(): No output available for device %04x", device); 152770c236c9290732782d5267935af1475b8d5ae602Eric Laurent return output; 152870c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 152970c236c9290732782d5267935af1475b8d5ae602Eric Laurent 153070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (outProfile->mModule->mHandle == 0) { 153170c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGE("checkOutputForDevice(): could not open HW module %s", 153270c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mModule->mName); 1533b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return output; 1534b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1535b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1536b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("opening output for device %08x", device); 15375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc = new AudioOutputDescriptor(outProfile); 1538b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc->mDevice = device; 153970c236c9290732782d5267935af1475b8d5ae602Eric Laurent output = mpClientInterface->openOutput(outProfile->mModule->mHandle, 154070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 1541b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &outputDesc->mSamplingRate, 1542b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &outputDesc->mFormat, 154370c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 1544b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &outputDesc->mLatency, 1545b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc->mFlags); 1546b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1547b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (output != 0) { 1548b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t duplicatedOutput = 0; 1549b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // add output descriptor 1550b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent addOutput(output, outputDesc); 1551b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // set initial stream volume for device 1552b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent applyStreamVolumes(output, device); 1553b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1554b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent //TODO: configure audio effect output stage here 1555b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1556b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // open a duplicating output thread for the new output and the primary output 1557b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent duplicatedOutput = mpClientInterface->openDuplicateOutput(output, mPrimaryOutput); 1558b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (duplicatedOutput != 0) { 1559f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // add duplicated output descriptor 1560b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL); 1561b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); 1562b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent dupOutputDesc->mOutput2 = mOutputs.valueFor(output); 1563f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mSamplingRate = outputDesc->mSamplingRate; 1564f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mFormat = outputDesc->mFormat; 156570c236c9290732782d5267935af1475b8d5ae602Eric Laurent dupOutputDesc->mChannelMask = outputDesc->mChannelMask; 1566f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mLatency = outputDesc->mLatency; 1567b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent addOutput(duplicatedOutput, dupOutputDesc); 1568b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent applyStreamVolumes(duplicatedOutput, device); 1569b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 1570b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGW("getOutput() could not open duplicated output for %d and %d", 1571b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mPrimaryOutput, output); 1572b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(output); 1573b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(output); 1574b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete outputDesc; 1575b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1576f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1577f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 15785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW("checkOutputForDevice() could not open output for device %x", device); 1579f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete outputDesc; 1580b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1581f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1582f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1583b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // we assume that one given device is supported by zero or one output 1584b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // check if one opened output is not needed any more after disconnecting one device 1585b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1586b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc = mOutputs.valueAt(i); 1587b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputDesc->mProfile && 1588b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent !(outputDesc->mProfile->mSupportedDevices & mAvailableOutputDevices)) { 1589b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent output = mOutputs.keyAt(i); 1590b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent break; 1591b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1592f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1593f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1594f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1595b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return output; 1596f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1597f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1598b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::closeOutput(audio_io_handle_t output) 1599f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1600b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput(%d)", output); 1601f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1602b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 1603b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputDesc == NULL) { 1604b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGW("closeOutput() unknown output %d", output); 1605b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1607f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1608b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // look for duplicated outputs connected to the output being removed. 1609b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1610b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i); 1611b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->isDuplicated() && 1612b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (dupOutputDesc->mOutput1 == outputDesc || 1613b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent dupOutputDesc->mOutput2 == outputDesc)) { 1614b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc2; 1615b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->mOutput1 == outputDesc) { 1616b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput2; 1617b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 1618b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput1; 1619b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1620b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // As all active tracks on duplicated output will be deleted, 1621b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // and as they were also referenced on the other output, the reference 1622b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // count for their stream type must be adjusted accordingly on 1623b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // the other output. 1624b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (int j = 0; j < (int)AudioSystem::NUM_STREAM_TYPES; j++) { 1625b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent int refCount = dupOutputDesc->mRefCount[j]; 1626b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2->changeRefCount((AudioSystem::stream_type)j,-refCount); 1627b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1628b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i); 1629b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); 1630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1631b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(duplicatedOutput); 1632b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(duplicatedOutput); 1633b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(duplicatedOutput); 1634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1635f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1636b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1637b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioParameter param; 1638b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent param.add(String8("closing"), String8("true")); 1639b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(output, param.toString()); 1640b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1641b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(output); 1642b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(output); 1643b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(output); 1644f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1645f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1646f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManagerBase::getOutputsForDevice(audio_devices_t device) 1647f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1648b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t> outputs; 1649f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1650b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("getOutputsForDevice() device %04x", device); 1651b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 165212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ALOGV("output %d isDuplicated=%d device=%04x", 165312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi i, mOutputs.valueAt(i)->isDuplicated(), mOutputs.valueAt(i)->supportedDevices()); 1654b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if ((device & mOutputs.valueAt(i)->supportedDevices()) == device) { 1655b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("getOutputsForDevice() found output %d", mOutputs.keyAt(i)); 1656b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputs.add(mOutputs.keyAt(i)); 1657f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1658f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1659b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return outputs; 1660f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1662b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentbool AudioPolicyManagerBase::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, 1663b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t>& outputs2) 1664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1665b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1.size() != outputs2.size()) { 1666b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 1667f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1668b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < outputs1.size(); i++) { 1669b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1[i] != outputs2[i]) { 1670b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 1671f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1673b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return true; 1674b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 1675b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1676b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy) 1677b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 167801e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); 167901e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); 168001e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice); 168101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice); 1682b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1683b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!vectorsEqual(srcOutputs,dstOutputs)) { 1684b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", 1685b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent strategy, srcOutputs[0], dstOutputs[0]); 16865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // mute strategy while moving tracks from one output to another 16875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < srcOutputs.size(); i++) { 16885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setStrategyMute(strategy, true, srcOutputs[i]); 168901e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); 16905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 1691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Move effects associated to this strategy from previous output to new output 16935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent//FIXME: removing this code works for effects applied to a particular session as they will be 16945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// re-connected when the tracks are re-created after being invalidated. 16955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// However we need to define a policy for global effects when more than one output is possible 16965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// for (size_t i = 0; i < mEffects.size(); i++) { 16975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// EffectDescriptor *desc = mEffects.valueAt(i); 16985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// if (desc->mSession != AudioSystem::SESSION_OUTPUT_STAGE && 16995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// desc->mStrategy == strategy && 17005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// desc->mIo == srcOutputs[0]) { 17015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// ALOGV("checkOutputForStrategy() moving effect %d to output %d", 17025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// mEffects.keyAt(i), dstOutputs[0]); 17035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// mpClientInterface->moveEffects(desc->mSession, srcOutputs[0], dstOutputs[0]); 17045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// desc->mIo = dstOutputs[0]; 17055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// } 17065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// } 17075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // Move tracks associated to this strategy from previous output to new output 1708f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 1709f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)i) == strategy) { 171012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi //FIXME see fixme on name change 1711b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, dstOutputs[0]); 1712f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1713f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1715f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1716f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1717f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkOutputForAllStrategies() 1718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1719c16ac09f510437e8340be691720177a490ae78f0Eric Laurent checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 1720f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_PHONE); 1721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_SONIFICATION); 172212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 1723f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_MEDIA); 1724f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_DTMF); 1725f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1726f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1727b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::getA2dpOutput() 1728b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 17295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp) { 1730b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1731b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1732b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1733b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1734b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 1735b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 1736b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mOutputs.keyAt(i); 1737b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1738b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1739b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1740b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1741b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 1742b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1743f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkA2dpSuspend() 1744f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 17455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp) { 1746b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1747b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1748b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t a2dpOutput = getA2dpOutput(); 1749b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (a2dpOutput == 0) { 1750b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1751b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1752b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1753f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // suspend A2DP output if: 1754f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (NOT already suspended) && 1755f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is connected && 1756f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage for communication || for record is SCO))) || 1757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is ringing || in call) 1758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // restore A2DP output if: 1760f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (Already suspended) && 1761f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is NOT connected || 1762f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage NOT for communication && NOT for record is SCO))) && 1763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is NOT ringing && NOT in call) 1764f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpSuspended) { 1766f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress == "") || 1767f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) && 1768f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) && 1769f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState != AudioSystem::MODE_IN_CALL) && 1770f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState != AudioSystem::MODE_RINGTONE))) { 1771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1772b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->restoreOutput(a2dpOutput); 1773f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = false; 1774f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1775f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1776f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress != "") && 1777f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 1778f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) || 1779f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState == AudioSystem::MODE_IN_CALL) || 1780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState == AudioSystem::MODE_RINGTONE))) { 1781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1782b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->suspendOutput(a2dpOutput); 1783f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = true; 1784f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1785f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1788f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache) 1789f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1790f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device = (audio_devices_t)0; 1791f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1792f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 1793f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check the following by order of priority to request a routing change if necessary: 1794c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 1: the strategy enforced audible is active on the output: 1795c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // use device for strategy enforced audible 1796c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 2: we are in call or the strategy phone is active on the output: 1797f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy phone 1798c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 3: the strategy sonification is active on the output: 1799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy sonification 180012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 4: the strategy "respectful" sonification is active on the output: 180112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // use device for strategy "respectful" sonification 180212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 5: the strategy media is active on the output: 1803f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy media 180412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 6: the strategy DTMF is active on the output: 1805f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy DTMF 1806c16ac09f510437e8340be691720177a490ae78f0Eric Laurent if (outputDesc->isUsedByStrategy(STRATEGY_ENFORCED_AUDIBLE)) { 1807c16ac09f510437e8340be691720177a490ae78f0Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 1808c16ac09f510437e8340be691720177a490ae78f0Eric Laurent } else if (isInCall() || 1809c16ac09f510437e8340be691720177a490ae78f0Eric Laurent outputDesc->isUsedByStrategy(STRATEGY_PHONE)) { 1810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 1811f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) { 1812f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 181312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION_RESPECTFUL)) { 18145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); 1815f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) { 1816f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 1817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) { 1818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 1819f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1820f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 18216a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getNewDevice() selected device %x", device); 1822f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return device; 1823f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1824f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1825f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getStrategyForStream(AudioSystem::stream_type stream) { 1826f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return (uint32_t)getStrategy(stream); 1827f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1828f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1829f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDevicesForStream(AudioSystem::stream_type stream) { 1830f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t devices; 1831f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // By checking the range of stream before calling getStrategy, we avoid 18325efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 1833f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and then return STRATEGY_MEDIA, but we want to return the empty set. 1834f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream < (AudioSystem::stream_type) 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 1835f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent devices = (audio_devices_t)0; 1836f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1837f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioPolicyManagerBase::routing_strategy strategy = getStrategy(stream); 18385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devices = getDeviceForStrategy(strategy, true /*fromCache*/); 1839f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1840f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return devices; 1841f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1842f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1843f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy( 1844f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream) { 1845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // stream to strategy mapping 1846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (stream) { 1847f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::VOICE_CALL: 1848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::BLUETOOTH_SCO: 1849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_PHONE; 1850f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::RING: 1851f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::ALARM: 1852f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_SONIFICATION; 185312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::NOTIFICATION: 185412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi return STRATEGY_SONIFICATION_RESPECTFUL; 1855f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DTMF: 1856f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_DTMF; 1857f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 18585efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("unknown stream type"); 1859f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::SYSTEM: 1860f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 1861f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // while key clicks are played produces a poor result 1862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::TTS: 1863f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::MUSIC: 1864f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_MEDIA; 1865c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case AudioSystem::ENFORCED_AUDIBLE: 1866c16ac09f510437e8340be691720177a490ae78f0Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 1867f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1868f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1869f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 187012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivivoid AudioPolicyManagerBase::handleNotificationRoutingForStream(AudioSystem::stream_type stream) { 187112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi switch(stream) { 187212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::MUSIC: 187312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 187412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi updateDeviceForStrategy(); 187512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 187612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi default: 187712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 187812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 187912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi} 188012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 18815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, 18825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool fromCache) 1883f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device = 0; 1885f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1886f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (fromCache) { 18875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("getDeviceForStrategy() from cache strategy %d, device %x", 18885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent strategy, mDeviceForStrategy[strategy]); 1889f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mDeviceForStrategy[strategy]; 1890f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1891f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1892f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (strategy) { 189312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 189412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case STRATEGY_SONIFICATION_RESPECTFUL: 189512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if (isInCall()) { 18965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 189712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 189812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // while media is playing (or has recently played), use the same device 18995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 190012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else { 190112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // when media is not playing anymore, fall back on the sonification behavior 19025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 190312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 190412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 190512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 190612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 1907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_DTMF: 1908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall()) { 1909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when off call, DTMF strategy follows the same rules as MEDIA strategy 19105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 1911f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1912f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1913f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when in call, DTMF and PHONE strategies follow the same rules 1914f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 1915f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1916f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_PHONE: 1917f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // for phone strategy, we first consider the forced use and then the available devices by order 1918f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // of priority 1919f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { 1920f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_BT_SCO: 1921f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall() || strategy != STRATEGY_DTMF) { 1922f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 1923f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1924f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1925f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 1926f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO; 1928f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1929f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if SCO device is requested but no SCO device is available, fall back to default case 1930f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 1931f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1932f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: // FORCE_NONE 1933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE; 1934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; 1936f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1937f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 19385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mHasA2dp && !isInCall() && !mA2dpSuspended) { 1939f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; 1940f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 1942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1943f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1944599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 1945599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device) break; 1946599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 1947599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device) break; 1948f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 1949f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 195055ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 195155ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent if (device) break; 1952f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 1953f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1954f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE; 19555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 19565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 1957f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 19585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); 1959f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1960f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1961f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1962f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_SPEAKER: 1963f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 1964f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // A2DP speaker when forcing to speaker output 19655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mHasA2dp && !isInCall() && !mA2dpSuspended) { 1966f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 1967f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1968f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1969599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 1970599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device) break; 1971599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 1972599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device) break; 1973f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 1974f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 197555ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 197655ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent if (device) break; 1977f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 1978f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1979f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 19805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 19815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 1982f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 19835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); 1984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1985f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1986f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1987f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1989f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_SONIFICATION: 1990f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 1992f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handleIncallSonification(). 1993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 19945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); 1995f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1996f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1997c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // FALL THROUGH 1998c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 1999c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 2000c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 2001ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // except: 2002ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // - when in call where it doesn't default to STRATEGY_PHONE behavior 2003ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // - in countries where not enforced in which case it follows STRATEGY_MEDIA 2004c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 2005ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent if (strategy == STRATEGY_SONIFICATION || 2006ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent !mStreams[AUDIO_STREAM_ENFORCED_AUDIBLE].mCanBeMuted) { 2007ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 2008ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent if (device == 0) { 2009ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); 2010ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent } 2011f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2012f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // The second device used for sonification is the same as the device used by media strategy 2013f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2014f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2015f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_MEDIA: { 2016f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE; 2017f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 2018f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; 2019f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 20205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mHasA2dp && (getA2dpOutput() != 0) && !mA2dpSuspended) { 2021f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 2022f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; 2023f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2024f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 2025f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2026f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2027f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 2028f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2029f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2030f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2031f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 2032599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2033599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 2034599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device2 == 0) { 2035599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2036599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 2037599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device2 == 0) { 203855ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 2039f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2040f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 204155ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 2042f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2043f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 2044f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 2045f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2046f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 2047f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 2048f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2049f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2050c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 2051c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, 0 otherwise 2052f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device |= device2; 20535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 20545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2055f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 20565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); 2057f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2058f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 2059f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2060f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 206164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 2062f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2063f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2064f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 20656a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 2066f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)device; 2067f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2068f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2069f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::updateDeviceForStrategy() 2070f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2071f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_STRATEGIES; i++) { 20725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 20735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 20745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 20755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2076b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurentuint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc, 20779029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent audio_devices_t prevDevice, 20785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t delayMs) 20795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 20809029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // mute/unmute strategies using an incompatible device combination 20819029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // if muting, wait for the audio in pcm buffer to be drained before proceeding 20829029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // if unmuting, unmute only after the specified delay 20835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->isDuplicated()) { 2084b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return 0; 20855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 20865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 20875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t muteWaitMs = 0; 20885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t device = outputDesc->device(); 20895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool shouldMute = (outputDesc->refCount() != 0) && 20905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (AudioSystem::popCount(device) >= 2); 20919029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // temporary mute output if device selection changes to avoid volume bursts due to 20929029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // different per device volumes 20939029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent bool tempMute = (outputDesc->refCount() != 0) && (device != prevDevice); 20945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 20955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 20965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 20975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool mute = shouldMute && (curDevice & device) && (curDevice != device); 20985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool doMute = false; 20995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 21005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mute && !outputDesc->mStrategyMutedByDevice[i]) { 21015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent doMute = true; 21025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = true; 21035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){ 21045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent doMute = true; 21055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = false; 21065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 21079029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (doMute || tempMute) { 21085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t j = 0; j < mOutputs.size(); j++) { 21095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(j); 21105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if ((desc->supportedDevices() & outputDesc->supportedDevices()) == 0) { 21115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent continue; 21125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 21135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(j); 21145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", 21155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mute ? "muting" : "unmuting", i, curDevice, curOutput); 21165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); 21179029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (desc->strategyRefCount((routing_strategy)i) != 0) { 21189029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (tempMute) { 211901e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStrategyMute((routing_strategy)i, true, curOutput); 212001e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStrategyMute((routing_strategy)i, false, curOutput, 212101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent desc->latency() * 2, device); 21229029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent } 21239029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (tempMute || mute) { 21249029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (muteWaitMs < desc->latency()) { 21259029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent muteWaitMs = desc->latency(); 21269029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent } 21275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 21285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 21295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 21305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 21315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 21325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 21335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // FIXME: should not need to double latency if volume could be applied immediately by the 21345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // audioflinger mixer. We must account for the delay between now and the next time 21355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // the audioflinger thread for this output will process a buffer (which corresponds to 21365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // one buffer size, usually 1/2 or 1/4 of the latency). 21375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent muteWaitMs *= 2; 21385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // wait for the PCM output buffers to empty before proceeding with the rest of the command 21395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (muteWaitMs > delayMs) { 2140b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs -= delayMs; 2141b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent usleep(muteWaitMs * 1000); 2142b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2143f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2144b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return 0; 2145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2147b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurentuint32_t AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, 2148f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2149f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent bool force, 2150f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent int delayMs) 2151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 21525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); 2153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 21545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioParameter param; 2155b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t muteWaitMs = 0; 2156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->isDuplicated()) { 2158b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); 2159b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); 2160b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // filter devices according to output selected 2163f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices); 2164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 21655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t prevDevice = outputDesc->mDevice; 21665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 21675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() prevDevice %04x", prevDevice); 21685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 21695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device != 0) { 21705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mDevice = device; 21715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 21729029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); 21735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Do not change the routing if: 21755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // - the requested device is 0 2176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the requested device is the same as current device and force is not specified. 2177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Doing this check here allows the caller to call setOutputDevice() without conditions 2178f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((device == 0 || device == prevDevice) && !force) { 21795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); 2180b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2181f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2182f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 21835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() changing device"); 2184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do the routing 2185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)device); 21865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mpClientInterface->setParameters(output, param.toString(), delayMs); 21875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // update stream volumes according to new device 2189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin applyStreamVolumes(output, device, delayMs); 2190b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent 2191b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 21925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 2193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 21945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getInputProfile(audio_devices_t device, 21955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t samplingRate, 21965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t format, 21975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t channelMask) 21985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 21995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // Choose an input profile based on the requested capture parameters: select the first available 22005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // profile supporting all requested parameters. 22015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 220270c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 22035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent { 220470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 22055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent continue; 22065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 220770c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 22085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent { 220970c236c9290732782d5267935af1475b8d5ae602Eric Laurent IOProfile *profile = mHwModules[i]->mInputProfiles[j]; 221070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 22110977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent channelMask,(audio_output_flags_t)0)) { 221270c236c9290732782d5267935af1475b8d5ae602Eric Laurent return profile; 22135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 22145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2215f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 221670c236c9290732782d5267935af1475b8d5ae602Eric Laurent return NULL; 2217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2219f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) 2220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 22215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t device = 0; 2222f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(inputSource) { 2224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_DEFAULT: 2225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_MIC: 2226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_RECOGNITION: 2227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_COMMUNICATION: 2228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO && 2229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 2230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; 2231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 2232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_WIRED_HEADSET; 22335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_BUILTIN_MIC) { 2234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BUILTIN_MIC; 2235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_CAMCORDER: 22385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mAvailableInputDevices & AudioSystem::DEVICE_IN_BACK_MIC) { 2239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BACK_MIC; 22405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_BUILTIN_MIC) { 2241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BUILTIN_MIC; 2242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 2245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 2246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 22475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mAvailableInputDevices & AudioSystem::DEVICE_IN_VOICE_CALL) { 22485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = AudioSystem::DEVICE_IN_VOICE_CALL; 22495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 225264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 2253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 22556a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 2256f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)device; 2257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getActiveInput() 2260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 2262f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mInputs.valueAt(i)->mRefCount > 0) { 2263f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mInputs.keyAt(i); 2264f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2266f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 2267f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2269e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2270c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForVolume(audio_devices_t device) 2271e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2272e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent if (device == 0) { 2273e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // this happens when forcing a route update and no track is active on an output. 2274e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // In this case the returned category is not important. 2275c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 2276c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else if (AudioSystem::popCount(device) > 1) { 2277e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // Multiple device selection is either: 2278e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - speaker + one other device: give priority to speaker in this case. 2279e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 2280e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 2281e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // selection if not the speaker. 2282c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 2283c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 2284c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else { 2285c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 2286c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 2287e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 2288e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 228964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW_IF(AudioSystem::popCount(device) != 1, 2290c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 2291e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device); 2292e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2293c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return device; 2294c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 2295c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2296f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric LaurentAudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(audio_devices_t device) 2297c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 2298f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent switch(getDeviceForVolume(device)) { 2299e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 2300e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_EARPIECE; 2301e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 2302e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 2303e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 2304e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 2305e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 2306e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 2307e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_HEADSET; 2308e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 2309e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 2310e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 2311c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent case AUDIO_DEVICE_OUT_AUX_DIGITAL: 2312599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent case AUDIO_DEVICE_OUT_USB_ACCESSORY: 2313599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent case AUDIO_DEVICE_OUT_USB_DEVICE: 2314e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent default: 2315e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_SPEAKER; 2316e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 2317e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent} 2318e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2319f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentfloat AudioPolicyManagerBase::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, 2320e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int indexInUi) 2321e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2322e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device_category deviceCategory = getDeviceCategory(device); 2323e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 2324e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // the volume index in the UI is relative to the min and max volume indices for this stream type 2326e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 2327e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[VOLMIN].mIndex; 2328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 2329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (streamDesc.mIndexMax - streamDesc.mIndexMin); 2330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // find what part of the curve this index volume belongs to, or if it's out of bounds 2332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int segment = 0; 2333e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 2334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0.0f; 2335e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 2336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 0; 2337e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 2338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 1; 2339e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 2340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 2; 2341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { // out of bounds 2342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0f; 2343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // linear interpolation in the attenuation table in dB 2346e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent float decibels = curve[segment].mDBAttenuation + 2347e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 2348e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ( (curve[segment+1].mDBAttenuation - 2349e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation) / 2350e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(curve[segment+1].mIndex - 2351e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex)) ); 2352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2353f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 2354f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 23556a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 2356e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex, volIdx, 2357e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mIndex, 2358e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation, 2359cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent decibels, 2360e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mDBAttenuation, 2361f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin amplification); 2362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return amplification; 2364f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2366cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2367e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2368e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 2369e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2370e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2371e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2372e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2373e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 2374cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent}; 2375cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent 2376e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2377e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2378e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 2379e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2380e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2381e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2382e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2383e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 2384e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2385e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2386ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks 2387ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets (See AudioService.java). 23887465678e0d5711ebcd78ae47b3a76821534a23eaEric Laurent// The range is constrained between -30dB and -12dB over speaker and -30dB and -18dB over headset. 2389ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2390ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent AudioPolicyManagerBase::sDefaultSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 23917465678e0d5711ebcd78ae47b3a76821534a23eaEric Laurent {1, -30.0f}, {33, -24.0f}, {66, -18.0f}, {100, -12.0f} 2392ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent}; 2393ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent 2394ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2395ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent AudioPolicyManagerBase::sHeadsetSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 23967465678e0d5711ebcd78ae47b3a76821534a23eaEric Laurent {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f} 2397ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent}; 2398e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2399e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2400ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent *AudioPolicyManagerBase::sVolumeProfiles[AUDIO_STREAM_CNT] 2401e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent [AudioPolicyManagerBase::DEVICE_CATEGORY_CNT] = { 2402ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_VOICE_CALL 2403e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2404e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2405e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2406e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2407ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_SYSTEM 2408ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2409ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2410ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2411ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2412ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_RING 2413e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2414e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2415e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2416e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2417ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_MUSIC 2418ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 2419ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2420ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 2421ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2422ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_ALARM 242312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 242412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 242512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 242612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi }, 2427ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_NOTIFICATION 2428e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2429ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2430e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2431c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2432ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_BLUETOOTH_SCO 2433c16ac09f510437e8340be691720177a490ae78f0Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2434ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2435c16ac09f510437e8340be691720177a490ae78f0Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2436c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2437ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_ENFORCED_AUDIBLE 2438ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2439ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2440ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2441ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2442ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_DTMF 2443ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2444ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2445ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2446ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2447ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_TTS 2448ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 2449ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2450ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 2451ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2452e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2453e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2454e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentvoid AudioPolicyManagerBase::initializeVolumeCurves() 2455e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2456ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 2457e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 2458cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent mStreams[i].mVolumeCurve[j] = 2459ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sVolumeProfiles[i][j]; 2460cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2461cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2462f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2464c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentfloat AudioPolicyManagerBase::computeVolume(int stream, 2465c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2466c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2467f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device) 2468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = 1.0; 2470f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 2472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 2474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = outputDesc->device(); 2475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if volume is not 0 (not muted), force media volume to max on digital output 2478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::MUSIC && 2479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin index != mStreams[stream].mIndexMin && 2480f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent (device == AUDIO_DEVICE_OUT_AUX_DIGITAL || 2481599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET || 2482599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_USB_ACCESSORY || 2483599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_USB_DEVICE)) { 2484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0; 2485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = volIndexToAmpl(device, streamDesc, index); 2488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if a headset is connected, apply the following rules to ring tones and notifications 2490f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // to avoid sound level bursts in user's ears: 2491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - always attenuate ring tones and notifications volume by 6dB 2492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - if music is playing, always limit the volume to current music volume, 2493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // with a minimum threshold at -36dB so that notification is always perceived. 249412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 249512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if ((device & (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP | 249612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 249712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi AudioSystem::DEVICE_OUT_WIRED_HEADSET | 249812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) && 249912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION) 250012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) 250112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi || (stream == AudioSystem::SYSTEM)) && 2502f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin streamDesc.mCanBeMuted) { 2503f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 2504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when the phone is ringing we must consider that music could have been paused just before 2505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // by the music application and behave as if music was active if the last music track was 2506f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // just stopped 2507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[AudioSystem::MUSIC] || mLimitRingtoneVolume) { 2508c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float musicVol = computeVolume(AudioSystem::MUSIC, 2509f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mStreams[AudioSystem::MUSIC].getVolumeIndex(device), 2510c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2511f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent device); 2512c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 2513c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 2514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume > minVol) { 2515f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = minVol; 25166a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 2517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2518f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2519f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2520f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2521f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return volume; 2522f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2523f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2524c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::checkAndSetVolume(int stream, 2525c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2526c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2527f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2528c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 2529c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 2530f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2531f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2532f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change actual stream volume if the stream is muted 2533f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 25345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("checkAndSetVolume() stream %d muted count %d", 25355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent stream, mOutputs.valueFor(output)->mMuteCount[stream]); 2536f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2537f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2538f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2539f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change in call volume if bluetooth is connected and vice versa 2540f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 2541f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) { 25426a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 2543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, mForceUse[AudioSystem::FOR_COMMUNICATION]); 2544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 2545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2547f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = computeVolume(stream, index, output, device); 2548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // We actually change the volume if: 2549f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the float value returned by computeVolume() changed 2550f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the force flag is set 2551f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 2552f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force) { 2553f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueFor(output)->mCurVolume[stream] = volume; 25545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 2555f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL || 2556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::DTMF || 2557f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::BLUETOOTH_SCO) { 2558f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // offset value to reflect actual hardware volume that never reaches 0 2559f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java) 2560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = 0.01 + 0.99 * volume; 2561f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 2562f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // enabled 2563f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::BLUETOOTH_SCO) { 2564f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs); 2565f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2566f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2567f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2568f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); 2569f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2570f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2571f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL || 2572f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::BLUETOOTH_SCO) { 2573f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float voiceVolume; 2574f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force voice volume to max for bluetooth SCO as volume is managed by the headset 2575f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL) { 2576f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 2577f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2578f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = 1.0; 2579f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2580f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2581b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { 2582f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 2583f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLastVoiceVolume = voiceVolume; 2584f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2585f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2586f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2587f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2588f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2589f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2590c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, 2591f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2592c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 2593c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 2594f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 25956a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("applyStreamVolumes() for output %d and device %x", output, device); 2596f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2597f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 2598c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 2599f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mStreams[stream].getVolumeIndex(device), 2600c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2601c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 2602c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs, 2603c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent force); 2604f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2605f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 260701e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurentvoid AudioPolicyManagerBase::setStrategyMute(routing_strategy strategy, 260801e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent bool on, 260901e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_io_handle_t output, 261001e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent int delayMs, 261101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t device) 2612f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 26136a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 2614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 2615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)stream) == strategy) { 261601e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStreamMute(stream, on, output, delayMs, device); 2617f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2618f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2619f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2620f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 262101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurentvoid AudioPolicyManagerBase::setStreamMute(int stream, 262201e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent bool on, 262301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_io_handle_t output, 262401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent int delayMs, 262501e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t device) 2626f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2627f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 2628f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 262901e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent if (device == 0) { 263001e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent device = outputDesc->device(); 263101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent } 2632f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 263301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent ALOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x", 263401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent stream, on, output, outputDesc->mMuteCount[stream], device); 2635f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2636f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (on) { 2637f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 2638f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (streamDesc.mCanBeMuted) { 2639c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 2640f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2641f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2642f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 2643f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mMuteCount[stream]++; 2644f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2645f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 264664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setStreamMute() unmuting non muted stream!"); 2647f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 2648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2649f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (--outputDesc->mMuteCount[stream] == 0) { 2650c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 2651c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent streamDesc.getVolumeIndex((audio_devices_t)device), 2652c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2653c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 2654c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs); 2655f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2656f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2657f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2658f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2659f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, bool stateChange) 2660f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if the stream pertains to sonification strategy and we are in call we must 2662f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // mute the stream if it is low visibility. If it is high visibility, we must play a tone 2663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // in the device used for phone strategy and play the tone if the selected device does not 2664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // interfere with the device used for phone strategy 2665f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 2666f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // many times as there are active tracks on the output 266712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 266812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if ((stream_strategy == STRATEGY_SONIFICATION) || 266912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { 2670b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 26716a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 2672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, starting, outputDesc->mDevice, stateChange); 2673f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream]) { 2674f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int muteCount = 1; 2675f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stateChange) { 2676f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin muteCount = outputDesc->mRefCount[stream]; 2677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2678f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) { 26796a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 2680f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 2681b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 2682f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2683f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 26846a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility"); 26855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->device() & 26865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) { 26876a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 2688f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 2689b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 2690f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (starting) { 2693f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL); 2694f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2695f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->stopTone(); 2696f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2697f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2698f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2699f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2700f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2701f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2702f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isInCall() 2703f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2704f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return isStateInCall(mPhoneState); 2705f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2706f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2707f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStateInCall(int state) { 2708f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((state == AudioSystem::MODE_IN_CALL) || 2709f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (state == AudioSystem::MODE_IN_COMMUNICATION)); 2710f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2711f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 271270c236c9290732782d5267935af1475b8d5ae602Eric Laurentbool AudioPolicyManagerBase::needsDirectOuput(audio_stream_type_t stream, 271370c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 271470c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_format_t format, 271570c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_channel_mask_t channelMask, 27160977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags, 271770c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_devices_t device) 2718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2719f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) || 2720b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (format != 0 && !AudioSystem::isLinearPCM(format))); 2721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2722f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2723f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsCpuLoad() 2724f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2725f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_CPU_LOAD; 2726f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2727f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2728f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsMemory() 2729f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2730f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_MEMORY; 2731f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2732f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2733f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioOutputDescriptor class implementation 2734f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2735b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric LaurentAudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor( 27365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const IOProfile *profile) 273770c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mId(0), mSamplingRate(0), mFormat((audio_format_t)0), 273870c236c9290732782d5267935af1475b8d5ae602Eric Laurent mChannelMask((audio_channel_mask_t)0), mLatency(0), 27390977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent mFlags((audio_output_flags_t)0), mDevice((audio_devices_t)0), 2740f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mOutput1(0), mOutput2(0), mProfile(profile) 2741f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2742f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // clear usage count for all stream types 2743f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 2744f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[i] = 0; 2745f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurVolume[i] = -1.0; 2746f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mMuteCount[i] = 0; 2747f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStopTime[i] = 0; 2748f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2749f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2750f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2751f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::device() 2752f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2753f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 2754f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 2755f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2756f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return mDevice; 2757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 27605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::latency() 27615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 27625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isDuplicated()) { 27635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 27645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 27655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return mLatency; 27665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 27675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 27685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 27695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::sharesHwModuleWith( 27705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const AudioOutputDescriptor *outputDesc) 27715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 27725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isDuplicated()) { 27735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 27745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (outputDesc->isDuplicated()){ 27755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2); 27765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 277770c236c9290732782d5267935af1475b8d5ae602Eric Laurent return (mProfile->mModule == outputDesc->mProfile->mModule); 27785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 27795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 27805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta) 2782f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2783f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // forward usage count change to attached outputs 2784f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 2785f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput1->changeRefCount(stream, delta); 2786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput2->changeRefCount(stream, delta); 2787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2788f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((delta + (int)mRefCount[stream]) < 0) { 278964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]); 2790f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] = 0; 2791f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 2792f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2793f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] += delta; 27946a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 2795f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2796f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2797f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::refCount() 2798f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t refcount = 0; 2800f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 2801f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin refcount += mRefCount[i]; 2802f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2803f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return refcount; 2804f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2805f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2806f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::strategyRefCount(routing_strategy strategy) 2807f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2808f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t refCount = 0; 2809f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 2810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)i) == strategy) { 2811f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin refCount += mRefCount[i]; 2812f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2813f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2814f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return refCount; 2815f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2816f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2817f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::supportedDevices() 2818b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 2819b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (isDuplicated()) { 2820f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 2821b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 2822b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mProfile->mSupportedDevices ; 2823b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2824b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 2825b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2826f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd) 2827f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2828f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 2829f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 2830f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 2831f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2832f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 2833f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2834f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 2835f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 283670c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 2837f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2838f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 2839f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2840f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 2841f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2842f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", device()); 2843f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2844f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 2845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 2847f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 2848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2850f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 2851f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2852f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2853f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2854f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2855f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioInputDescriptor class implementation 2856f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 28575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor(const IOProfile *profile) 285870c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mSamplingRate(0), mFormat((audio_format_t)0), mChannelMask((audio_channel_mask_t)0), 285970c236c9290732782d5267935af1475b8d5ae602Eric Laurent mDevice((audio_devices_t)0), mRefCount(0), 28605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mInputSource(0), mProfile(profile) 2861f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2863f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2864f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd) 2865f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2866f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 2867f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 2868f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 2869f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2870f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 2871f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2872f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 2873f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 287470c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 2875f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2876f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 2877f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2878f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 2879f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2880f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 2881f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2882f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2883f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2885f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- StreamDescriptor class implementation 2886f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2887c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric LaurentAudioPolicyManagerBase::StreamDescriptor::StreamDescriptor() 2888c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 2889c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 2890c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 2891c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 2892c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2893c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentint AudioPolicyManagerBase::StreamDescriptor::getVolumeIndex(audio_devices_t device) 2894c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 2895c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AudioPolicyManagerBase::getDeviceForVolume(device); 2896c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 2897c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 2898c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 2899c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 2900c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return mIndexCur.valueFor(device); 2901c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 2902c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2903c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::StreamDescriptor::dump(int fd) 2904f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2905c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent const size_t SIZE = 256; 2906c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent char buffer[SIZE]; 2907c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent String8 result; 2908c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2909c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 2910c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 2911c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 2912c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 2913c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 2914c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.keyAt(i), 2915c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.valueAt(i)); 2916c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 2917c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 2918c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append("\n"); 2919c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2920c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent write(fd, result.string(), result.size()); 2921f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2922f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2923f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- EffectDescriptor class implementation 2924f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2925f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::EffectDescriptor::dump(int fd) 2926f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 2928f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 2929f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 2930f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 29311c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 2932f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 2934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Session: %d\n", mSession); 2936f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2937f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 2938f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2939582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 2940582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent result.append(buffer); 2941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 2942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2943f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2944f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2945f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 29465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// --- IOProfile class implementation 29475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 294870c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::HwModule::HwModule(const char *name) 294970c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0) 295070c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 295170c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 295270c236c9290732782d5267935af1475b8d5ae602Eric Laurent 295370c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::HwModule::~HwModule() 295470c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 295570c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 295670c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mOutputProfiles[i]; 295770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 295870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 295970c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mInputProfiles[i]; 296070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 296170c236c9290732782d5267935af1475b8d5ae602Eric Laurent free((void *)mName); 296270c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 296370c236c9290732782d5267935af1475b8d5ae602Eric Laurent 296470c236c9290732782d5267935af1475b8d5ae602Eric Laurentvoid AudioPolicyManagerBase::HwModule::dump(int fd) 296570c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 296670c236c9290732782d5267935af1475b8d5ae602Eric Laurent const size_t SIZE = 256; 296770c236c9290732782d5267935af1475b8d5ae602Eric Laurent char buffer[SIZE]; 296870c236c9290732782d5267935af1475b8d5ae602Eric Laurent String8 result; 296970c236c9290732782d5267935af1475b8d5ae602Eric Laurent 297070c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - name: %s\n", mName); 297170c236c9290732782d5267935af1475b8d5ae602Eric Laurent result.append(buffer); 297270c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 297370c236c9290732782d5267935af1475b8d5ae602Eric Laurent result.append(buffer); 297470c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, result.string(), result.size()); 297570c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mOutputProfiles.size()) { 297670c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, " - outputs:\n", sizeof(" - outputs:\n")); 297770c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 2978599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " output %d:\n", i); 2979599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent write(fd, buffer, strlen(buffer)); 298070c236c9290732782d5267935af1475b8d5ae602Eric Laurent mOutputProfiles[i]->dump(fd); 298170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 298270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 298370c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mInputProfiles.size()) { 298470c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, " - inputs:\n", sizeof(" - inputs:\n")); 298570c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 2986599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " input %d:\n", i); 2987599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent write(fd, buffer, strlen(buffer)); 298870c236c9290732782d5267935af1475b8d5ae602Eric Laurent mInputProfiles[i]->dump(fd); 298970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 299070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 299170c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 299270c236c9290732782d5267935af1475b8d5ae602Eric Laurent 299370c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::IOProfile::IOProfile(HwModule *module) 29940977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent : mFlags((audio_output_flags_t)0), mModule(module) 29955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 29965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 29975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 29985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::IOProfile::~IOProfile() 29995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 300070c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 300170c236c9290732782d5267935af1475b8d5ae602Eric Laurent 300270c236c9290732782d5267935af1475b8d5ae602Eric Laurent// checks if the IO profile is compatible with specified parameters. By convention a value of 0 300370c236c9290732782d5267935af1475b8d5ae602Eric Laurent// means a parameter is don't care 300470c236c9290732782d5267935af1475b8d5ae602Eric Laurentbool AudioPolicyManagerBase::IOProfile::isCompatibleProfile(audio_devices_t device, 300570c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 300670c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t format, 300770c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 30080977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags) const 300970c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 301070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if ((mSupportedDevices & device) != device) { 301170c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 301270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 301370c236c9290732782d5267935af1475b8d5ae602Eric Laurent if ((mFlags & flags) != flags) { 301470c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 301570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 301670c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (samplingRate != 0) { 301770c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 301870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mSamplingRates.size(); i++) 301970c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 302070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mSamplingRates[i] == samplingRate) { 302170c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 302270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 302370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 302470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mSamplingRates.size()) { 302570c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 302670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 302770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 302870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (format != 0) { 302970c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 303070c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mFormats.size(); i++) 303170c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 303270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mFormats[i] == format) { 303370c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 303470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 303570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 303670c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mFormats.size()) { 303770c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 303870c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 303970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 304070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (channelMask != 0) { 304170c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 304270c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mChannelMasks.size(); i++) 304370c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 304470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mChannelMasks[i] == channelMask) { 304570c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 304670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 304770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 304870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mChannelMasks.size()) { 304970c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 305070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 305170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 305270c236c9290732782d5267935af1475b8d5ae602Eric Laurent return true; 30535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 30545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 30555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::IOProfile::dump(int fd) 30565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 30575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const size_t SIZE = 256; 30585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char buffer[SIZE]; 30595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent String8 result; 30605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 306170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - sampling rates: "); 30625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 30635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 30645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent snprintf(buffer, SIZE, "%d", mSamplingRates[i]); 30655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 30665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mSamplingRates.size() - 1) ? "\n" : ", "); 30675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 30685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 306970c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - channel masks: "); 30705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 30715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 30725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent snprintf(buffer, SIZE, "%04x", mChannelMasks[i]); 30735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 30745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mChannelMasks.size() - 1) ? "\n" : ", "); 30755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 30765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 307770c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - formats: "); 30785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 30795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 30805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent snprintf(buffer, SIZE, "%d", mFormats[i]); 30815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 30825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mFormats.size() - 1) ? "\n" : ", "); 30835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 30845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 308570c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - devices: %04x\n", mSupportedDevices); 30865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 308770c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - flags: %04x\n", mFlags); 30885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 30895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 30905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, result.string(), result.size()); 30915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 30925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 30935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// --- audio_policy.conf file parsing 30945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 30955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentstruct StringToEnum { 30965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *name; 30975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t value; 30985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 30995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#define STRING_TO_ENUM(string) { #string, string } 31015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 31025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sDeviceNameToEnumTable[] = { 31045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE), 31055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER), 31065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET), 31075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE), 31085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO), 31095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP), 31105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL), 31115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET), 3112599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET), 3113599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE), 3114599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY), 3115599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB), 31165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), 31175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), 31185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET), 31195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL), 31205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL), 31215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC), 31225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 31235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sFlagNameToEnumTable[] = { 31250977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT), 31260977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), 3127b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), 3128b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), 31295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 31305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sFormatNameToEnumTable[] = { 31325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT), 31335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT), 31345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_MP3), 31355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AAC), 31365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_VORBIS), 31375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 31385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sOutChannelsNameToEnumTable[] = { 31405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO), 31415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 31425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 31435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 31445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 31455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sInChannelsNameToEnumTable[] = { 31475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), 31485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), 31495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 31505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentuint32_t AudioPolicyManagerBase::stringToEnum(const struct StringToEnum *table, 31535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent size_t size, 31545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *name) 31555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 31565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < size; i++) { 31575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(table[i].name, name) == 0) { 31585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("stringToEnum() found %s", table[i].name); 31595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return table[i].value; 31605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 31615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 31625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 31635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 31645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31650977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurentaudio_output_flags_t AudioPolicyManagerBase::parseFlagNames(char *name) 31665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 31675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t flag = 0; 31685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // it is OK to cast name to non const here as we are not going to use it after 31705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // strtok() modifies it 31715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *flagName = strtok(name, "|"); 31725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (flagName != NULL) { 31735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strlen(flagName) != 0) { 31745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flag |= stringToEnum(sFlagNameToEnumTable, 31755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sFlagNameToEnumTable), 31765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flagName); 31775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 31785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flagName = strtok(NULL, "|"); 31795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 31800977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent return (audio_output_flags_t)flag; 31815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 31825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_devices_t AudioPolicyManagerBase::parseDeviceNames(char *name) 31845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 31855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t device = 0; 31865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *devName = strtok(name, "|"); 31885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (devName != NULL) { 31895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strlen(devName) != 0) { 31905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device |= stringToEnum(sDeviceNameToEnumTable, 31915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 31925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devName); 31935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 31945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devName = strtok(NULL, "|"); 31955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 31965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return (audio_devices_t)device; 31975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 31985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadSamplingRates(char *name, IOProfile *profile) 32005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 32015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *str = strtok(name, "|"); 32025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 32045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t rate = atoi(str); 32055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (rate != 0) { 32065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadSamplingRates() adding rate %d", rate); 32075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSamplingRates.add(rate); 32085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 32105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 32125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 32135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadFormats(char *name, IOProfile *profile) 32155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 32165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *str = strtok(name, "|"); 32175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 32195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable, 32205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 32215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str); 32225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (format != 0) { 32235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mFormats.add(format); 32245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 32265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 32285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 32295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadInChannels(char *name, IOProfile *profile) 32315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 32325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *str = strtok(name, "|"); 32335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInChannels() %s", name); 32355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 32365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_channel_mask_t channelMask = 32375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 32385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 32395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str); 32405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (channelMask != 0) { 32415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInChannels() adding channelMask %04x", channelMask); 32425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mChannelMasks.add(channelMask); 32435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 32455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 32475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 32485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadOutChannels(char *name, IOProfile *profile) 32505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 32515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *str = strtok(name, "|"); 32525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_channel_mask_t channelMask; 32535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 32555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent channelMask = stringToEnum(sOutChannelsNameToEnumTable, 32565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 32575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str); 32585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (channelMask != 0) { 32595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mChannelMasks.add(channelMask); 32605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 32625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 32645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 32655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 326670c236c9290732782d5267935af1475b8d5ae602Eric Laurentstatus_t AudioPolicyManagerBase::loadInput(cnode *root, HwModule *module) 32675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 32685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = root->first_child; 32695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = new IOProfile(module); 32715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 32735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 32745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadSamplingRates((char *)node->value, profile); 32755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 32765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadFormats((char *)node->value, profile); 32775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 32785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadInChannels((char *)node->value, profile); 32795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 32805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices = parseDeviceNames((char *)node->value); 32815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 32835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSupportedDevices == (audio_devices_t)0, 32855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported devices"); 32865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 32875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported channel masks"); 32885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 32895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported sampling rates"); 32905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 32915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported formats"); 32925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if ((profile->mSupportedDevices != (audio_devices_t)0) && 32935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mChannelMasks.size() != 0) && 32945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mSamplingRates.size() != 0) && 32955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mFormats.size() != 0)) { 32965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInput() adding input mSupportedDevices %04x", profile->mSupportedDevices); 32985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 329970c236c9290732782d5267935af1475b8d5ae602Eric Laurent module->mInputProfiles.add(profile); 33005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 33015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 33025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent delete profile; 33035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return BAD_VALUE; 33045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 33065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 330770c236c9290732782d5267935af1475b8d5ae602Eric Laurentstatus_t AudioPolicyManagerBase::loadOutput(cnode *root, HwModule *module) 33085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 33095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = root->first_child; 33105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = new IOProfile(module); 33125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 33145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 33155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadSamplingRates((char *)node->value, profile); 33165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 33175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadFormats((char *)node->value, profile); 33185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 33195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadOutChannels((char *)node->value, profile); 33205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 33215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices = parseDeviceNames((char *)node->value); 33225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FLAGS_TAG) == 0) { 33235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mFlags = parseFlagNames((char *)node->value); 33245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 33265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSupportedDevices == (audio_devices_t)0, 33285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported devices"); 33295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 33305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported channel masks"); 33315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 33325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported sampling rates"); 33335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 33345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported formats"); 33355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if ((profile->mSupportedDevices != (audio_devices_t)0) && 33365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mChannelMasks.size() != 0) && 33375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mSamplingRates.size() != 0) && 33385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mFormats.size() != 0)) { 33395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadOutput() adding output mSupportedDevices %04x, mFlags %04x", 33415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices, profile->mFlags); 33425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 334370c236c9290732782d5267935af1475b8d5ae602Eric Laurent module->mOutputProfiles.add(profile); 33445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 33455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 33465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent delete profile; 33475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return BAD_VALUE; 33485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 33505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadHwModule(cnode *root) 33525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 33535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, OUTPUTS_TAG); 33545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status_t status = NAME_NOT_FOUND; 335570c236c9290732782d5267935af1475b8d5ae602Eric Laurent 335670c236c9290732782d5267935af1475b8d5ae602Eric Laurent HwModule *module = new HwModule(root->name); 335770c236c9290732782d5267935af1475b8d5ae602Eric Laurent 33585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node != NULL) { 33595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_A2DP) == 0) { 33605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mHasA2dp = true; 3361599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } else if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_USB) == 0) { 3362599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mHasUsb = true; 33635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 3364599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent 33655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 33665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 33675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModule() loading output %s", node->name); 336870c236c9290732782d5267935af1475b8d5ae602Eric Laurent status_t tmpStatus = loadOutput(node, module); 33695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 33705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status = tmpStatus; 33715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 33735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = config_find(root, INPUTS_TAG); 33765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node != NULL) { 33775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 33785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 33795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModule() loading input %s", node->name); 338070c236c9290732782d5267935af1475b8d5ae602Eric Laurent status_t tmpStatus = loadInput(node, module); 33815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 33825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status = tmpStatus; 33835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 33855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NO_ERROR) { 338870c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules.add(module); 338970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } else { 339070c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete module; 33915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 33935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadHwModules(cnode *root) 33955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 33965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); 33975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node == NULL) { 33985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 33995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 34025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 34035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModules() loading module %s", node->name); 34045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadHwModule(node); 34055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 34065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 34085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadGlobalConfig(cnode *root) 34105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 34115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, GLOBAL_CONFIG_TAG); 34125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node == NULL) { 34135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 34145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 34165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 34175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { 34185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAttachedOutputDevices = parseDeviceNames((char *)node->value); 34195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(mAttachedOutputDevices == 0, "loadGlobalConfig() no attached output devices"); 34205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mAttachedOutputDevices %04x", mAttachedOutputDevices); 34215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { 34225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mDefaultOutputDevice = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable, 34235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 34245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (char *)node->value); 34255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(mDefaultOutputDevice == 0, "loadGlobalConfig() default device not specified"); 34265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mDefaultOutputDevice %04x", mDefaultOutputDevice); 34275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { 34285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAvailableInputDevices = parseDeviceNames((char *)node->value); 34295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mAvailableInputDevices %04x", mAvailableInputDevices); 34305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 34325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 34345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentstatus_t AudioPolicyManagerBase::loadAudioPolicyConfig(const char *path) 34365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 34375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *root; 34385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *data; 34395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent data = (char *)load_file(path, NULL); 34415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (data == NULL) { 34425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return -ENODEV; 34435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent root = config_node("", ""); 34455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent config_load(root, data); 34465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadGlobalConfig(root); 34485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadHwModules(root); 34495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent config_free(root); 34515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent free(root); 34525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent free(data); 34535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34545ec145df7708564d385fd3fb764085321cf4c253Dima Zavin ALOGI("loadAudioPolicyConfig() loaded %s\n", path); 34555ec145df7708564d385fd3fb764085321cf4c253Dima Zavin 34565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 34575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 3458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3459739022f26a7127ba76a98dda65411496086114a7Dima Zavinvoid AudioPolicyManagerBase::defaultAudioPolicyConfig(void) 3460739022f26a7127ba76a98dda65411496086114a7Dima Zavin{ 3461739022f26a7127ba76a98dda65411496086114a7Dima Zavin HwModule *module; 3462739022f26a7127ba76a98dda65411496086114a7Dima Zavin IOProfile *profile; 3463739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3464739022f26a7127ba76a98dda65411496086114a7Dima Zavin mDefaultOutputDevice = AUDIO_DEVICE_OUT_SPEAKER; 3465739022f26a7127ba76a98dda65411496086114a7Dima Zavin mAttachedOutputDevices = AUDIO_DEVICE_OUT_SPEAKER; 3466739022f26a7127ba76a98dda65411496086114a7Dima Zavin mAvailableInputDevices = AUDIO_DEVICE_IN_BUILTIN_MIC; 3467739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3468739022f26a7127ba76a98dda65411496086114a7Dima Zavin module = new HwModule("primary"); 3469739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3470739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile = new IOProfile(module); 3471739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSamplingRates.add(44100); 3472739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 3473739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO); 3474739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSupportedDevices = AUDIO_DEVICE_OUT_SPEAKER; 3475739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY; 3476739022f26a7127ba76a98dda65411496086114a7Dima Zavin module->mOutputProfiles.add(profile); 3477739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3478739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile = new IOProfile(module); 3479739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSamplingRates.add(8000); 3480739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 3481739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO); 3482739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSupportedDevices = AUDIO_DEVICE_IN_BUILTIN_MIC; 3483739022f26a7127ba76a98dda65411496086114a7Dima Zavin module->mInputProfiles.add(profile); 3484739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3485739022f26a7127ba76a98dda65411496086114a7Dima Zavin mHwModules.add(module); 3486739022f26a7127ba76a98dda65411496086114a7Dima Zavin} 3487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin}; // namespace android 3489