AudioPolicyManagerBase.cpp revision c94dccc97cc3ed5171b45f46a0f7f8762d37156f
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 193cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 203cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent//#define VERY_VERBOSE_LOGGING 213cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent#ifdef VERY_VERBOSE_LOGGING 223cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent#define ALOGVV ALOGV 233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent#else 243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent#define ALOGVV(a...) do { } while(0) 253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent#endif 263cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 27f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <utils/Log.h> 28f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <hardware_legacy/AudioPolicyManagerBase.h> 291c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent#include <hardware/audio_effect.h> 3008b014d9e509c9163db6b33a63852e73db4d07ccEric Laurent#include <hardware/audio.h> 31f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <math.h> 325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#include <hardware_legacy/audio_policy_conf.h> 33f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 34e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinnamespace android_audio_legacy { 35f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 36f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 37f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyInterface implementation 38f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 39f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 40f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 41f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_devices device, 42f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state, 43f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 44f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 453cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent SortedVector <audio_io_handle_t> outputs; 46f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 476a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); 48f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 49f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // connect/disconnect only 1 device at a time 50f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::popCount(device) != 1) return BAD_VALUE; 51f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 52f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { 535efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid address: %s", device_address); 54f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 55f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 56f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 57f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output devices 58f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isOutputDevice(device)) { 59f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp && AudioSystem::isA2dpDevice(device)) { 615efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid device: %x", device); 62f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 63f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 64599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (!mHasUsb && audio_is_usb_device((audio_devices_t)device)) { 65599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent ALOGE("setDeviceConnectionState() invalid device: %x", device); 66599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent return BAD_VALUE; 67599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 68f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 69c952527e6f89d5427881462823514be9d79f13e6Eric Laurent // save a copy of the opened output descriptors before any output is opened or closed 70c952527e6f89d5427881462823514be9d79f13e6Eric Laurent // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() 71c952527e6f89d5427881462823514be9d79f13e6Eric Laurent mPreviousOutputs = mOutputs; 72f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 73f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 74f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device connection 75f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: 76f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableOutputDevices & device) { 7764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %x", device); 78f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 79f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 806a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() connecting device %x", device); 81f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 823cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (checkOutputsForDevice((audio_devices_t)device, state, outputs) != NO_ERROR) { 833cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return INVALID_OPERATION; 843cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 853cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %d outputs", 863cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.size()); 87f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // register new device as available 88f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device); 89f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 903cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!outputs.isEmpty()) { 913cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8 paramStr; 923cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (mHasA2dp && AudioSystem::isA2dpDevice(device)) { 933cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle A2DP device connection 943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioParameter param; 953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), String8(device_address)); 963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent paramStr = param.toString(); 973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mA2dpSuspended = false; 993cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } else if (AudioSystem::isBluetoothScoDevice(device)) { 1003cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle SCO device connection 1013cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 1023cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } else if (mHasUsb && audio_is_usb_device((audio_devices_t)device)) { 1033cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle USB device connection 1043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mUsbCardAndDevice = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 1053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent paramStr = mUsbCardAndDevice; 1063cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!paramStr.isEmpty()) { 1083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t i = 0; i < outputs.size(); i++) { 1093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mpClientInterface->setParameters(outputs[i], paramStr); 1103cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1113cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 112f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 114f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device disconnection 115f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 116f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableOutputDevices & device)) { 11764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %x", device); 118f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 119f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 120f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1216a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() disconnecting device %x", device); 122f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // remove device from available output devices 123f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device); 124f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent checkOutputsForDevice((audio_devices_t)device, state, outputs); 1265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mHasA2dp && AudioSystem::isA2dpDevice(device)) { 1273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle A2DP device disconnection 128b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpDeviceAddress = ""; 129b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpSuspended = false; 130b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else if (AudioSystem::isBluetoothScoDevice(device)) { 1313cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle SCO device disconnection 132b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mScoDeviceAddress = ""; 133599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } else if (mHasUsb && audio_is_usb_device((audio_devices_t)device)) { 1343cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle USB device disconnection 135599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mUsbCardAndDevice = ""; 136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 137f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 138f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 139f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 1405efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 141f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 143f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 144f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 146b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // outputs must be closed after checkOutputForAllStrategies() is executed 1473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!outputs.isEmpty()) { 1483cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t i = 0; i < outputs.size(); i++) { 1493cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // close unused outputs after device disconnection or direct outputs that have been 1503cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // opened by checkOutputsForDevice() to query dynamic parameters 1513cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if ((state == AudioSystem::DEVICE_STATE_UNAVAILABLE) || 1523cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (mOutputs.valueFor(outputs[i])->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) { 1533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent closeOutput(outputs[i]); 1543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 158c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 1595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(mOutputs.keyAt(i), getNewDevice(mOutputs.keyAt(i), true /*fromCache*/)); 1615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_WIRED_HEADSET; 165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO || 166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET || 167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; 169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 171f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 173f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input devices 174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isInputDevice(device)) { 175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 178f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device connection 179f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: { 180f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableInputDevices & device) { 18164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %d", device); 182f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 183f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAvailableInputDevices = (audio_devices_t)(mAvailableInputDevices | device); 185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device disconnection 189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableInputDevices & device)) { 19164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %d", device); 192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAvailableInputDevices = (audio_devices_t) (mAvailableInputDevices & ~device); 195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 196f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 1985efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 205f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 2065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if ((newDevice != 0) && (newDevice != inputDesc->mDevice)) { 2076a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() changing device from %x to %x for input %d", 208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 211f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 215f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 21964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() invalid device: %x", device); 220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 222f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(AudioSystem::audio_devices device, 224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE; 227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 address = String8(device_address); 228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isOutputDevice(device)) { 229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableOutputDevices) { 230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isA2dpDevice(device) && 2315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (!mHasA2dp || (address != "" && mA2dpDeviceAddress != address))) { 232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isBluetoothScoDevice(device) && 235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin address != "" && mScoDeviceAddress != address) { 236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 238599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (audio_is_usb_device((audio_devices_t)device) && 239599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent (!mHasUsb || (address != "" && mUsbCardAndDevice != address))) { 240599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent ALOGE("setDeviceConnectionState() invalid device: %x", device); 241599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent return state; 242599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (AudioSystem::isInputDevice(device)) { 246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableInputDevices) { 247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setPhoneState(int state) 255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2566a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() state %d", state); 257f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t newDevice = (audio_devices_t)0; 258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state < 0 || state >= AudioSystem::NUM_MODES) { 25964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() invalid state %d", state); 260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 262f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 263f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == mPhoneState ) { 26464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() setting same state %d", state); 265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 266f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 267f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if leaving call state, handle special case of active streams 269f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 2716a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, true); 274f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 275f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 277f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store previous phone state for management of sonification strategy below 278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int oldState = mPhoneState; 279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mPhoneState = state; 280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool force = false; 281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // are we entering or starting a call 283f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isStateInCall(oldState) && isStateInCall(state)) { 2846a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Entering call in setPhoneState()"); 285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when starting a call 286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(oldState) && !isStateInCall(state)) { 2896a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Exiting call in setPhoneState()"); 290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when exiting a call 291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(state) && (state != oldState)) { 2946a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 295f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when switching between telephony and VoIP 296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 297f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check for device and output changes triggered by new phone state 3015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/); 302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 304c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 306b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when ending call 309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(oldState) && newDevice == 0) { 311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin newDevice = hwOutputDesc->device(); 312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when changing from ring tone to in call mode, mute the ringing tone 315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // immediately and delay the route change to avoid sending the ring tone 316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // tail into the earpiece or headset. 317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int delayMs = 0; 318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) { 319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // delay the device change command by twice the output latency to have some margin 320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and be sure that audio buffers not yet affected by the mute are out when 321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // we actually apply the route change 322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delayMs = hwOutputDesc->mLatency*2; 323b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(AudioSystem::RING, true, mPrimaryOutput); 324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // change routing is necessary 327b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setOutputDevice(mPrimaryOutput, newDevice, force, delayMs); 328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if entering in call state, handle special case of active streams 330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(state)) { 3326a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 333f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // unmute the ringing tone after a sufficient delay if it was muted before 334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // setting output device above 335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (oldState == AudioSystem::MODE_RINGTONE) { 336b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(AudioSystem::RING, false, mPrimaryOutput, MUTE_TIME_MS); 337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, true, true); 340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == AudioSystem::MODE_RINGTONE && 345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = true; 347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = false; 349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) 353f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3546a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool forceVolumeReeval = false; 357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(usage) { 358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_COMMUNICATION: 359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO && 360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 36164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 364f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_MEDIA: 368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP && 369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 370f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 3711afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE && 3721afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent config != AudioSystem::FORCE_NO_BT_A2DP) { 37364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_RECORD: 379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY && 380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 38164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 382f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_DOCK: 387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK && 388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_BT_DESK_DOCK && 389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_DIGITAL_DOCK) { 39264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 39864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid usage %d", usage); 399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // check for device and output changes triggered by new force usage 403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 405c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 4065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 4075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 4085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, true /*fromCache*/); 4094366b4a6735e5da342b56773073f0b41197c777fEric Laurent setOutputDevice(output, newDevice, (newDevice != 0)); 4104366b4a6735e5da342b56773073f0b41197c777fEric Laurent if (forceVolumeReeval && (newDevice != 0)) { 4115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent applyStreamVolumes(output, newDevice, 0, true); 4125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 4185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 4195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if ((newDevice != 0) && (newDevice != inputDesc->mDevice)) { 4206a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() changing device from %x to %x for input %d", 421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage) 432f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mForceUse[usage]; 434f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 435f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 436f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setSystemProperty(const char* property, const char* value) 437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 4386a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setSystemProperty() property %s, value %s", property, value); 439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (strcmp(property, "ro.camera.sound.forced") == 0) { 440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (atoi(value)) { 4416a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("ENFORCED_AUDIBLE cannot be muted"); 442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false; 443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 4446a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("ENFORCED_AUDIBLE can be muted"); 445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true; 446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 449f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4503cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric LaurentAudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getProfileForDirectOutput( 4513cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_devices_t device, 45270c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 45370c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t format, 45470c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 4550977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags) 45670c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 45770c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 45870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 45970c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 46070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 46170c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { 4623cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; 4633cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 4643cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent channelMask, 4653cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AUDIO_OUTPUT_FLAG_DIRECT)) { 4663cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (mAvailableOutputDevices & profile->mSupportedDevices) { 4673cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return mHwModules[i]->mOutputProfiles[j]; 4683cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 46970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 47070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 47170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 47270c236c9290732782d5267935af1475b8d5ae602Eric Laurent return 0; 47370c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 47470c236c9290732782d5267935af1475b8d5ae602Eric Laurent 475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream, 476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 47870c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::output_flags flags) 480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t output = 0; 482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t latency = 0; 483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); 4845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 48570c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getOutput() stream %d, samplingRate %d, format %d, channelMask %x, flags %x", 48670c236c9290732782d5267935af1475b8d5ae602Eric Laurent stream, samplingRate, format, channelMask, flags); 487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mCurOutput != 0) { 49070c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", 491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput] == 0) { 4946a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() opening test output"); 4953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = mTestDevice; 497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = mTestSamplingRate; 498f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFormat = mTestFormat; 49970c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mChannelMask = mTestChannels; 500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = mTestLatencyMs; 5010977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent outputDesc->mFlags = (audio_output_flags_t)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0); 502f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 50370c236c9290732782d5267935af1475b8d5ae602Eric Laurent mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice, 504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 50670c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 509f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput]) { 510f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 511f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"),mCurOutput); 512f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 513f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(mTestOutputs[mCurOutput], outputDesc); 514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 515f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 516f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mTestOutputs[mCurOutput]; 517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 518f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 519f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 520f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a direct output if required by specified parameters 5213cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = getProfileForDirectOutput(device, 5223cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent samplingRate, 5233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent format, 5243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent channelMask, 5253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (audio_output_flags_t)flags); 5263cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile != NULL) { 527f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5286a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() opening direct output device %x", device); 52970c236c9290732782d5267935af1475b8d5ae602Eric Laurent 5303cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(profile); 531f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = device; 532f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = samplingRate; 53370c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mFormat = (audio_format_t)format; 53470c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mChannelMask = (audio_channel_mask_t)channelMask; 535f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = 0; 5363cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputDesc->mFlags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);; 537f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 538f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mStopTime[stream] = 0; 5393cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent output = mpClientInterface->openOutput(profile->mModule->mHandle, 54070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 541f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 54370c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5479f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi // only accept an output with the requested parameters 548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == 0 || 549f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || 550f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != 0 && format != outputDesc->mFormat) || 55170c236c9290732782d5267935af1475b8d5ae602Eric Laurent (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { 5523cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," 5533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent "format %d %d, channelMask %04x %04x", output, samplingRate, 5543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, 5553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputDesc->mChannelMask); 556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output != 0) { 557f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 558f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 559f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete outputDesc; 560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 561f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 562f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(output, outputDesc); 5633cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("getOutput() returns direct output %d", output); 564f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 565f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 566f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5679f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi // ignoring channel mask due to downmix capability in mixer 5689f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi 569f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a non direct output 570f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 571f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // get which output is suitable for the specified stream. The actual routing change will happen 572f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when startOutput() will be called 573c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs); 574f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent output = selectOutput(outputs, flags); 576f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 57770c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d," 57870c236c9290732782d5267935af1475b8d5ae602Eric Laurent "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); 579f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("getOutput() returns output %d", output); 5815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 582f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 583f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 584f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::selectOutput(const SortedVector<audio_io_handle_t>& outputs, 5865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioSystem::output_flags flags) 5875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 5885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // select one output among several that provide a path to a particular device or set of 5895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // devices (the list was previously build by getOutputsForDevice()). 5905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // The priority is as follows: 5915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 1: the output with the highest number of requested policy flags 5925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 2: the primary output 5935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 3: the first output in the list 5945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 5955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputs.size() == 0) { 5965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 5975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 5985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputs.size() == 1) { 5995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputs[0]; 6005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent int maxCommonFlags = 0; 6035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t outputFlags = 0; 6045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t outputPrimary = 0; 6055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 6075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]); 6085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!outputDesc->isDuplicated()) { 6095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent int commonFlags = (int)AudioSystem::popCount(outputDesc->mProfile->mFlags & flags); 6105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (commonFlags > maxCommonFlags) { 6115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputFlags = outputs[i]; 6125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent maxCommonFlags = commonFlags; 6135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); 6145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6150977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 6165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputPrimary = outputs[i]; 6175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputFlags != 0) { 6225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputFlags; 6235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputPrimary != 0) { 6255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputPrimary; 6265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputs[0]; 6295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 6305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 631f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, 632f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 633f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 6356a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 636f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 637f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 63864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startOutput() unknow output %d", output); 639f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 640f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 641f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 642f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 643f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // increment usage count for this stream on the requested output: 645f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE that the usage count is the same for duplicated output and hardware output which is 6465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // necessary for a correct control of hardware output routing by startOutput() and stopOutput() 647f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, 1); 648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->mRefCount[stream] == 1) { 6505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t prevDevice = outputDesc->device(); 6515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 652b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent routing_strategy strategy = getStrategy(stream); 653b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent bool shouldWait = (strategy == STRATEGY_SONIFICATION) || 654b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent (strategy == STRATEGY_SONIFICATION_RESPECTFUL); 655b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t waitMs = 0; 6565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool force = false; 6575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 6585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 659b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (desc != outputDesc) { 660b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // force a device change if any other output is managed by the same hw 661b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // module and has a current device selection that differs from selected device. 662b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // In this case, the audio HAL must receive the new device selection so that it can 663b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // change the device currently selected by the other active output. 664b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (outputDesc->sharesHwModuleWith(desc) && 6655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent desc->device() != newDevice) { 666b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent force = true; 667b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 668b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // wait for audio on other active outputs to be presented when starting 669b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // a notification so that audio focus effect can propagate. 670b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (shouldWait && (desc->refCount() != 0) && (waitMs < desc->latency())) { 671b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent waitMs = desc->latency(); 672b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 6735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 675b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); 676f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // handle special case for sonification while in call 6785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isInCall()) { 6795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleIncallSonification(stream, true, false); 6805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 681c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 6825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // apply volume rules for current stream and device if necessary 6835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent checkAndSetVolume(stream, 6845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mStreams[stream].getVolumeIndex((audio_devices_t)newDevice), 6855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent output, 6865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice); 68712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 6885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // update the outputs if starting an output with a stream that can affect notification 6895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // routing 6905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleNotificationRoutingForStream(stream); 691b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (waitMs > muteWaitMs) { 692b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent usleep((waitMs - muteWaitMs) * 2 * 1000); 693b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 6945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 695f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 696f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 697f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 699f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, 700f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 701f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 702f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7036a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 704f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 705f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 70664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() unknow output %d", output); 707f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 708f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 709f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 710f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 711f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 712f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle special case for sonification while in call 713f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, false); 715f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 716f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 717f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream] > 0) { 718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // decrement usage count of this stream on the output 719f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, -1); 720f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store time at which the stream was stopped - see isStreamActive() 7215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->mRefCount[stream] == 0) { 7225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStopTime[stream] = systemTime(); 7235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 7245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // delay the device switch by twice the latency because stopOutput() is executed when 7255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // the track stop() command is received and at that time the audio track buffer can 7265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // still contain data that needs to be drained. The latency only covers the audio HAL 7275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // and kernel buffers. Also the latency does not always include additional delay in the 7285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // audio path (audio DSP, CODEC ...) 7295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); 7305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 7315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // force restoring the device selection on other active outputs if it differs from the 7325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // one being selected for this output 7335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 7345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(i); 7355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 7365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (curOutput != output && 7375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent desc->refCount() != 0 && 7385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->sharesHwModuleWith(desc) && 7395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice != desc->device()) { 7405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(curOutput, 7415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent getNewDevice(curOutput, false /*fromCache*/), 7425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent true, 7435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mLatency*2); 7445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // update the outputs if stopping one with a stream that can affect notification routing 7475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleNotificationRoutingForStream(stream); 748f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 749f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 750f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 75164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() refcount is already 0 for output %d", output); 752f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 753f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 754f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 755f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 756f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output) 757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7586a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseOutput() %d", output); 759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 760f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 76164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseOutput() releasing unknown output %d", output); 762f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 764f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 766f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int testIndex = testOutputIndex(output); 767f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (testIndex != 0) { 768f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 769f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->refCount() == 0) { 770f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(index); 772f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(output); 773f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[testIndex] = 0; 774f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 775f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 776f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 777f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 778f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 779f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) { 780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(index); 782f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(output); 783f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 78412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 785f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource, 788f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 789f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 79070c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 791f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::audio_in_acoustics acoustics) 792f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 793f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t input = 0; 794f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device = getDeviceForInputSource(inputSource); 795f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 79670c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x", 79770c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputSource, samplingRate, format, channelMask, acoustics); 798f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 8005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW("getInput() could not find device for inputSource %d", inputSource); 801f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 802f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 803f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 804f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // adapt channel selection to input source 805f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(inputSource) { 806f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 80770c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = AudioSystem::CHANNEL_IN_VOICE_UPLINK; 808f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 809f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 81070c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = AudioSystem::CHANNEL_IN_VOICE_DNLINK; 811f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 812f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 81370c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK); 814f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 815f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 816f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 8195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = getInputProfile(device, 8205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent samplingRate, 8215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent format, 82270c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask); 8235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (profile == NULL) { 8245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d," 82570c236c9290732782d5267935af1475b8d5ae602Eric Laurent "channelMask %04x", 82670c236c9290732782d5267935af1475b8d5ae602Eric Laurent device, samplingRate, format, channelMask); 82770c236c9290732782d5267935af1475b8d5ae602Eric Laurent return 0; 82870c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 82970c236c9290732782d5267935af1475b8d5ae602Eric Laurent 83070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (profile->mModule->mHandle == 0) { 8313cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); 8325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 8335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 8345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 8355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile); 836f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 837f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mInputSource = inputSource; 838f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = device; 839f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mSamplingRate = samplingRate; 84070c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputDesc->mFormat = (audio_format_t)format; 84170c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputDesc->mChannelMask = (audio_channel_mask_t)channelMask; 842f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 84370c236c9290732782d5267935af1475b8d5ae602Eric Laurent input = mpClientInterface->openInput(profile->mModule->mHandle, 84470c236c9290732782d5267935af1475b8d5ae602Eric Laurent &inputDesc->mDevice, 845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mSamplingRate, 846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mFormat, 84770c236c9290732782d5267935af1475b8d5ae602Eric Laurent &inputDesc->mChannelMask); 848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // only accept input with the exact requested set of parameters 850f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input == 0 || 851f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != inputDesc->mSamplingRate) || 852f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != inputDesc->mFormat) || 85370c236c9290732782d5267935af1475b8d5ae602Eric Laurent (channelMask != inputDesc->mChannelMask)) { 85470c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getInput() failed opening input: samplingRate %d, format %d, channelMask %d", 85570c236c9290732782d5267935af1475b8d5ae602Eric Laurent samplingRate, format, channelMask); 856f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input != 0) { 857f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 858f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 859f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete inputDesc; 860f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 861f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.add(input, inputDesc); 863f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return input; 864f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 865f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 866f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startInput(audio_io_handle_t input) 867f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8686a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startInput() input %d", input); 869f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 870f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 87164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startInput() unknow input %d", input); 872f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 873f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 874f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 875f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 876f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 877f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestInput == 0) 878f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 879f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 880f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // refuse 2 active AudioRecord clients at the same time 881f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getActiveInput() != 0) { 88264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startInput() input %d failed: other input already started", input); 883f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 885f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 886f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 887f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 888f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice); 889f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 890f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource); 8916a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 892f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 893f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 894f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 895f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 1; 896f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 897f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 898f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 899f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopInput(audio_io_handle_t input) 900f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 9016a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopInput() input %d", input); 902f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 903f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 90464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() unknow input %d", input); 905f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 906f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (inputDesc->mRefCount == 0) { 91064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() input %d already stopped", input); 911f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 912f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 913f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 914f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), 0); 915f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 916f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 917f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 918f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 919f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 920f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 921f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseInput(audio_io_handle_t input) 922f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 9236a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() %d", input); 924f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 925f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 92664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseInput() releasing unknown input %d", input); 927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 928f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 929f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 930f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(index); 931f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.removeItem(input); 9326a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() exit"); 933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream, 936f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMin, 937f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMax) 938f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 9396a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 940f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (indexMin < 0 || indexMin >= indexMax) { 94164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 943f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 944f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMin = indexMin; 945f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMax = indexMax; 946f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 947f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 948c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, 949c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 950c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 951f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 952f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 953f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 954f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 955f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 956c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 957c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 958c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 959f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 960f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force max volume if stream cannot be muted 961f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 962f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 963b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", 964c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent stream, device, index); 965c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 966c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 967c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // clear all device specific values 968c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 969c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.clear(); 970c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 971c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 972f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 973f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // compute and apply stream volume on all outputs according to connected device 974f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin status_t status = NO_ERROR; 975f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 976c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent audio_devices_t curDevice = 977c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent getDeviceForVolume((audio_devices_t)mOutputs.valueAt(i)->device()); 978c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent if (device == curDevice) { 979c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); 980c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent if (volStatus != NO_ERROR) { 981c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status = volStatus; 982c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent } 983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 985f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return status; 986f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 987f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 988c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, 989c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int *index, 990c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 992c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (index == NULL) { 993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 994f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 995c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 996c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 997c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 998c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 999c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // the strategy the stream belongs to. 1000c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 10015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = (audio_devices_t)getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); 1002c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1003c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = getDeviceForVolume(device); 1004c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 1005c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 1006c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 1007f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1008f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1009f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1010c94dccc97cc3ed5171b45f46a0f7f8762d37156fGlenn Kastenaudio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(const effect_descriptor_t *desc) 1011f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 10126a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutputForEffect()"); 1013f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // apply simple rule where global effects are attached to the same output as MUSIC streams 10144660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen 10154660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen routing_strategy strategy = getStrategy(AudioSystem::MUSIC); 10164660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 1017c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs); 10184660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen int outIdx = 0; 10194660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen for (size_t i = 0; i < dstOutputs.size(); i++) { 10204660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen AudioOutputDescriptor *desc = mOutputs.valueFor(dstOutputs[i]); 10214660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) { 10224660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen outIdx = i; 10234660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 10244660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 10254660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen return dstOutputs[outIdx]; 1026f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1027f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1028c94dccc97cc3ed5171b45f46a0f7f8762d37156fGlenn Kastenstatus_t AudioPolicyManagerBase::registerEffect(const effect_descriptor_t *desc, 10291c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent audio_io_handle_t io, 1030f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t strategy, 1031f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session, 1032f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int id) 1033f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 10341c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 1035f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 10361c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent index = mInputs.indexOfKey(io); 10371c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent if (index < 0) { 103864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() unknown io %d", io); 10391c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent return INVALID_OPERATION; 10401c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent } 1041f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1042f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1043f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 104464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 1045f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin desc->name, desc->memoryUsage); 1046f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1047f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1048f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory += desc->memoryUsage; 10496a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 10501c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent desc->name, io, strategy, session, id); 10516a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 1052f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1053f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = new EffectDescriptor(); 1054f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t)); 10551c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent pDesc->mIo = io; 1056f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mStrategy = (routing_strategy)strategy; 1057f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mSession = session; 1058582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = false; 1059582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1060f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.add(id, pDesc); 1061f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1062f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1063f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1064f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1065f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::unregisterEffect(int id) 1066f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1067f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mEffects.indexOfKey(id); 1068f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 106964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 1070f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1071f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1072f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1073f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = mEffects.valueAt(index); 1074f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1075582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent setEffectEnabled(pDesc, false); 1076582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1077f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) { 107864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() memory %d too big for total %d", 1079f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1080f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage = mTotalEffectsMemory; 1081f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1082f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory -= pDesc->mDesc.memoryUsage; 10836a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 1084582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1085f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1086f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.removeItem(id); 1087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete pDesc; 1088f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1089f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1090f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1091f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1092582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(int id, bool enabled) 1093582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 1094582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1095582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (index < 0) { 109664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 1097582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1098582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1099582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1100582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 1101582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 1102582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1103582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(EffectDescriptor *pDesc, bool enabled) 1104582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 1105582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled == pDesc->mEnabled) { 11066a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(%s) effect already %s", 1107582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 1108582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1109582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1110582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1111582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled) { 1112582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 111364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 1114582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10); 1115582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1116582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1117582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad; 11186a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 1119582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } else { 1120582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) { 112164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 1122582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 1123582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 1124582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1125582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad; 11266a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 1127582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1128582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = enabled; 1129582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return NO_ERROR; 1130582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 1131582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1132f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const 1133f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1134f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin nsecs_t sysTime = systemTime(); 1135f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueAt(i)->mRefCount[stream] != 0 || 1137f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ns2ms(sysTime - mOutputs.valueAt(i)->mStopTime[stream]) < inPastMs) { 1138f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return true; 1139f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1140f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1141f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1143f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1144f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::dump(int fd) 1146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1147f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1148f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1149f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 1150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 1152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1153b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 115470c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput); 1155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string()); 1157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string()); 1159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1160599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " USB audio ALSA %s\n", mUsbCardAndDevice.string()); 1161599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent result.append(buffer); 1162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices); 1163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices); 1165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 1167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]); 1169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]); 1171f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]); 1173f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]); 1175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 1177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 11785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 117970c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 11805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, buffer, strlen(buffer)); 118170c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 118270c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, "- HW Module %d:\n", i + 1); 11835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, buffer, strlen(buffer)); 118470c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules[i]->dump(fd); 11855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 11865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 1187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nOutputs dump:\n"); 1188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 1191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueAt(i)->dump(fd); 1193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nInputs dump:\n"); 1196f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1198f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 1199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.valueAt(i)->dump(fd); 1201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nStreams dump:\n"); 1204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1205c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, 1206c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 1207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 1209c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, " %02d ", i); 1210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1211c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[i].dump(fd); 1212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 1215f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 1216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "Registered effects:\n"); 1219f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mEffects.size(); i++) { 1221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 1222f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.valueAt(i)->dump(fd); 1224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyManagerBase 1232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface) 1235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin : 1236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Thread(false), 1238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 123970c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput((audio_io_handle_t)0), 1240f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices((audio_devices_t)0), 1241ca0657a1ca087a6d474a75fcfedd6aac3901d587Glenn Kasten mPhoneState(AudioSystem::MODE_NORMAL), 1242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 1243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 1244599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mA2dpSuspended(false), mHasA2dp(false), mHasUsb(false) 1245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface = clientInterface; 1247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) { 1249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[i] = AudioSystem::FORCE_NONE; 1250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin initializeVolumeCurves(); 1253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpDeviceAddress = String8(""); 1255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mScoDeviceAddress = String8(""); 1256599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mUsbCardAndDevice = String8(""); 1257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 12585ec145df7708564d385fd3fb764085321cf4c253Dima Zavin if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { 12595ec145df7708564d385fd3fb764085321cf4c253Dima Zavin if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { 1260739022f26a7127ba76a98dda65411496086114a7Dima Zavin ALOGE("could not load audio policy configuration file, setting defaults"); 1261739022f26a7127ba76a98dda65411496086114a7Dima Zavin defaultAudioPolicyConfig(); 12625ec145df7708564d385fd3fb764085321cf4c253Dima Zavin } 12635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 12645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 1265b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // open all output streams needed to access attached devices 126670c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 126770c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 126870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 126970c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGW("could not open HW module %s", mHwModules[i]->mName); 127070c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 127170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 127270c236c9290732782d5267935af1475b8d5ae602Eric Laurent // open all output streams needed to access attached devices 127370c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 127470c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 127570c236c9290732782d5267935af1475b8d5ae602Eric Laurent const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j]; 127670c236c9290732782d5267935af1475b8d5ae602Eric Laurent 127770c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (outProfile->mSupportedDevices & mAttachedOutputDevices) { 127870c236c9290732782d5267935af1475b8d5ae602Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile); 127970c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice & 128070c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mSupportedDevices); 128170c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput( 128270c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mModule->mHandle, 128370c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 128470c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mSamplingRate, 128570c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mFormat, 128670c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 128770c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mLatency, 128870c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mFlags); 128970c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (output == 0) { 129070c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete outputDesc; 129170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } else { 129270c236c9290732782d5267935af1475b8d5ae602Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | 129370c236c9290732782d5267935af1475b8d5ae602Eric Laurent (outProfile->mSupportedDevices & mAttachedOutputDevices)); 129470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mPrimaryOutput == 0 && 12950977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 129670c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput = output; 129770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 129870c236c9290732782d5267935af1475b8d5ae602Eric Laurent addOutput(output, outputDesc); 129970c236c9290732782d5267935af1475b8d5ae602Eric Laurent setOutputDevice(output, 130070c236c9290732782d5267935af1475b8d5ae602Eric Laurent (audio_devices_t)(mDefaultOutputDevice & 130170c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mSupportedDevices), 130270c236c9290732782d5267935af1475b8d5ae602Eric Laurent true); 1303b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1304b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1305b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 13085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE_IF((mAttachedOutputDevices & ~mAvailableOutputDevices), 1309b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent "Not output found for attached devices %08x", 13105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (mAttachedOutputDevices & ~mAvailableOutputDevices)); 1311b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1312b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 1313b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1314c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 13153cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 1316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1317b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput != 0) { 1318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1320b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER; 1323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = 44100; 1324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = AudioSystem::PCM_16_BIT; 1325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = AudioSystem::CHANNEL_OUT_STEREO; 1326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestLatencyMs = 0; 1327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = 0; 1328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[i] = 0; 1331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1333f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 1336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin run(buffer, ANDROID_PRIORITY_AUDIO); 1337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::~AudioPolicyManagerBase() 1342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin exit(); 1345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(mOutputs.keyAt(i)); 1348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(i); 1349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(mInputs.keyAt(i)); 1352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(i); 1353f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 135470c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 135570c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mHwModules[i]; 13565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 1357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::initCheck() 1360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1361b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; 1362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1364f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::threadLoop() 1366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 13676a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("entering threadLoop()"); 1368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin while (!exitPending()) 1369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1370f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 command; 1371f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int valueInt; 1372f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 value; 1373f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Mutex::Autolock _l(mLock); 1375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 1376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 1378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(command); 1379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 1381f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin valueInt != 0) { 13826a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("Test command %s received", command.string()); 1383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 target; 1384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("target"), target) != NO_ERROR) { 1385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin target = "Manager"; 1386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 1388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_output")); 1389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = valueInt; 1390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 1392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_direct")); 1393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "false") { 1394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "true") { 1396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = true; 1397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 1400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_input")); 1401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestInput = valueInt; 1402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 1405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_format")); 1406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int format = AudioSystem::INVALID_FORMAT; 1407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "PCM 16 bits") { 1408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_16_BIT; 1409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "PCM 8 bits") { 1410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_8_BIT; 1411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Compressed MP3") { 1412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::MP3; 1413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (format != AudioSystem::INVALID_FORMAT) { 1415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = format; 1417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("format"), format); 1420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 1425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_channels")); 1426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int channels = 0; 1427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "Channels Stereo") { 1429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_STEREO; 1430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Channels Mono") { 1431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_MONO; 1432f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (channels != 0) { 1434f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1435f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = channels; 1436f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("channels"), channels); 1439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 1444f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_sampleRate")); 1445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (valueInt >= 0 && valueInt <= 96000) { 1446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int samplingRate = valueInt; 1447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = samplingRate; 1449f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1450f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1451f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("sampling_rate"), samplingRate); 1452f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1453f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1454f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1455f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 1458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_reopen")); 1459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 146070c236c9290732782d5267935af1475b8d5ae602Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 1461b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(mPrimaryOutput); 146270c236c9290732782d5267935af1475b8d5ae602Eric Laurent 146370c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; 146470c236c9290732782d5267935af1475b8d5ae602Eric Laurent 1465b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(mPrimaryOutput); 1466b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(mPrimaryOutput); 1467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1468b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 1469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER; 147070c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput = mpClientInterface->openOutput(moduleHandle, 147170c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 1472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 1473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 147470c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 1475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 1476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 1477b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput == 0) { 14785efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d", 147970c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); 1480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1483b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1484b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent addOutput(mPrimaryOutput, outputDesc); 1485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 1490f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1495f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::exit() 1496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1498f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AutoMutex _l(mLock); 1499f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExit(); 1500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.signal(); 1501f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1502f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExitAndWait(); 1503f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinint AudioPolicyManagerBase::testOutputIndex(audio_io_handle_t output) 1506f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == mTestOutputs[i]) return i; 1509f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1510f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 1511f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1512f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1513f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- 1515f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1516f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc) 1517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1518f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mId = id; 1519f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.add(id, outputDesc); 1520f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1521f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1522f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 15233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurentstatus_t AudioPolicyManagerBase::checkOutputsForDevice(audio_devices_t device, 15243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioSystem::device_connection_state state, 15253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent SortedVector<audio_io_handle_t>& outputs) 1526f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 15273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *desc; 1528b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1529b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (state == AudioSystem::DEVICE_STATE_AVAILABLE) { 15303cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // first list already open outputs that can be routed to this device 1531b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 15323cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(i); 15333cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices & device)) { 15343cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i)); 15353cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(mOutputs.keyAt(i)); 1536b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1537b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 15383cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // then look for output profiles that can be routed to this device 15393cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent SortedVector<IOProfile *> profiles; 154070c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 1541b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent { 154270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 154370c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 154470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 154570c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 154670c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 154770c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices & device) { 15483cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): adding profile %d from module %d", j, i); 15493cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profiles.add(mHwModules[i]->mOutputProfiles[j]); 155070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 155170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 1552b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 155370c236c9290732782d5267935af1475b8d5ae602Eric Laurent 15543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profiles.isEmpty() && outputs.isEmpty()) { 15553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 15563cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return BAD_VALUE; 155770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 155870c236c9290732782d5267935af1475b8d5ae602Eric Laurent 15593cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // open outputs for matching profiles if needed. Direct outputs are also opened to 15603cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 15613cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 15623cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = profiles[profile_index]; 1563b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 15643cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // nothing to do if one output is already opened for this profile 15653cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent size_t j; 15663cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (j = 0; j < outputs.size(); j++) { 15673cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(j); 15683cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && desc->mProfile == profile) { 15693cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent break; 15703cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 15713cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 15723cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (j != outputs.size()) { 15733cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent continue; 15743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 15753cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 15763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("opening output for device %08x", device); 15773cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = new AudioOutputDescriptor(profile); 15783cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc->mDevice = device; 15793cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle, 15803cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mDevice, 15813cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mSamplingRate, 15823cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mFormat, 15833cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mChannelMask, 15843cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mLatency, 15853cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc->mFlags); 15863cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (output != 0) { 15873cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { 15883cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8 reply; 15893cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent char *value; 15903cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mSamplingRates[0] == 0) { 15913cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply = mpClientInterface->getParameters(output, 15923cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 15933cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice() direct output sup sampling rates %s", 15943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply.string()); 15953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent value = strpbrk((char *)reply.string(), "="); 15963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (value != NULL) { 15973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent loadSamplingRates(value, profile); 15983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 15993cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16003cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mFormats[0] == 0) { 16013cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply = mpClientInterface->getParameters(output, 16023cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 16033cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice() direct output sup formats %s", 16043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply.string()); 16053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent value = strpbrk((char *)reply.string(), "="); 16063cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (value != NULL) { 16073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent loadFormats(value, profile); 16083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16103cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mChannelMasks[0] == 0) { 16113cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply = mpClientInterface->getParameters(output, 16123cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 16133cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice() direct output sup channel masks %s", 16143cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply.string()); 16153cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent value = strpbrk((char *)reply.string(), "="); 16163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (value != NULL) { 16173cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent loadOutChannels(value + 1, profile); 16183cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16193cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16203cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (((profile->mSamplingRates[0] == 0) && 16213cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mSamplingRates.size() < 2)) || 16223cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ((profile->mFormats[0] == 0) && 16233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mFormats.size() < 2)) || 16243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ((profile->mFormats[0] == 0) && 16253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mChannelMasks.size() < 2))) { 16263cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice() direct output missing param"); 16273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent output = 0; 16283cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } else { 16293cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent addOutput(output, desc); 16303cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16313cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } else { 16323cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_io_handle_t duplicatedOutput = 0; 16333cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // add output descriptor 16343cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent addOutput(output, desc); 16353cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // set initial stream volume for device 16364366b4a6735e5da342b56773073f0b41197c777fEric Laurent applyStreamVolumes(output, device, 0, true); 16373cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 16383cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent //TODO: configure audio effect output stage here 16393cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 16403cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // open a duplicating output thread for the new output and the primary output 16413cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent duplicatedOutput = mpClientInterface->openDuplicateOutput(output, 16423cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mPrimaryOutput); 16433cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (duplicatedOutput != 0) { 16443cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // add duplicated output descriptor 16453cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL); 16463cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); 16473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mOutput2 = mOutputs.valueFor(output); 16483cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mSamplingRate = desc->mSamplingRate; 16493cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mFormat = desc->mFormat; 16503cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mChannelMask = desc->mChannelMask; 16513cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mLatency = desc->mLatency; 16523cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent addOutput(duplicatedOutput, dupOutputDesc); 16534366b4a6735e5da342b56773073f0b41197c777fEric Laurent applyStreamVolumes(duplicatedOutput, device, 0, true); 16543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } else { 16553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice() could not open dup output for %d and %d", 16563cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mPrimaryOutput, output); 16573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mpClientInterface->closeOutput(output); 16583cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mOutputs.removeItem(output); 16593cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent output = 0; 16603cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16613cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16623cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16633cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (output == 0) { 16643cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice() could not open output for device %x", device); 16653cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent delete desc; 16663cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profiles.removeAt(profile_index); 16673cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile_index--; 1668b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 16693cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(output); 16703cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): adding output %d", output); 1671f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 16723cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16733cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 16743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profiles.isEmpty()) { 16753cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 16763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return BAD_VALUE; 1677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1678f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1679b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // check if one opened output is not needed any more after disconnecting one device 1680b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 16813cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(i); 16823cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && 16833cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent !(desc->mProfile->mSupportedDevices & mAvailableOutputDevices)) { 16843cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i)); 16853cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(mOutputs.keyAt(i)); 16863cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16873cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16883cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 16893cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent { 16903cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (mHwModules[i]->mHandle == 0) { 16913cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent continue; 16923cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16933cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 16943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent { 16953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; 16963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if ((profile->mSupportedDevices & device) && 16973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) { 16983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): clearing direct output profile %d on module %d", 16993cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent j, i); 17003cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mSamplingRates[0] == 0) { 17013cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.clear(); 17023cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.add(0); 17033cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mFormats[0] == 0) { 17053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mFormats.clear(); 17063cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mFormats.add((audio_format_t)0); 17073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mChannelMasks[0] == 0) { 17093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.clear(); 17103cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.add((audio_channel_mask_t)0); 17113cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17123cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1713b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1715f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 17163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return NO_ERROR; 1717f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1719b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::closeOutput(audio_io_handle_t output) 1720f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1721b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput(%d)", output); 1722f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1723b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 1724b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputDesc == NULL) { 1725b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGW("closeOutput() unknown output %d", output); 1726b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1727f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1728f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1729b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // look for duplicated outputs connected to the output being removed. 1730b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1731b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i); 1732b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->isDuplicated() && 1733b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (dupOutputDesc->mOutput1 == outputDesc || 1734b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent dupOutputDesc->mOutput2 == outputDesc)) { 1735b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc2; 1736b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->mOutput1 == outputDesc) { 1737b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput2; 1738b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 1739b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput1; 1740b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1741b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // As all active tracks on duplicated output will be deleted, 1742b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // and as they were also referenced on the other output, the reference 1743b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // count for their stream type must be adjusted accordingly on 1744b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // the other output. 1745b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (int j = 0; j < (int)AudioSystem::NUM_STREAM_TYPES; j++) { 1746b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent int refCount = dupOutputDesc->mRefCount[j]; 1747b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2->changeRefCount((AudioSystem::stream_type)j,-refCount); 1748b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1749b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i); 1750b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); 1751f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1752b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(duplicatedOutput); 1753b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(duplicatedOutput); 1754b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(duplicatedOutput); 1755f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1756f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1757b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1758b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioParameter param; 1759b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent param.add(String8("closing"), String8("true")); 1760b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(output, param.toString()); 1761b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1762b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(output); 1763b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(output); 1764b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(output); 1765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1766f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1767c952527e6f89d5427881462823514be9d79f13e6Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManagerBase::getOutputsForDevice(audio_devices_t device, 1768c952527e6f89d5427881462823514be9d79f13e6Eric Laurent DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs) 1769f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1770b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t> outputs; 1771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 17723cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getOutputsForDevice() device %04x", device); 1773c952527e6f89d5427881462823514be9d79f13e6Eric Laurent for (size_t i = 0; i < openOutputs.size(); i++) { 17743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("output %d isDuplicated=%d device=%04x", 1775c952527e6f89d5427881462823514be9d79f13e6Eric Laurent i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices()); 1776c952527e6f89d5427881462823514be9d79f13e6Eric Laurent if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) { 1777c952527e6f89d5427881462823514be9d79f13e6Eric Laurent ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i)); 1778c952527e6f89d5427881462823514be9d79f13e6Eric Laurent outputs.add(openOutputs.keyAt(i)); 1779f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1781b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return outputs; 1782f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1783f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1784b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentbool AudioPolicyManagerBase::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, 1785b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t>& outputs2) 1786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1787b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1.size() != outputs2.size()) { 1788b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 1789f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1790b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < outputs1.size(); i++) { 1791b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1[i] != outputs2[i]) { 1792b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 1793f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1794f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1795b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return true; 1796b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 1797b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1798b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy) 1799b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 180001e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); 180101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); 1802c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs); 1803c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); 1804b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1805b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!vectorsEqual(srcOutputs,dstOutputs)) { 1806b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", 1807b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent strategy, srcOutputs[0], dstOutputs[0]); 18085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // mute strategy while moving tracks from one output to another 18095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < srcOutputs.size(); i++) { 1810fa3697d716b444bbea6be480801536c44bf69214Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]); 1811fa3697d716b444bbea6be480801536c44bf69214Eric Laurent if (desc->strategyRefCount(strategy) != 0) { 1812fa3697d716b444bbea6be480801536c44bf69214Eric Laurent setStrategyMute(strategy, true, srcOutputs[i]); 1813fa3697d716b444bbea6be480801536c44bf69214Eric Laurent setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); 1814fa3697d716b444bbea6be480801536c44bf69214Eric Laurent } 18155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 1816f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Move effects associated to this strategy from previous output to new output 18184660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (strategy == STRATEGY_MEDIA) { 18194660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen int outIdx = 0; 18204660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen for (size_t i = 0; i < dstOutputs.size(); i++) { 18214660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen AudioOutputDescriptor *desc = mOutputs.valueFor(dstOutputs[i]); 18224660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) { 18234660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen outIdx = i; 18244660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 18254660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 18264660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen SortedVector<audio_io_handle_t> moved; 18274660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen for (size_t i = 0; i < mEffects.size(); i++) { 18284660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen EffectDescriptor *desc = mEffects.valueAt(i); 18294660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX && 18304660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen desc->mIo != dstOutputs[outIdx]) { 18314660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (moved.indexOf(desc->mIo) < 0) { 18324660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen ALOGV("checkOutputForStrategy() moving effect %d to output %d", 18334660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen mEffects.keyAt(i), dstOutputs[outIdx]); 18344660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, desc->mIo, 18354660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen dstOutputs[outIdx]); 18364660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen moved.add(desc->mIo); 18374660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 18384660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen desc->mIo = dstOutputs[outIdx]; 18394660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 18404660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 18414660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 18425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // Move tracks associated to this strategy from previous output to new output 1843f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 1844f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)i) == strategy) { 184512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi //FIXME see fixme on name change 18464660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, 18474660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen dstOutputs[0] /* ignored */); 1848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1850f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1851f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1852f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1853f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkOutputForAllStrategies() 1854f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1855c16ac09f510437e8340be691720177a490ae78f0Eric Laurent checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 1856f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_PHONE); 1857f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_SONIFICATION); 185812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 1859f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_MEDIA); 1860f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_DTMF); 1861f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1863b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::getA2dpOutput() 1864b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 18655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp) { 1866b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1867b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1868b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1869b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1870b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 1871b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 1872b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mOutputs.keyAt(i); 1873b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1874b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1875b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1876b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1877b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 1878b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1879f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkA2dpSuspend() 1880f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 18815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp) { 1882b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1883b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1884b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t a2dpOutput = getA2dpOutput(); 1885b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (a2dpOutput == 0) { 1886b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1887b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1888b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1889f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // suspend A2DP output if: 1890f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (NOT already suspended) && 1891f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is connected && 1892f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage for communication || for record is SCO))) || 1893f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is ringing || in call) 1894f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1895f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // restore A2DP output if: 1896f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (Already suspended) && 1897f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is NOT connected || 1898f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage NOT for communication && NOT for record is SCO))) && 1899f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is NOT ringing && NOT in call) 1900f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1901f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpSuspended) { 1902f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress == "") || 1903f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) && 1904f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) && 1905f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState != AudioSystem::MODE_IN_CALL) && 1906f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState != AudioSystem::MODE_RINGTONE))) { 1907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1908b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->restoreOutput(a2dpOutput); 1909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = false; 1910f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1911f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1912f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress != "") && 1913f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 1914f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) || 1915f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState == AudioSystem::MODE_IN_CALL) || 1916f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState == AudioSystem::MODE_RINGTONE))) { 1917f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1918b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->suspendOutput(a2dpOutput); 1919f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = true; 1920f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1921f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1922f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1923f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1924f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache) 1925f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1926f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device = (audio_devices_t)0; 1927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1928f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 1929f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check the following by order of priority to request a routing change if necessary: 1930c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 1: the strategy enforced audible is active on the output: 1931c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // use device for strategy enforced audible 1932c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 2: we are in call or the strategy phone is active on the output: 1933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy phone 1934c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 3: the strategy sonification is active on the output: 1935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy sonification 193612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 4: the strategy "respectful" sonification is active on the output: 193712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // use device for strategy "respectful" sonification 193812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 5: the strategy media is active on the output: 1939f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy media 194012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 6: the strategy DTMF is active on the output: 1941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy DTMF 1942c16ac09f510437e8340be691720177a490ae78f0Eric Laurent if (outputDesc->isUsedByStrategy(STRATEGY_ENFORCED_AUDIBLE)) { 1943c16ac09f510437e8340be691720177a490ae78f0Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 1944c16ac09f510437e8340be691720177a490ae78f0Eric Laurent } else if (isInCall() || 1945c16ac09f510437e8340be691720177a490ae78f0Eric Laurent outputDesc->isUsedByStrategy(STRATEGY_PHONE)) { 1946f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 1947f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) { 1948f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 194912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION_RESPECTFUL)) { 19505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); 1951f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) { 1952f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 1953f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) { 1954f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 1955f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1956f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 19576a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getNewDevice() selected device %x", device); 1958f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return device; 1959f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1960f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1961f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getStrategyForStream(AudioSystem::stream_type stream) { 1962f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return (uint32_t)getStrategy(stream); 1963f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1964f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1965f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDevicesForStream(AudioSystem::stream_type stream) { 1966f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t devices; 1967f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // By checking the range of stream before calling getStrategy, we avoid 19685efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 1969f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and then return STRATEGY_MEDIA, but we want to return the empty set. 1970f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream < (AudioSystem::stream_type) 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 1971f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent devices = (audio_devices_t)0; 1972f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1973f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioPolicyManagerBase::routing_strategy strategy = getStrategy(stream); 19745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devices = getDeviceForStrategy(strategy, true /*fromCache*/); 1975f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1976f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return devices; 1977f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1978f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1979f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy( 1980f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream) { 1981f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // stream to strategy mapping 1982f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (stream) { 1983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::VOICE_CALL: 1984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::BLUETOOTH_SCO: 1985f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_PHONE; 1986f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::RING: 1987f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::ALARM: 1988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_SONIFICATION; 198912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::NOTIFICATION: 199012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi return STRATEGY_SONIFICATION_RESPECTFUL; 1991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DTMF: 1992f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_DTMF; 1993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 19945efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("unknown stream type"); 1995f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::SYSTEM: 1996f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 1997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // while key clicks are played produces a poor result 1998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::TTS: 1999f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::MUSIC: 2000f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_MEDIA; 2001c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case AudioSystem::ENFORCED_AUDIBLE: 2002c16ac09f510437e8340be691720177a490ae78f0Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 2003f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2004f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2005f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 200612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivivoid AudioPolicyManagerBase::handleNotificationRoutingForStream(AudioSystem::stream_type stream) { 200712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi switch(stream) { 200812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::MUSIC: 200912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 2010c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 201112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 201212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi default: 201312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 201412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 201512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi} 201612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 20175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, 20185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool fromCache) 2019f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2020f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device = 0; 2021f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2022f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (fromCache) { 20233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x", 20245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent strategy, mDeviceForStrategy[strategy]); 2025f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mDeviceForStrategy[strategy]; 2026f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2027f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2028f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (strategy) { 202912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 203012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case STRATEGY_SONIFICATION_RESPECTFUL: 203112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if (isInCall()) { 20325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 203312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 203412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // while media is playing (or has recently played), use the same device 20355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 203612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else { 203712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // when media is not playing anymore, fall back on the sonification behavior 20385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 203912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 204012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 204112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 204212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 2043f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_DTMF: 2044f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall()) { 2045f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when off call, DTMF strategy follows the same rules as MEDIA strategy 20465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 2047f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2048f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2049f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when in call, DTMF and PHONE strategies follow the same rules 2050f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2051f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2052f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_PHONE: 2053f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // for phone strategy, we first consider the forced use and then the available devices by order 2054f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // of priority 2055f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { 2056f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_BT_SCO: 2057f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall() || strategy != STRATEGY_DTMF) { 2058f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 2059f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2060f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2061f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 2062f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2063f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO; 2064f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2065f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if SCO device is requested but no SCO device is available, fall back to default case 2066f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2067f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2068f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: // FORCE_NONE 2069f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 20701afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (mHasA2dp && !isInCall() && 20711afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 20721afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 2073f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; 2074f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2075f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2076f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2077f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 20781afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE; 20791afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (device) break; 20801afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; 20811afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (device) break; 2082599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2083599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device) break; 2084599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2085599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device) break; 2086f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 2087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 208855ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 208955ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent if (device) break; 2090f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 2091f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2092f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE; 20935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 20945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2095f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 20965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); 2097f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2098f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2099f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_SPEAKER: 2101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 2102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // A2DP speaker when forcing to speaker output 21031afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (mHasA2dp && !isInCall() && 21041afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 21051afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 2106f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2107f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2108f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2109599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2110599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device) break; 2111599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2112599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device) break; 2113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 2114f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 211555ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 211655ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent if (device) break; 2117f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 2118f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2119f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 21205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 21215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2122f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 21235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); 2124f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2125f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2126f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2127f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2128f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2129f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_SONIFICATION: 2130f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2131f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 2132f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handleIncallSonification(). 2133f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 21345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); 2135f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2137c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // FALL THROUGH 2138c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 2139c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 2140c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 2141ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // except: 2142ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // - when in call where it doesn't default to STRATEGY_PHONE behavior 2143ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // - in countries where not enforced in which case it follows STRATEGY_MEDIA 2144c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 2145ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent if (strategy == STRATEGY_SONIFICATION || 2146ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent !mStreams[AUDIO_STREAM_ENFORCED_AUDIBLE].mCanBeMuted) { 2147ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 2148ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent if (device == 0) { 2149ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); 2150ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent } 2151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // The second device used for sonification is the same as the device used by media strategy 2153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_MEDIA: { 21561afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent uint32_t device2 = 0; 21571afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 21581afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 21591afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; 2160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 2161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 2164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 21681afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE; 21691afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent } 21701afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (device2 == 0) { 21711afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; 21721afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent } 21731afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (device2 == 0) { 2174599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2175599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 2176599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device2 == 0) { 2177599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2178599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 2179599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent if (device2 == 0) { 218055ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 2181f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2182f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 218355ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 2184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 2186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 2187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 2189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 2190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2192c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 2193c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, 0 otherwise 2194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device |= device2; 21955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 21965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 21985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); 2199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 2201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 220364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 2204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2206f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 22073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 2208f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)device; 2209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2211c952527e6f89d5427881462823514be9d79f13e6Eric Laurentvoid AudioPolicyManagerBase::updateDevicesAndOutputs() 2212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_STRATEGIES; i++) { 22145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 22155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2216c952527e6f89d5427881462823514be9d79f13e6Eric Laurent mPreviousOutputs = mOutputs; 22175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 22185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2219b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurentuint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc, 22209029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent audio_devices_t prevDevice, 22215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t delayMs) 22225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 22239029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // mute/unmute strategies using an incompatible device combination 22249029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // if muting, wait for the audio in pcm buffer to be drained before proceeding 22259029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // if unmuting, unmute only after the specified delay 22265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->isDuplicated()) { 2227b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return 0; 22285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 22295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 22305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t muteWaitMs = 0; 22315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t device = outputDesc->device(); 22325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool shouldMute = (outputDesc->refCount() != 0) && 22335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (AudioSystem::popCount(device) >= 2); 22349029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // temporary mute output if device selection changes to avoid volume bursts due to 22359029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // different per device volumes 22369029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent bool tempMute = (outputDesc->refCount() != 0) && (device != prevDevice); 22375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 22385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 22395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 22405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool mute = shouldMute && (curDevice & device) && (curDevice != device); 22415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool doMute = false; 22425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 22435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mute && !outputDesc->mStrategyMutedByDevice[i]) { 22445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent doMute = true; 22455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = true; 22465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){ 22475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent doMute = true; 22485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = false; 22495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 22509029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (doMute || tempMute) { 22515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t j = 0; j < mOutputs.size(); j++) { 22525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(j); 22535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if ((desc->supportedDevices() & outputDesc->supportedDevices()) == 0) { 22545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent continue; 22555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 22565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(j); 22573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", 22585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mute ? "muting" : "unmuting", i, curDevice, curOutput); 22595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); 22609029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (desc->strategyRefCount((routing_strategy)i) != 0) { 22619029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (tempMute) { 226201e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStrategyMute((routing_strategy)i, true, curOutput); 226301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStrategyMute((routing_strategy)i, false, curOutput, 226401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent desc->latency() * 2, device); 22659029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent } 22669029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (tempMute || mute) { 22679029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (muteWaitMs < desc->latency()) { 22689029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent muteWaitMs = desc->latency(); 22699029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent } 22705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 22715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 22725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 22735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 22745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 22755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 22765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // FIXME: should not need to double latency if volume could be applied immediately by the 22775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // audioflinger mixer. We must account for the delay between now and the next time 22785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // the audioflinger thread for this output will process a buffer (which corresponds to 22795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // one buffer size, usually 1/2 or 1/4 of the latency). 22805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent muteWaitMs *= 2; 22815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // wait for the PCM output buffers to empty before proceeding with the rest of the command 22825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (muteWaitMs > delayMs) { 2283b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs -= delayMs; 2284b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent usleep(muteWaitMs * 1000); 2285b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2287b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return 0; 2288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2290b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurentuint32_t AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, 2291f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2292f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent bool force, 2293f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent int delayMs) 2294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 22955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); 2296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 22975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioParameter param; 2298b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t muteWaitMs = 0; 2299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->isDuplicated()) { 2301b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); 2302b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); 2303b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // filter devices according to output selected 2306f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices); 2307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 23085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t prevDevice = outputDesc->mDevice; 23095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 23105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() prevDevice %04x", prevDevice); 23115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 23125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device != 0) { 23135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mDevice = device; 23145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 23159029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); 23165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Do not change the routing if: 23185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // - the requested device is 0 2319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the requested device is the same as current device and force is not specified. 2320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Doing this check here allows the caller to call setOutputDevice() without conditions 2321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((device == 0 || device == prevDevice) && !force) { 23225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); 2323b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 23265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() changing device"); 2327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do the routing 2328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)device); 23295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mpClientInterface->setParameters(output, param.toString(), delayMs); 23305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // update stream volumes according to new device 2332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin applyStreamVolumes(output, device, delayMs); 2333b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent 2334b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 23355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 2336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 23375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getInputProfile(audio_devices_t device, 23385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t samplingRate, 23395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t format, 23405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t channelMask) 23415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 23425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // Choose an input profile based on the requested capture parameters: select the first available 23435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // profile supporting all requested parameters. 23445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 234570c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 23465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent { 234770c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 23485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent continue; 23495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 235070c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 23515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent { 235270c236c9290732782d5267935af1475b8d5ae602Eric Laurent IOProfile *profile = mHwModules[i]->mInputProfiles[j]; 235370c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 23540977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent channelMask,(audio_output_flags_t)0)) { 235570c236c9290732782d5267935af1475b8d5ae602Eric Laurent return profile; 23565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 23575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 235970c236c9290732782d5267935af1475b8d5ae602Eric Laurent return NULL; 2360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2361f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2362f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) 2363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 23645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t device = 0; 2365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(inputSource) { 2367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_DEFAULT: 2368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_MIC: 2369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_RECOGNITION: 2370f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_COMMUNICATION: 2371f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO && 2372f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 2373f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; 2374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 2375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_WIRED_HEADSET; 23765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_BUILTIN_MIC) { 2377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BUILTIN_MIC; 2378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_CAMCORDER: 23815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mAvailableInputDevices & AudioSystem::DEVICE_IN_BACK_MIC) { 2382f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BACK_MIC; 23835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_BUILTIN_MIC) { 2384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BUILTIN_MIC; 2385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 2388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 2389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 23905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mAvailableInputDevices & AudioSystem::DEVICE_IN_VOICE_CALL) { 23915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = AudioSystem::DEVICE_IN_VOICE_CALL; 23925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 239564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 2396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 23986a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 2399f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)device; 2400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getActiveInput() 2403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 2405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mInputs.valueAt(i)->mRefCount > 0) { 2406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mInputs.keyAt(i); 2407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 2410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2412e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2413c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForVolume(audio_devices_t device) 2414e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2415e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent if (device == 0) { 2416e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // this happens when forcing a route update and no track is active on an output. 2417e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // In this case the returned category is not important. 2418c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 2419c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else if (AudioSystem::popCount(device) > 1) { 2420e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // Multiple device selection is either: 2421e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - speaker + one other device: give priority to speaker in this case. 2422e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 2423e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 2424e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // selection if not the speaker. 2425c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 2426c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 2427c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else { 2428c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 2429c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 2430e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 2431e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 243264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW_IF(AudioSystem::popCount(device) != 1, 2433c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 2434e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device); 2435e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2436c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return device; 2437c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 2438c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2439f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric LaurentAudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(audio_devices_t device) 2440c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 2441f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent switch(getDeviceForVolume(device)) { 2442e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 2443e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_EARPIECE; 2444e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 2445e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 2446e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 2447e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 2448e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 2449e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 2450e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_HEADSET; 2451e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 2452e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 2453e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 2454c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent case AUDIO_DEVICE_OUT_AUX_DIGITAL: 2455599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent case AUDIO_DEVICE_OUT_USB_ACCESSORY: 2456599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent case AUDIO_DEVICE_OUT_USB_DEVICE: 2457e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent default: 2458e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_SPEAKER; 2459e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 2460e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent} 2461e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2462f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentfloat AudioPolicyManagerBase::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, 2463e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int indexInUi) 2464e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2465e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device_category deviceCategory = getDeviceCategory(device); 2466e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 2467e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // the volume index in the UI is relative to the min and max volume indices for this stream type 2469e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 2470e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[VOLMIN].mIndex; 2471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 2472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (streamDesc.mIndexMax - streamDesc.mIndexMin); 2473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // find what part of the curve this index volume belongs to, or if it's out of bounds 2475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int segment = 0; 2476e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 2477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0.0f; 2478e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 2479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 0; 2480e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 2481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 1; 2482e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 2483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 2; 2484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { // out of bounds 2485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0f; 2486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // linear interpolation in the attenuation table in dB 2489e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent float decibels = curve[segment].mDBAttenuation + 2490e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 2491e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ( (curve[segment+1].mDBAttenuation - 2492e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation) / 2493e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(curve[segment+1].mIndex - 2494e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex)) ); 2495f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 2497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 2499e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex, volIdx, 2500e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mIndex, 2501e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation, 2502cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent decibels, 2503e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mDBAttenuation, 2504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin amplification); 2505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2506f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return amplification; 2507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2509cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2510e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2511e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 2512e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2513e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2514e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2515e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2516e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 2517cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent}; 2518cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent 2519e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2520e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2521e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 2522e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2523e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2524e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2525e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2526e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 2527e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2528e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2529ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks 2530ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets (See AudioService.java). 2531123897874418f9f0e48bb89386d8c470e6975f28Jean-Michel Trivi// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset. 2532ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2533ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent AudioPolicyManagerBase::sDefaultSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2534123897874418f9f0e48bb89386d8c470e6975f28Jean-Michel Trivi {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f} 2535ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent}; 2536ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent 2537ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2538ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent AudioPolicyManagerBase::sHeadsetSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 25397465678e0d5711ebcd78ae47b3a76821534a23eaEric Laurent {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f} 2540ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent}; 2541e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2542e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2543ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent *AudioPolicyManagerBase::sVolumeProfiles[AUDIO_STREAM_CNT] 2544e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent [AudioPolicyManagerBase::DEVICE_CATEGORY_CNT] = { 2545ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_VOICE_CALL 2546e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2547e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2548e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2549e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2550ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_SYSTEM 2551ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2552ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2553ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2554ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2555ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_RING 2556e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2557e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2558e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2559e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2560ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_MUSIC 2561ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 2562ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2563ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 2564ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2565ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_ALARM 256612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 256712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 256812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 256912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi }, 2570ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_NOTIFICATION 2571e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2572ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2573e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2574c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2575ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_BLUETOOTH_SCO 2576c16ac09f510437e8340be691720177a490ae78f0Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2577ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2578c16ac09f510437e8340be691720177a490ae78f0Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2579c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2580ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_ENFORCED_AUDIBLE 2581ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2582ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2583ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2584ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2585ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_DTMF 2586ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2587ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2588ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2589ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2590ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_TTS 2591ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 2592ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2593ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 2594ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2595e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2596e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2597e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentvoid AudioPolicyManagerBase::initializeVolumeCurves() 2598e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2599ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 2600e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 2601cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent mStreams[i].mVolumeCurve[j] = 2602ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sVolumeProfiles[i][j]; 2603cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2604cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2605f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2607c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentfloat AudioPolicyManagerBase::computeVolume(int stream, 2608c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2609c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2610f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device) 2611f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2612f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = 1.0; 2613f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 2615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2616f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 2617f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = outputDesc->device(); 2618f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2619f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2620f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if volume is not 0 (not muted), force media volume to max on digital output 2621f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::MUSIC && 2622f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin index != mStreams[stream].mIndexMin && 2623f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent (device == AUDIO_DEVICE_OUT_AUX_DIGITAL || 2624599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET || 2625599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_USB_ACCESSORY || 2626599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_USB_DEVICE)) { 2627f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0; 2628f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2629f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = volIndexToAmpl(device, streamDesc, index); 2631f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2632f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if a headset is connected, apply the following rules to ring tones and notifications 2633f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // to avoid sound level bursts in user's ears: 2634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - always attenuate ring tones and notifications volume by 6dB 2635f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - if music is playing, always limit the volume to current music volume, 2636f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // with a minimum threshold at -36dB so that notification is always perceived. 263712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 263812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if ((device & (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP | 263912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 264012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi AudioSystem::DEVICE_OUT_WIRED_HEADSET | 264112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) && 264212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION) 264312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) 264412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi || (stream == AudioSystem::SYSTEM)) && 2645f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin streamDesc.mCanBeMuted) { 2646f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 2647f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when the phone is ringing we must consider that music could have been paused just before 2648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // by the music application and behave as if music was active if the last music track was 2649f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // just stopped 2650ac3cf10ef6de12e69540a1244ac7255f93fa7502Eric Laurent if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || 2651ac3cf10ef6de12e69540a1244ac7255f93fa7502Eric Laurent mLimitRingtoneVolume) { 2652c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float musicVol = computeVolume(AudioSystem::MUSIC, 2653f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mStreams[AudioSystem::MUSIC].getVolumeIndex(device), 2654c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2655f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent device); 2656c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 2657c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 2658f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume > minVol) { 2659f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = minVol; 26606a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 2661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2662f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2665f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return volume; 2666f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2667f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2668c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::checkAndSetVolume(int stream, 2669c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2670c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2671f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2672c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 2673c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 2674f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2675f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2676f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change actual stream volume if the stream is muted 2677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 26783cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkAndSetVolume() stream %d muted count %d", 26795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent stream, mOutputs.valueFor(output)->mMuteCount[stream]); 2680f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2681f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2682f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2683f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change in call volume if bluetooth is connected and vice versa 2684f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 2685f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) { 26866a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 2687f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, mForceUse[AudioSystem::FOR_COMMUNICATION]); 2688f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 2689f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2690f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = computeVolume(stream, index, output, device); 2692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // We actually change the volume if: 2693f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the float value returned by computeVolume() changed 2694f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the force flag is set 2695f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 2696f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force) { 2697f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueFor(output)->mCurVolume[stream] = volume; 26983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 2699f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL || 2700f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::DTMF || 2701f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::BLUETOOTH_SCO) { 2702f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // offset value to reflect actual hardware volume that never reaches 0 2703f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java) 2704f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = 0.01 + 0.99 * volume; 2705f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 2706f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // enabled 2707f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::BLUETOOTH_SCO) { 2708f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs); 2709f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2710f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2711f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2712f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); 2713f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2715f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL || 2716f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::BLUETOOTH_SCO) { 2717f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float voiceVolume; 2718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force voice volume to max for bluetooth SCO as volume is managed by the headset 2719f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL) { 2720f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 2721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2722f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = 1.0; 2723f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2724f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2725b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { 2726f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 2727f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLastVoiceVolume = voiceVolume; 2728f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2729f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2730f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2731f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2732f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2733f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2734c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, 2735f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2736c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 2737c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 2738f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 27393cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("applyStreamVolumes() for output %d and device %x", output, device); 2740f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2741f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 2742c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 2743f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mStreams[stream].getVolumeIndex(device), 2744c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2745c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 2746c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs, 2747c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent force); 2748f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2749f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2750f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 275101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurentvoid AudioPolicyManagerBase::setStrategyMute(routing_strategy strategy, 275201e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent bool on, 275301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_io_handle_t output, 275401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent int delayMs, 275501e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t device) 2756f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 27573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 2758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 2759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)stream) == strategy) { 276001e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStreamMute(stream, on, output, delayMs, device); 2761f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2762f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2764f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 276501e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurentvoid AudioPolicyManagerBase::setStreamMute(int stream, 276601e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent bool on, 276701e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_io_handle_t output, 276801e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent int delayMs, 276901e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t device) 2770f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 2772f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 277301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent if (device == 0) { 277401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent device = outputDesc->device(); 277501e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent } 2776f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 27773cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x", 277801e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent stream, on, output, outputDesc->mMuteCount[stream], device); 2779f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (on) { 2781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 2782f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (streamDesc.mCanBeMuted) { 2783c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 2784f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2785f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 2787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mMuteCount[stream]++; 2788f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2789f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 27903cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("setStreamMute() unmuting non muted stream!"); 2791f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 2792f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2793f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (--outputDesc->mMuteCount[stream] == 0) { 2794c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 2795c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent streamDesc.getVolumeIndex((audio_devices_t)device), 2796c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2797c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 2798c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs); 2799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2800f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2801f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2802f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2803f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, bool stateChange) 2804f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2805f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if the stream pertains to sonification strategy and we are in call we must 2806f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // mute the stream if it is low visibility. If it is high visibility, we must play a tone 2807f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // in the device used for phone strategy and play the tone if the selected device does not 2808f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // interfere with the device used for phone strategy 2809f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 2810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // many times as there are active tracks on the output 281112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 281212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if ((stream_strategy == STRATEGY_SONIFICATION) || 281312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { 2814b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 28156a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 2816f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, starting, outputDesc->mDevice, stateChange); 2817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream]) { 2818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int muteCount = 1; 2819f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stateChange) { 2820f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin muteCount = outputDesc->mRefCount[stream]; 2821f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2822f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) { 28236a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 2824f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 2825b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 2826f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2827f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 28286a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility"); 28295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->device() & 28305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) { 28316a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 2832f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 2833b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 2834f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2835f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2836f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (starting) { 2837f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL); 2838f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2839f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->stopTone(); 2840f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2841f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2842f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2843f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2844f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isInCall() 2847f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return isStateInCall(mPhoneState); 2849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2850f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2851f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStateInCall(int state) { 2852f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((state == AudioSystem::MODE_IN_CALL) || 2853f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (state == AudioSystem::MODE_IN_COMMUNICATION)); 2854f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2855f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 285670c236c9290732782d5267935af1475b8d5ae602Eric Laurentbool AudioPolicyManagerBase::needsDirectOuput(audio_stream_type_t stream, 285770c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 285870c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_format_t format, 285970c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_channel_mask_t channelMask, 28600977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags, 286170c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_devices_t device) 2862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2863f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) || 2864b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (format != 0 && !AudioSystem::isLinearPCM(format))); 2865f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2866f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2867f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsCpuLoad() 2868f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2869f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_CPU_LOAD; 2870f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2871f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2872f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsMemory() 2873f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2874f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_MEMORY; 2875f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2876f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2877f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioOutputDescriptor class implementation 2878f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2879b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric LaurentAudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor( 28805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const IOProfile *profile) 288170c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mId(0), mSamplingRate(0), mFormat((audio_format_t)0), 288270c236c9290732782d5267935af1475b8d5ae602Eric Laurent mChannelMask((audio_channel_mask_t)0), mLatency(0), 28830977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent mFlags((audio_output_flags_t)0), mDevice((audio_devices_t)0), 2884f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mOutput1(0), mOutput2(0), mProfile(profile) 2885f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2886f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // clear usage count for all stream types 2887f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 2888f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[i] = 0; 2889f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurVolume[i] = -1.0; 2890f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mMuteCount[i] = 0; 2891f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStopTime[i] = 0; 2892f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 28933cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile != NULL) { 28943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mSamplingRate = profile->mSamplingRates[0]; 28953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mFormat = profile->mFormats[0]; 28963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mChannelMask = profile->mChannelMasks[0]; 28973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mFlags = profile->mFlags; 28983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 2899f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2900f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2901f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::device() 2902f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2903f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 2904f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 2905f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2906f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return mDevice; 2907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 29105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::latency() 29115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 29125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isDuplicated()) { 29135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 29145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 29155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return mLatency; 29165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 29175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 29185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 29195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::sharesHwModuleWith( 29205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const AudioOutputDescriptor *outputDesc) 29215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 29225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isDuplicated()) { 29235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 29245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (outputDesc->isDuplicated()){ 29255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2); 29265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 292770c236c9290732782d5267935af1475b8d5ae602Eric Laurent return (mProfile->mModule == outputDesc->mProfile->mModule); 29285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 29295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 29305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2931f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta) 2932f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // forward usage count change to attached outputs 2934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 2935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput1->changeRefCount(stream, delta); 2936f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput2->changeRefCount(stream, delta); 2937f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2938f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((delta + (int)mRefCount[stream]) < 0) { 293964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]); 2940f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] = 0; 2941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 2942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2943f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] += delta; 29446a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 2945f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2946f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2947f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::refCount() 2948f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2949f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t refcount = 0; 2950f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 2951f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin refcount += mRefCount[i]; 2952f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2953f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return refcount; 2954f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2955f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2956f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::strategyRefCount(routing_strategy strategy) 2957f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2958f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t refCount = 0; 2959f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 2960f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)i) == strategy) { 2961f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin refCount += mRefCount[i]; 2962f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2963f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2964f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return refCount; 2965f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2966f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2967f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::supportedDevices() 2968b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 2969b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (isDuplicated()) { 2970f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 2971b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 2972b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mProfile->mSupportedDevices ; 2973b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2974b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 2975b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2976f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd) 2977f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2978f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 2979f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 2980f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 2981f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2982f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 2983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 2985f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 298670c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 2987f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 2989f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2990f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 2991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2992f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", device()); 2993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2994f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 2995f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2996f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 2997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 2998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2999f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3000f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3001f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3002f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3003f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3004f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3005f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioInputDescriptor class implementation 3006f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 30075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor(const IOProfile *profile) 300870c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mSamplingRate(0), mFormat((audio_format_t)0), mChannelMask((audio_channel_mask_t)0), 300970c236c9290732782d5267935af1475b8d5ae602Eric Laurent mDevice((audio_devices_t)0), mRefCount(0), 30105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mInputSource(0), mProfile(profile) 3011f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3012f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3013f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3014f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd) 3015f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3016f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 3017f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 3018f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 3019f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3020f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 3021f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3022f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 3023f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 302470c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 3025f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3026f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 3027f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3028f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 3029f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3030f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3031f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3032f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3033f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3034f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3035f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- StreamDescriptor class implementation 3036f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3037c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric LaurentAudioPolicyManagerBase::StreamDescriptor::StreamDescriptor() 3038c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 3039c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 3040c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 3041c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 3042c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3043c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentint AudioPolicyManagerBase::StreamDescriptor::getVolumeIndex(audio_devices_t device) 3044c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 3045c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AudioPolicyManagerBase::getDeviceForVolume(device); 3046c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 3047c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 3048c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 3049c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 3050c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return mIndexCur.valueFor(device); 3051c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 3052c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3053c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::StreamDescriptor::dump(int fd) 3054f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3055c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent const size_t SIZE = 256; 3056c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent char buffer[SIZE]; 3057c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent String8 result; 3058c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3059c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 3060c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 3061c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 3062c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 3063c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 3064c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.keyAt(i), 3065c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.valueAt(i)); 3066c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 3067c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 3068c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append("\n"); 3069c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3070c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent write(fd, result.string(), result.size()); 3071f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3072f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3073f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- EffectDescriptor class implementation 3074f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3075f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::EffectDescriptor::dump(int fd) 3076f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3077f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 3078f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 3079f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 3080f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 30811c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 3082f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3083f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 3084f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3085f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Session: %d\n", mSession); 3086f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 3088f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3089582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 3090582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent result.append(buffer); 3091f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3092f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3093f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3095f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 30965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// --- IOProfile class implementation 30975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 309870c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::HwModule::HwModule(const char *name) 309970c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0) 310070c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 310170c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 310270c236c9290732782d5267935af1475b8d5ae602Eric Laurent 310370c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::HwModule::~HwModule() 310470c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 310570c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 310670c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mOutputProfiles[i]; 310770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 310870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 310970c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mInputProfiles[i]; 311070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 311170c236c9290732782d5267935af1475b8d5ae602Eric Laurent free((void *)mName); 311270c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 311370c236c9290732782d5267935af1475b8d5ae602Eric Laurent 311470c236c9290732782d5267935af1475b8d5ae602Eric Laurentvoid AudioPolicyManagerBase::HwModule::dump(int fd) 311570c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 311670c236c9290732782d5267935af1475b8d5ae602Eric Laurent const size_t SIZE = 256; 311770c236c9290732782d5267935af1475b8d5ae602Eric Laurent char buffer[SIZE]; 311870c236c9290732782d5267935af1475b8d5ae602Eric Laurent String8 result; 311970c236c9290732782d5267935af1475b8d5ae602Eric Laurent 312070c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - name: %s\n", mName); 312170c236c9290732782d5267935af1475b8d5ae602Eric Laurent result.append(buffer); 312270c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 312370c236c9290732782d5267935af1475b8d5ae602Eric Laurent result.append(buffer); 312470c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, result.string(), result.size()); 312570c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mOutputProfiles.size()) { 312670c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, " - outputs:\n", sizeof(" - outputs:\n")); 312770c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 3128599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " output %d:\n", i); 3129599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent write(fd, buffer, strlen(buffer)); 313070c236c9290732782d5267935af1475b8d5ae602Eric Laurent mOutputProfiles[i]->dump(fd); 313170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 313270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 313370c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mInputProfiles.size()) { 313470c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, " - inputs:\n", sizeof(" - inputs:\n")); 313570c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 3136599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " input %d:\n", i); 3137599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent write(fd, buffer, strlen(buffer)); 313870c236c9290732782d5267935af1475b8d5ae602Eric Laurent mInputProfiles[i]->dump(fd); 313970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 314070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 314170c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 314270c236c9290732782d5267935af1475b8d5ae602Eric Laurent 314370c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::IOProfile::IOProfile(HwModule *module) 31440977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent : mFlags((audio_output_flags_t)0), mModule(module) 31455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 31465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 31475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 31485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::IOProfile::~IOProfile() 31495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 315070c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 315170c236c9290732782d5267935af1475b8d5ae602Eric Laurent 315270c236c9290732782d5267935af1475b8d5ae602Eric Laurent// checks if the IO profile is compatible with specified parameters. By convention a value of 0 315370c236c9290732782d5267935af1475b8d5ae602Eric Laurent// means a parameter is don't care 315470c236c9290732782d5267935af1475b8d5ae602Eric Laurentbool AudioPolicyManagerBase::IOProfile::isCompatibleProfile(audio_devices_t device, 315570c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 315670c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t format, 315770c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 31580977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags) const 315970c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 316070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if ((mSupportedDevices & device) != device) { 316170c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 316270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 316370c236c9290732782d5267935af1475b8d5ae602Eric Laurent if ((mFlags & flags) != flags) { 316470c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 316570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 316670c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (samplingRate != 0) { 316770c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 316870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mSamplingRates.size(); i++) 316970c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 317070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mSamplingRates[i] == samplingRate) { 317170c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 317270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 317370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 317470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mSamplingRates.size()) { 317570c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 317670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 317770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 317870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (format != 0) { 317970c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 318070c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mFormats.size(); i++) 318170c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 318270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mFormats[i] == format) { 318370c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 318470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 318570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 318670c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mFormats.size()) { 318770c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 318870c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 318970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 319070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (channelMask != 0) { 319170c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 319270c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mChannelMasks.size(); i++) 319370c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 319470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mChannelMasks[i] == channelMask) { 319570c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 319670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 319770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 319870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mChannelMasks.size()) { 319970c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 320070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 320170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 320270c236c9290732782d5267935af1475b8d5ae602Eric Laurent return true; 32035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 32045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::IOProfile::dump(int fd) 32065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 32075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const size_t SIZE = 256; 32085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char buffer[SIZE]; 32095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent String8 result; 32105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 321170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - sampling rates: "); 32125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 32135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 32145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent snprintf(buffer, SIZE, "%d", mSamplingRates[i]); 32155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 32165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mSamplingRates.size() - 1) ? "\n" : ", "); 32175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 321970c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - channel masks: "); 32205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 32215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 32225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent snprintf(buffer, SIZE, "%04x", mChannelMasks[i]); 32235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 32245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mChannelMasks.size() - 1) ? "\n" : ", "); 32255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 322770c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - formats: "); 32285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 32295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 32305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent snprintf(buffer, SIZE, "%d", mFormats[i]); 32315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 32325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mFormats.size() - 1) ? "\n" : ", "); 32335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 323570c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - devices: %04x\n", mSupportedDevices); 32365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 323770c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - flags: %04x\n", mFlags); 32385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 32395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, result.string(), result.size()); 32415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 32425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// --- audio_policy.conf file parsing 32445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentstruct StringToEnum { 32465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *name; 32475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t value; 32485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 32495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#define STRING_TO_ENUM(string) { #string, string } 32515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 32525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sDeviceNameToEnumTable[] = { 32545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE), 32555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER), 32565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET), 32575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE), 32585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO), 32595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP), 32605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL), 32615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET), 3262599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET), 3263599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE), 3264599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY), 3265599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB), 32665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), 32675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), 32685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET), 32695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL), 32705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL), 32715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC), 32725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 32735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sFlagNameToEnumTable[] = { 32750977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT), 32760977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), 3277b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), 3278b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), 32795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 32805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sFormatNameToEnumTable[] = { 32825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT), 32835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT), 32845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_MP3), 32855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AAC), 32865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_VORBIS), 32875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 32885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sOutChannelsNameToEnumTable[] = { 32905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO), 32915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 32925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 32935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 32945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 32955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sInChannelsNameToEnumTable[] = { 32975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), 32985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), 32995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 33005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentuint32_t AudioPolicyManagerBase::stringToEnum(const struct StringToEnum *table, 33035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent size_t size, 33045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *name) 33055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 33065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < size; i++) { 33075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(table[i].name, name) == 0) { 33085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("stringToEnum() found %s", table[i].name); 33095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return table[i].value; 33105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 33135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 33145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33150977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurentaudio_output_flags_t AudioPolicyManagerBase::parseFlagNames(char *name) 33165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 33175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t flag = 0; 33185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // it is OK to cast name to non const here as we are not going to use it after 33205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // strtok() modifies it 33215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *flagName = strtok(name, "|"); 33225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (flagName != NULL) { 33235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strlen(flagName) != 0) { 33245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flag |= stringToEnum(sFlagNameToEnumTable, 33255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sFlagNameToEnumTable), 33265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flagName); 33275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flagName = strtok(NULL, "|"); 33295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33300977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent return (audio_output_flags_t)flag; 33315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 33325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_devices_t AudioPolicyManagerBase::parseDeviceNames(char *name) 33345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 33355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t device = 0; 33365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *devName = strtok(name, "|"); 33385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (devName != NULL) { 33395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strlen(devName) != 0) { 33405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device |= stringToEnum(sDeviceNameToEnumTable, 33415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 33425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devName); 33435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devName = strtok(NULL, "|"); 33455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return (audio_devices_t)device; 33475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 33485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadSamplingRates(char *name, IOProfile *profile) 33505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 33515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *str = strtok(name, "|"); 33525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling 33543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // rates should be read from the output stream after it is opened for the first time 33553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 33563cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.add(0); 33573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 33583cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 33593cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 33605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 33615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t rate = atoi(str); 33625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (rate != 0) { 33635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadSamplingRates() adding rate %d", rate); 33645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSamplingRates.add(rate); 33655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 33675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 33695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 33705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadFormats(char *name, IOProfile *profile) 33725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 33735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *str = strtok(name, "|"); 33745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33753cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mFormats indicates the supported formats 33763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // should be read from the output stream after it is opened for the first time 33773cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 33783cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mFormats.add((audio_format_t)0); 33793cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 33803cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 33813cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 33825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 33835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable, 33845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 33855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str); 33865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (format != 0) { 33875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mFormats.add(format); 33885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 33905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 33925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 33935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadInChannels(char *name, IOProfile *profile) 33955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 33965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *str = strtok(name, "|"); 33975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInChannels() %s", name); 33993cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 34003cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 34013cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.add((audio_channel_mask_t)0); 34023cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 34033cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 34043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 34055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 34065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_channel_mask_t channelMask = 34075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 34085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 34095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str); 34105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (channelMask != 0) { 34115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInChannels() adding channelMask %04x", channelMask); 34125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mChannelMasks.add(channelMask); 34135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 34155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 34175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 34185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadOutChannels(char *name, IOProfile *profile) 34205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 34215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *str = strtok(name, "|"); 34223cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 34233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("loadOutChannels() %s", name); 34243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 34253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mChannelMasks indicates the supported channel 34263cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // masks should be read from the output stream after it is opened for the first time 34273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 34283cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.add((audio_channel_mask_t)0); 34293cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 34303cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 34315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 34333cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_channel_mask_t channelMask = 34343cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 34353cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 34363cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent str); 34375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (channelMask != 0) { 34385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mChannelMasks.add(channelMask); 34395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 34415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 34435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 34445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 344570c236c9290732782d5267935af1475b8d5ae602Eric Laurentstatus_t AudioPolicyManagerBase::loadInput(cnode *root, HwModule *module) 34465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 34475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = root->first_child; 34485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = new IOProfile(module); 34505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 34525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 34535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadSamplingRates((char *)node->value, profile); 34545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 34555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadFormats((char *)node->value, profile); 34565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 34575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadInChannels((char *)node->value, profile); 34585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 34595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices = parseDeviceNames((char *)node->value); 34605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 34625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSupportedDevices == (audio_devices_t)0, 34645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported devices"); 34655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 34665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported channel masks"); 34675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 34685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported sampling rates"); 34695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 34705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported formats"); 34715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if ((profile->mSupportedDevices != (audio_devices_t)0) && 34725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mChannelMasks.size() != 0) && 34735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mSamplingRates.size() != 0) && 34745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mFormats.size() != 0)) { 34755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInput() adding input mSupportedDevices %04x", profile->mSupportedDevices); 34775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 347870c236c9290732782d5267935af1475b8d5ae602Eric Laurent module->mInputProfiles.add(profile); 34795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 34805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 34815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent delete profile; 34825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return BAD_VALUE; 34835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 34855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 348670c236c9290732782d5267935af1475b8d5ae602Eric Laurentstatus_t AudioPolicyManagerBase::loadOutput(cnode *root, HwModule *module) 34875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 34885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = root->first_child; 34895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = new IOProfile(module); 34915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 34935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 34945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadSamplingRates((char *)node->value, profile); 34955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 34965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadFormats((char *)node->value, profile); 34975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 34985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadOutChannels((char *)node->value, profile); 34995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 35005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices = parseDeviceNames((char *)node->value); 35015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FLAGS_TAG) == 0) { 35025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mFlags = parseFlagNames((char *)node->value); 35035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 35055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSupportedDevices == (audio_devices_t)0, 35075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported devices"); 35085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 35095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported channel masks"); 35105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 35115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported sampling rates"); 35125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 35135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported formats"); 35145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if ((profile->mSupportedDevices != (audio_devices_t)0) && 35155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mChannelMasks.size() != 0) && 35165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mSamplingRates.size() != 0) && 35175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mFormats.size() != 0)) { 35185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadOutput() adding output mSupportedDevices %04x, mFlags %04x", 35205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices, profile->mFlags); 35215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 352270c236c9290732782d5267935af1475b8d5ae602Eric Laurent module->mOutputProfiles.add(profile); 35235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 35245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 35255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent delete profile; 35265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return BAD_VALUE; 35275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadHwModule(cnode *root) 35315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 35325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, OUTPUTS_TAG); 35335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status_t status = NAME_NOT_FOUND; 353470c236c9290732782d5267935af1475b8d5ae602Eric Laurent 353570c236c9290732782d5267935af1475b8d5ae602Eric Laurent HwModule *module = new HwModule(root->name); 353670c236c9290732782d5267935af1475b8d5ae602Eric Laurent 35375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node != NULL) { 35385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_A2DP) == 0) { 35395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mHasA2dp = true; 3540599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } else if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_USB) == 0) { 3541599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mHasUsb = true; 35425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 3543599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent 35445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 35455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 35465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModule() loading output %s", node->name); 354770c236c9290732782d5267935af1475b8d5ae602Eric Laurent status_t tmpStatus = loadOutput(node, module); 35485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 35495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status = tmpStatus; 35505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 35525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = config_find(root, INPUTS_TAG); 35555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node != NULL) { 35565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 35575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 35585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModule() loading input %s", node->name); 355970c236c9290732782d5267935af1475b8d5ae602Eric Laurent status_t tmpStatus = loadInput(node, module); 35605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 35615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status = tmpStatus; 35625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 35645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NO_ERROR) { 356770c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules.add(module); 356870c236c9290732782d5267935af1475b8d5ae602Eric Laurent } else { 356970c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete module; 35705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadHwModules(cnode *root) 35745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 35755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); 35765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node == NULL) { 35775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 35785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 35815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 35825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModules() loading module %s", node->name); 35835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadHwModule(node); 35845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 35855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadGlobalConfig(cnode *root) 35895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 35905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, GLOBAL_CONFIG_TAG); 35915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node == NULL) { 35925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 35935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 35955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 35965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { 35975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAttachedOutputDevices = parseDeviceNames((char *)node->value); 35985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(mAttachedOutputDevices == 0, "loadGlobalConfig() no attached output devices"); 35995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mAttachedOutputDevices %04x", mAttachedOutputDevices); 36005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { 36015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mDefaultOutputDevice = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable, 36025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 36035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (char *)node->value); 36045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(mDefaultOutputDevice == 0, "loadGlobalConfig() default device not specified"); 36055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mDefaultOutputDevice %04x", mDefaultOutputDevice); 36065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { 36075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAvailableInputDevices = parseDeviceNames((char *)node->value); 36085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mAvailableInputDevices %04x", mAvailableInputDevices); 36095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 36115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 36135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentstatus_t AudioPolicyManagerBase::loadAudioPolicyConfig(const char *path) 36155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 36165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *root; 36175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *data; 36185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent data = (char *)load_file(path, NULL); 36205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (data == NULL) { 36215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return -ENODEV; 36225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent root = config_node("", ""); 36245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent config_load(root, data); 36255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadGlobalConfig(root); 36275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadHwModules(root); 36285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent config_free(root); 36305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent free(root); 36315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent free(data); 36325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36335ec145df7708564d385fd3fb764085321cf4c253Dima Zavin ALOGI("loadAudioPolicyConfig() loaded %s\n", path); 36345ec145df7708564d385fd3fb764085321cf4c253Dima Zavin 36355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 36365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 3637f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3638739022f26a7127ba76a98dda65411496086114a7Dima Zavinvoid AudioPolicyManagerBase::defaultAudioPolicyConfig(void) 3639739022f26a7127ba76a98dda65411496086114a7Dima Zavin{ 3640739022f26a7127ba76a98dda65411496086114a7Dima Zavin HwModule *module; 3641739022f26a7127ba76a98dda65411496086114a7Dima Zavin IOProfile *profile; 3642739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3643739022f26a7127ba76a98dda65411496086114a7Dima Zavin mDefaultOutputDevice = AUDIO_DEVICE_OUT_SPEAKER; 3644739022f26a7127ba76a98dda65411496086114a7Dima Zavin mAttachedOutputDevices = AUDIO_DEVICE_OUT_SPEAKER; 3645739022f26a7127ba76a98dda65411496086114a7Dima Zavin mAvailableInputDevices = AUDIO_DEVICE_IN_BUILTIN_MIC; 3646739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3647739022f26a7127ba76a98dda65411496086114a7Dima Zavin module = new HwModule("primary"); 3648739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3649739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile = new IOProfile(module); 3650739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSamplingRates.add(44100); 3651739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 3652739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO); 3653739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSupportedDevices = AUDIO_DEVICE_OUT_SPEAKER; 3654739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY; 3655739022f26a7127ba76a98dda65411496086114a7Dima Zavin module->mOutputProfiles.add(profile); 3656739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3657739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile = new IOProfile(module); 3658739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSamplingRates.add(8000); 3659739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 3660739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO); 3661739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSupportedDevices = AUDIO_DEVICE_IN_BUILTIN_MIC; 3662739022f26a7127ba76a98dda65411496086114a7Dima Zavin module->mInputProfiles.add(profile); 3663739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3664739022f26a7127ba76a98dda65411496086114a7Dima Zavin mHwModules.add(module); 3665739022f26a7127ba76a98dda65411496086114a7Dima Zavin} 3666f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3667f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin}; // namespace android 3668