AudioPolicyManagerBase.cpp revision e92d623811f3fd3e7cc5e5dd8bc93c0c0a8fdf50
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 276d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi// A device mask for all audio input devices that are considered "virtual" when evaluating 286d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi// active inputs in getActiveInput() 296d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL AUDIO_DEVICE_IN_REMOTE_SUBMIX 30dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi// A device mask for all audio output devices that are considered "remote" when evaluating 31dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi// active output devices in isStreamActiveRemotely() 32dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX 336d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi 34f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <utils/Log.h> 35f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <hardware_legacy/AudioPolicyManagerBase.h> 361c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent#include <hardware/audio_effect.h> 3708b014d9e509c9163db6b33a63852e73db4d07ccEric Laurent#include <hardware/audio.h> 38f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <math.h> 395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#include <hardware_legacy/audio_policy_conf.h> 40f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 41e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinnamespace android_audio_legacy { 42f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 43f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 44f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyInterface implementation 45f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 46f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 47f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 48c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivistatus_t AudioPolicyManagerBase::setDeviceConnectionState(audio_devices_t device, 49f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state, 50f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 51f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 523cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent SortedVector <audio_io_handle_t> outputs; 53f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 546a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); 55f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 56f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // connect/disconnect only 1 device at a time 57ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; 58f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 59f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { 605efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid address: %s", device_address); 61f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 62f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 63f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 64f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output devices 65c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_output_device(device)) { 66f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 67c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (!mHasA2dp && audio_is_a2dp_device(device)) { 6848387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("setDeviceConnectionState() invalid A2DP device: %x", device); 69f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 70f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 71c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (!mHasUsb && audio_is_usb_device(device)) { 7248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("setDeviceConnectionState() invalid USB audio device: %x", device); 7348387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi return BAD_VALUE; 7448387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 7548387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi if (!mHasRemoteSubmix && audio_is_remote_submix_device((audio_devices_t)device)) { 7648387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("setDeviceConnectionState() invalid remote submix audio device: %x", device); 77599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent return BAD_VALUE; 78599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 79f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 80c952527e6f89d5427881462823514be9d79f13e6Eric Laurent // save a copy of the opened output descriptors before any output is opened or closed 81c952527e6f89d5427881462823514be9d79f13e6Eric Laurent // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() 82c952527e6f89d5427881462823514be9d79f13e6Eric Laurent mPreviousOutputs = mOutputs; 83f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 84f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 85f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device connection 86f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: 87f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableOutputDevices & device) { 8864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %x", device); 89f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 90f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 916a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() connecting device %x", device); 92f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 93c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) { 943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return INVALID_OPERATION; 953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %d outputs", 973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.size()); 98f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // register new device as available 99f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device); 100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1013cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!outputs.isEmpty()) { 1023cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8 paramStr; 103c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (mHasA2dp && audio_is_a2dp_device(device)) { 1043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle A2DP device connection 1053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioParameter param; 1063cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), String8(device_address)); 1073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent paramStr = param.toString(); 1083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 1093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mA2dpSuspended = false; 110c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (audio_is_bluetooth_sco_device(device)) { 1113cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle SCO device connection 1123cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 113c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mHasUsb && audio_is_usb_device(device)) { 1143cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle USB device connection 1153cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mUsbCardAndDevice = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 1163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent paramStr = mUsbCardAndDevice; 1173cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 11848387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi // not currently handling multiple simultaneous submixes: ignoring remote submix 11948387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi // case and address 1203cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!paramStr.isEmpty()) { 1213cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t i = 0; i < outputs.size(); i++) { 1223cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mpClientInterface->setParameters(outputs[i], paramStr); 1233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 125f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 126f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 127f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device disconnection 128f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 129f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableOutputDevices & device)) { 13064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %x", device); 131f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 132f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 133f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1346a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() disconnecting device %x", device); 135f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // remove device from available output devices 136f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device); 137f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 138c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi checkOutputsForDevice(device, state, outputs); 139c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (mHasA2dp && audio_is_a2dp_device(device)) { 1403cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle A2DP device disconnection 141b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpDeviceAddress = ""; 142b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpSuspended = false; 143c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (audio_is_bluetooth_sco_device(device)) { 1443cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle SCO device disconnection 145b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mScoDeviceAddress = ""; 146c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mHasUsb && audio_is_usb_device(device)) { 1473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle USB device disconnection 148599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mUsbCardAndDevice = ""; 149f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 15048387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi // not currently handling multiple simultaneous submixes: ignoring remote submix 15148387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi // case and address 152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 1555efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 161b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // outputs must be closed after checkOutputForAllStrategies() is executed 1623cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!outputs.isEmpty()) { 1633cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t i = 0; i < outputs.size(); i++) { 1643cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // close unused outputs after device disconnection or direct outputs that have been 1653cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // opened by checkOutputsForDevice() to query dynamic parameters 1663cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if ((state == AudioSystem::DEVICE_STATE_UNAVAILABLE) || 1673cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (mOutputs.valueFor(outputs[i])->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) { 1683cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent closeOutput(outputs[i]); 1693cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1703cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 171f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 173c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 1745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1752c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent // do not force device change on duplicated output because if device is 0, it will 1762c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent // also force a device 0 for the two outputs it is duplicated to which may override 1772c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent // a valid device selection on those outputs. 17876e97d3950f2654adbb0a415218b6d048200c395Eric Laurent setOutputDevice(mOutputs.keyAt(i), 17976e97d3950f2654adbb0a415218b6d048200c395Eric Laurent getNewDevice(mOutputs.keyAt(i), true /*fromCache*/), 1802c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent !mOutputs.valueAt(i)->isDuplicated(), 18176e97d3950f2654adbb0a415218b6d048200c395Eric Laurent 0); 1825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 183f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 184c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET) { 185c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_WIRED_HEADSET; 186c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO || 187c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET || 188c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 189c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input devices 195c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_input_device(device)) { 196f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 198f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device connection 200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: { 201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableInputDevices & device) { 20264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %d", device); 203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 205ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableInputDevices = mAvailableInputDevices | (device & ~AUDIO_DEVICE_BIT_IN); 206f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device disconnection 210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 211f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableInputDevices & device)) { 21264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %d", device); 213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAvailableInputDevices = (audio_devices_t) (mAvailableInputDevices & ~device); 216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 2195efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 222f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 226f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 227ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { 2286a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() changing device from %x to %x for input %d", 229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() invalid device: %x", device); 241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 244c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel TriviAudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(audio_devices_t device, 245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE; 248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 address = String8(device_address); 249c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_output_device(device)) { 250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableOutputDevices) { 251c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_a2dp_device(device) && 2525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (!mHasA2dp || (address != "" && mA2dpDeviceAddress != address))) { 253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 255c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_bluetooth_sco_device(device) && 256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin address != "" && mScoDeviceAddress != address) { 257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 259c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_usb_device(device) && 260599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent (!mHasUsb || (address != "" && mUsbCardAndDevice != address))) { 26148387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("getDeviceConnectionState() invalid device: %x", device); 26248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi return state; 26348387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 26448387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi if (audio_is_remote_submix_device((audio_devices_t)device) && !mHasRemoteSubmix) { 265599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent return state; 266599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 267f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 269c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (audio_is_input_device(device)) { 270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableInputDevices) { 271f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 274f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 275f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 277f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setPhoneState(int state) 279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2806a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() state %d", state); 281ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent audio_devices_t newDevice = AUDIO_DEVICE_NONE; 282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state < 0 || state >= AudioSystem::NUM_MODES) { 28364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() invalid state %d", state); 284f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == mPhoneState ) { 28864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() setting same state %d", state); 289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if leaving call state, handle special case of active streams 293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 2956a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 297f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, true); 298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store previous phone state for management of sonification strategy below 302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int oldState = mPhoneState; 303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mPhoneState = state; 304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool force = false; 305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // are we entering or starting a call 307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isStateInCall(oldState) && isStateInCall(state)) { 3086a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Entering call in setPhoneState()"); 309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when starting a call 310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(oldState) && !isStateInCall(state)) { 3136a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Exiting call in setPhoneState()"); 314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when exiting a call 315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(state) && (state != oldState)) { 3186a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when switching between telephony and VoIP 320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check for device and output changes triggered by new phone state 3255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/); 326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 328c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 330b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when ending call 333f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 334ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) { 335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin newDevice = hwOutputDesc->device(); 336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int delayMs = 0; 339772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani if (isStateInCall(state)) { 34080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent nsecs_t sysTime = systemTime(); 341772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani for (size_t i = 0; i < mOutputs.size(); i++) { 342772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani AudioOutputDescriptor *desc = mOutputs.valueAt(i); 34380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent // mute media and sonification strategies and delay device switch by the largest 34480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent // latency of any output where either strategy is active. 34580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent // This avoid sending the ring tone or music tail into the earpiece or headset. 34680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if ((desc->isStrategyActive(STRATEGY_MEDIA, 34780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 34880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime) || 34980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent desc->isStrategyActive(STRATEGY_SONIFICATION, 35080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 35180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime)) && 35280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent (delayMs < (int)desc->mLatency*2)) { 35380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent delayMs = desc->mLatency*2; 354772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani } 35580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); 35680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, 35780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); 35880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i)); 35980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS, 36080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/)); 361772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani } 362772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani } 363772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani 364f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // change routing is necessary 365b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setOutputDevice(mPrimaryOutput, newDevice, force, delayMs); 366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if entering in call state, handle special case of active streams 368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(state)) { 3706a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 371f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 372f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, true, true); 373f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == AudioSystem::MODE_RINGTONE && 378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = true; 380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 381f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = false; 382f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) 386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3876a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool forceVolumeReeval = false; 390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(usage) { 391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_COMMUNICATION: 392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO && 393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 39464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_MEDIA: 401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP && 402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 4041afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE && 40531363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi config != AudioSystem::FORCE_NO_BT_A2DP) { 40664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_RECORD: 412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY && 413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 41464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_DOCK: 420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK && 421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_BT_DESK_DOCK && 422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_DIGITAL_DOCK) { 42564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 430738207def5f691d605ae33d041116829a74513a9Eric Laurent case AudioSystem::FOR_SYSTEM: 431738207def5f691d605ae33d041116829a74513a9Eric Laurent if (config != AudioSystem::FORCE_NONE && 432738207def5f691d605ae33d041116829a74513a9Eric Laurent config != AudioSystem::FORCE_SYSTEM_ENFORCED) { 433738207def5f691d605ae33d041116829a74513a9Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config); 434738207def5f691d605ae33d041116829a74513a9Eric Laurent } 435738207def5f691d605ae33d041116829a74513a9Eric Laurent forceVolumeReeval = true; 436738207def5f691d605ae33d041116829a74513a9Eric Laurent mForceUse[usage] = config; 437738207def5f691d605ae33d041116829a74513a9Eric Laurent break; 438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 43964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid usage %d", usage); 440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // check for device and output changes triggered by new force usage 444f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 446c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 4475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 4485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 4495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, true /*fromCache*/); 450ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE)); 451ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) { 4525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent applyStreamVolumes(output, newDevice, 0, true); 4535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 454f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 455f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 4595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 460ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { 4616a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() changing device from %x to %x for input %d", 462f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 464f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 465f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 466f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 470f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage) 473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mForceUse[usage]; 475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setSystemProperty(const char* property, const char* value) 478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 4796a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setSystemProperty() property %s, value %s", property, value); 480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4823cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric LaurentAudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getProfileForDirectOutput( 4833cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_devices_t device, 48470c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 48570c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t format, 48670c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 4870977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags) 48870c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 48970c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 49070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 49170c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 49270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 49370c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { 4943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; 4953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 4963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent channelMask, 4973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AUDIO_OUTPUT_FLAG_DIRECT)) { 4983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (mAvailableOutputDevices & profile->mSupportedDevices) { 4993cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return mHwModules[i]->mOutputProfiles[j]; 5003cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 50170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 50270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 50370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 50470c236c9290732782d5267935af1475b8d5ae602Eric Laurent return 0; 50570c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 50670c236c9290732782d5267935af1475b8d5ae602Eric Laurent 507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream, 508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 509f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 51070c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 511f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::output_flags flags) 512f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 513f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t output = 0; 514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t latency = 0; 515f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); 5165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 51770c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getOutput() stream %d, samplingRate %d, format %d, channelMask %x, flags %x", 51870c236c9290732782d5267935af1475b8d5ae602Eric Laurent stream, samplingRate, format, channelMask, flags); 519f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 520f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 521f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mCurOutput != 0) { 52270c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", 523f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 524f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 525f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput] == 0) { 5266a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() opening test output"); 5273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 528f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = mTestDevice; 529f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = mTestSamplingRate; 530f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFormat = mTestFormat; 53170c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mChannelMask = mTestChannels; 532f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = mTestLatencyMs; 5330977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent outputDesc->mFlags = (audio_output_flags_t)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0); 534f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 53570c236c9290732782d5267935af1475b8d5ae602Eric Laurent mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice, 536f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 537f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 53870c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 539f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 540f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 541f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput]) { 542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"),mCurOutput); 544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(mTestOutputs[mCurOutput], outputDesc); 546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 547f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mTestOutputs[mCurOutput]; 549f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 550f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 551f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 552f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a direct output if required by specified parameters 5533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = getProfileForDirectOutput(device, 5543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent samplingRate, 5553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent format, 5563cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent channelMask, 5573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (audio_output_flags_t)flags); 5583cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile != NULL) { 5595a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent AudioOutputDescriptor *outputDesc = NULL; 560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5615a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 5625a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 5635a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (!desc->isDuplicated() && (profile == desc->mProfile)) { 5645a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc = desc; 5655a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent // reuse direct output if currently open and configured with same parameters 5665a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if ((samplingRate == outputDesc->mSamplingRate) && 5675a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent (format == outputDesc->mFormat) && 5685a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent (channelMask == outputDesc->mChannelMask)) { 5695a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc->mDirectOpenCount++; 5705a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent ALOGV("getOutput() reusing direct output %d", output); 5715a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent return mOutputs.keyAt(i); 5725a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 5735a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 5745a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 5755a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent // close direct output if currently open and configured with different parameters 5765a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (outputDesc != NULL) { 5775a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent closeOutput(outputDesc->mId); 5785a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 5795a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc = new AudioOutputDescriptor(profile); 580f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = device; 581f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = samplingRate; 58270c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mFormat = (audio_format_t)format; 58370c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mChannelMask = (audio_channel_mask_t)channelMask; 584f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = 0; 5853cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputDesc->mFlags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);; 586f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 587f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mStopTime[stream] = 0; 5885a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc->mDirectOpenCount = 1; 5893cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent output = mpClientInterface->openOutput(profile->mModule->mHandle, 59070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 591f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 592f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 59370c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 594f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 595f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 596f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5979f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi // only accept an output with the requested parameters 598f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == 0 || 599f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || 600f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != 0 && format != outputDesc->mFormat) || 60170c236c9290732782d5267935af1475b8d5ae602Eric Laurent (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { 6023cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," 6033cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent "format %d %d, channelMask %04x %04x", output, samplingRate, 6043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, 6053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputDesc->mChannelMask); 606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output != 0) { 607f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 608f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 609f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete outputDesc; 610f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 611f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 612f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(output, outputDesc); 6135a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent mPreviousOutputs = mOutputs; 6145a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent ALOGV("getOutput() returns new direct output %d", output); 615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 616f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 617f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6189f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi // ignoring channel mask due to downmix capability in mixer 6199f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi 620f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a non direct output 621f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 622f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // get which output is suitable for the specified stream. The actual routing change will happen 623f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when startOutput() will be called 624c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs); 625f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent output = selectOutput(outputs, flags); 627f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 62870c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d," 62970c236c9290732782d5267935af1475b8d5ae602Eric Laurent "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); 630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("getOutput() returns output %d", output); 6325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 633f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 635f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::selectOutput(const SortedVector<audio_io_handle_t>& outputs, 6375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioSystem::output_flags flags) 6385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 6395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // select one output among several that provide a path to a particular device or set of 6405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // devices (the list was previously build by getOutputsForDevice()). 6415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // The priority is as follows: 6425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 1: the output with the highest number of requested policy flags 6435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 2: the primary output 6445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 3: the first output in the list 6455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputs.size() == 0) { 6475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 6485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputs.size() == 1) { 6505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputs[0]; 6515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent int maxCommonFlags = 0; 6545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t outputFlags = 0; 6555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t outputPrimary = 0; 6565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 6585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]); 6595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!outputDesc->isDuplicated()) { 6605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent int commonFlags = (int)AudioSystem::popCount(outputDesc->mProfile->mFlags & flags); 6615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (commonFlags > maxCommonFlags) { 6625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputFlags = outputs[i]; 6635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent maxCommonFlags = commonFlags; 6645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); 6655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6660977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 6675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputPrimary = outputs[i]; 6685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputFlags != 0) { 6735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputFlags; 6745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputPrimary != 0) { 6765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputPrimary; 6775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputs[0]; 6805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 6815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 682f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, 683f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 684f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 685f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 6866a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 687f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 688f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 68964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startOutput() unknow output %d", output); 690f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 693f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 694f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // increment usage count for this stream on the requested output: 696f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE that the usage count is the same for duplicated output and hardware output which is 6975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // necessary for a correct control of hardware output routing by startOutput() and stopOutput() 698f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, 1); 699f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->mRefCount[stream] == 1) { 7015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 702b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent routing_strategy strategy = getStrategy(stream); 703b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent bool shouldWait = (strategy == STRATEGY_SONIFICATION) || 704b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent (strategy == STRATEGY_SONIFICATION_RESPECTFUL); 705b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t waitMs = 0; 7065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool force = false; 7075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 7085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 709b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (desc != outputDesc) { 710b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // force a device change if any other output is managed by the same hw 711b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // module and has a current device selection that differs from selected device. 712b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // In this case, the audio HAL must receive the new device selection so that it can 713b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // change the device currently selected by the other active output. 714b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (outputDesc->sharesHwModuleWith(desc) && 7155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent desc->device() != newDevice) { 716b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent force = true; 717b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 718b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // wait for audio on other active outputs to be presented when starting 719b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // a notification so that audio focus effect can propagate. 72042fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent uint32_t latency = desc->latency(); 72142fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { 72242fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent waitMs = latency; 723b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 7245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 726b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); 727f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // handle special case for sonification while in call 7295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isInCall()) { 7305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleIncallSonification(stream, true, false); 7315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 732c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 7335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // apply volume rules for current stream and device if necessary 7345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent checkAndSetVolume(stream, 735c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi mStreams[stream].getVolumeIndex(newDevice), 7365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent output, 7375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice); 73812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 7395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // update the outputs if starting an output with a stream that can affect notification 7405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // routing 7415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleNotificationRoutingForStream(stream); 742b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (waitMs > muteWaitMs) { 743b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent usleep((waitMs - muteWaitMs) * 2 * 1000); 744b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 7455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 746f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 747f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 748f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 750f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, 751f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 752f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 753f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7546a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 755f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 756f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 75764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() unknow output %d", output); 758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 760f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 761f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 762f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle special case for sonification while in call 764f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, false); 766f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 767f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 768f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream] > 0) { 769f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // decrement usage count of this stream on the output 770f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, -1); 771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store time at which the stream was stopped - see isStreamActive() 7725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->mRefCount[stream] == 0) { 7735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStopTime[stream] = systemTime(); 7745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 7755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // delay the device switch by twice the latency because stopOutput() is executed when 7765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // the track stop() command is received and at that time the audio track buffer can 7775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // still contain data that needs to be drained. The latency only covers the audio HAL 7785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // and kernel buffers. Also the latency does not always include additional delay in the 7795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // audio path (audio DSP, CODEC ...) 7805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); 7815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 7825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // force restoring the device selection on other active outputs if it differs from the 7835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // one being selected for this output 7845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 7855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(i); 7865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 7875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (curOutput != output && 78880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent desc->isActive() && 7895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->sharesHwModuleWith(desc) && 7905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice != desc->device()) { 7915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(curOutput, 7925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent getNewDevice(curOutput, false /*fromCache*/), 7935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent true, 7945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mLatency*2); 7955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // update the outputs if stopping one with a stream that can affect notification routing 7985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleNotificationRoutingForStream(stream); 799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 800f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 801f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 80264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() refcount is already 0 for output %d", output); 803f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 804f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 805f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 806f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 807f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output) 808f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8096a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseOutput() %d", output); 810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 811f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 81264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseOutput() releasing unknown output %d", output); 813f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 814f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 815f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 816f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int testIndex = testOutputIndex(output); 818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (testIndex != 0) { 819f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 82080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (outputDesc->isActive()) { 821f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 822f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(index); 823f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(output); 824f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[testIndex] = 0; 825f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 826f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 827f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 828f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 829f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 8305a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(index); 8315a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (desc->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) { 8325a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (desc->mDirectOpenCount <= 0) { 8335a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent ALOGW("releaseOutput() invalid open count %d for output %d", 8345a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent desc->mDirectOpenCount, output); 8355a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent return; 8365a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 8375a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (--desc->mDirectOpenCount == 0) { 8385a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent closeOutput(output); 8395a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 840f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 84112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 842f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 843f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 844f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource, 845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 84770c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::audio_in_acoustics acoustics) 849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 850f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t input = 0; 851f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device = getDeviceForInputSource(inputSource); 852f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 85370c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x", 85470c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputSource, samplingRate, format, channelMask, acoustics); 855f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 856ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 8575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW("getInput() could not find device for inputSource %d", inputSource); 858f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 859f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 860f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 861f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // adapt channel selection to input source 862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(inputSource) { 863f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 86470c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = AudioSystem::CHANNEL_IN_VOICE_UPLINK; 865f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 866f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 86770c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = AudioSystem::CHANNEL_IN_VOICE_DNLINK; 868f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 869f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 87070c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK); 871f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 872f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 873f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 874f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 875f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 8765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = getInputProfile(device, 8775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent samplingRate, 8785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent format, 87970c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask); 8805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (profile == NULL) { 8815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d," 88270c236c9290732782d5267935af1475b8d5ae602Eric Laurent "channelMask %04x", 88370c236c9290732782d5267935af1475b8d5ae602Eric Laurent device, samplingRate, format, channelMask); 88470c236c9290732782d5267935af1475b8d5ae602Eric Laurent return 0; 88570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 88670c236c9290732782d5267935af1475b8d5ae602Eric Laurent 88770c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (profile->mModule->mHandle == 0) { 8883cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); 8895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 8905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 8915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 8925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile); 893f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 894f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mInputSource = inputSource; 895f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = device; 896f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mSamplingRate = samplingRate; 89770c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputDesc->mFormat = (audio_format_t)format; 89870c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputDesc->mChannelMask = (audio_channel_mask_t)channelMask; 899f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 90070c236c9290732782d5267935af1475b8d5ae602Eric Laurent input = mpClientInterface->openInput(profile->mModule->mHandle, 90170c236c9290732782d5267935af1475b8d5ae602Eric Laurent &inputDesc->mDevice, 902f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mSamplingRate, 903f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mFormat, 90470c236c9290732782d5267935af1475b8d5ae602Eric Laurent &inputDesc->mChannelMask); 905f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 906f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // only accept input with the exact requested set of parameters 907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input == 0 || 908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != inputDesc->mSamplingRate) || 909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != inputDesc->mFormat) || 91070c236c9290732782d5267935af1475b8d5ae602Eric Laurent (channelMask != inputDesc->mChannelMask)) { 91170c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getInput() failed opening input: samplingRate %d, format %d, channelMask %d", 91270c236c9290732782d5267935af1475b8d5ae602Eric Laurent samplingRate, format, channelMask); 913f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input != 0) { 914f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 915f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 916f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete inputDesc; 917f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 918f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 919f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.add(input, inputDesc); 920f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return input; 921f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 922f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 923f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startInput(audio_io_handle_t input) 924f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 9256a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startInput() input %d", input); 926f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 92864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startInput() unknow input %d", input); 929f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 930f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 931f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 932f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestInput == 0) 935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 936f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 937f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // refuse 2 active AudioRecord clients at the same time 938f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getActiveInput() != 0) { 93964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startInput() input %d failed: other input already started", input); 940f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 943f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 94466707435156d8d99d795271a7bd54943065b4c2dEric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 94566707435156d8d99d795271a7bd54943065b4c2dEric Laurent if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { 94666707435156d8d99d795271a7bd54943065b4c2dEric Laurent inputDesc->mDevice = newDevice; 94766707435156d8d99d795271a7bd54943065b4c2dEric Laurent } 948f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 949f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice); 950f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 951f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource); 9526a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 953f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 954f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 955f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 956f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 1; 957f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 958f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 959f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 960f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopInput(audio_io_handle_t input) 961f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 9626a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopInput() input %d", input); 963f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 964f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 96564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() unknow input %d", input); 966f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 967f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 968f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 969f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 970f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (inputDesc->mRefCount == 0) { 97164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() input %d already stopped", input); 972f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 973f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 974f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 975f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), 0); 976f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 977f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 978f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 979f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 980f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 981f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 982f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseInput(audio_io_handle_t input) 983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 9846a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() %d", input); 985f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 986f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 98764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseInput() releasing unknown input %d", input); 988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 989f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 990f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(index); 992f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.removeItem(input); 9936a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() exit"); 994f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 995f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 996f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream, 997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMin, 998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMax) 999f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 10006a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 1001f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (indexMin < 0 || indexMin >= indexMax) { 100264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 1003f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 1004f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1005f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMin = indexMin; 1006f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMax = indexMax; 1007f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1008f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1009c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, 1010c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 1011c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 1012f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1013f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1014f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 1015f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 1016f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1017c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 1018c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 1019c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1020f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1021f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force max volume if stream cannot be muted 1022f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 1023f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1024b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", 1025c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent stream, device, index); 1026c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 1027c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 1028c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // clear all device specific values 1029c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1030c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.clear(); 1031c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1032c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 1033f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1034f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // compute and apply stream volume on all outputs according to connected device 1035f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin status_t status = NO_ERROR; 1036f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1037c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent audio_devices_t curDevice = 1038c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi getDeviceForVolume(mOutputs.valueAt(i)->device()); 1039e92d623811f3fd3e7cc5e5dd8bc93c0c0a8fdf50Eric Laurent if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) { 1040c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); 1041c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent if (volStatus != NO_ERROR) { 1042c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status = volStatus; 1043c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent } 1044f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1045f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1046f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return status; 1047f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1048f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1049c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, 1050c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int *index, 1051c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 1052f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1053c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (index == NULL) { 1054f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 1055f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1056c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 1057c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 1058c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1059c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 1060c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // the strategy the stream belongs to. 1061c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1062c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); 1063c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1064c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = getDeviceForVolume(device); 1065c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 1066c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 1067c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 1068f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1069f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1070f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1071c94dccc97cc3ed5171b45f46a0f7f8762d37156fGlenn Kastenaudio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(const effect_descriptor_t *desc) 1072f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 10736a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutputForEffect()"); 1074f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // apply simple rule where global effects are attached to the same output as MUSIC streams 10754660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen 10764660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen routing_strategy strategy = getStrategy(AudioSystem::MUSIC); 10774660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 1078c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs); 10794660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen int outIdx = 0; 10804660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen for (size_t i = 0; i < dstOutputs.size(); i++) { 10814660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen AudioOutputDescriptor *desc = mOutputs.valueFor(dstOutputs[i]); 10824660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) { 10834660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen outIdx = i; 10844660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 10854660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 10864660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen return dstOutputs[outIdx]; 1087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1088f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1089c94dccc97cc3ed5171b45f46a0f7f8762d37156fGlenn Kastenstatus_t AudioPolicyManagerBase::registerEffect(const effect_descriptor_t *desc, 10901c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent audio_io_handle_t io, 1091f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t strategy, 1092f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session, 1093f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int id) 1094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 10951c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 1096f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 10971c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent index = mInputs.indexOfKey(io); 10981c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent if (index < 0) { 109964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() unknown io %d", io); 11001c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent return INVALID_OPERATION; 11011c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent } 1102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1103f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1104f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 110564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 1106f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin desc->name, desc->memoryUsage); 1107f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1108f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1109f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory += desc->memoryUsage; 11106a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 11111c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent desc->name, io, strategy, session, id); 11126a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 1113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1114f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = new EffectDescriptor(); 1115f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t)); 11161c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent pDesc->mIo = io; 1117f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mStrategy = (routing_strategy)strategy; 1118f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mSession = session; 1119582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = false; 1120582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1121f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.add(id, pDesc); 1122f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1123f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1124f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1125f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1126f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::unregisterEffect(int id) 1127f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1128f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mEffects.indexOfKey(id); 1129f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 113064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 1131f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1132f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1133f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1134f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = mEffects.valueAt(index); 1135f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1136582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent setEffectEnabled(pDesc, false); 1137582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1138f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) { 113964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() memory %d too big for total %d", 1140f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1141f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage = mTotalEffectsMemory; 1142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1143f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory -= pDesc->mDesc.memoryUsage; 11446a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 1145582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1147f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.removeItem(id); 1148f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete pDesc; 1149f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1153582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(int id, bool enabled) 1154582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 1155582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1156582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (index < 0) { 115764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 1158582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1159582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1160582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1161582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 1162582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 1163582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1164582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(EffectDescriptor *pDesc, bool enabled) 1165582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 1166582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled == pDesc->mEnabled) { 11676a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(%s) effect already %s", 1168582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 1169582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1170582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1171582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1172582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled) { 1173582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 117464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 1175582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10); 1176582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1177582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1178582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad; 11796a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 1180582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } else { 1181582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) { 118264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 1183582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 1184582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 1185582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1186582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad; 11876a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 1188582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1189582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = enabled; 1190582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return NO_ERROR; 1191582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 1192582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const 1194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin nsecs_t sysTime = systemTime(); 1196f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 119780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 119880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (outputDesc->isStreamActive((AudioSystem::stream_type)stream, inPastMs, sysTime)) { 1199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return true; 1200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1205dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivibool AudioPolicyManagerBase::isStreamActiveRemotely(int stream, uint32_t inPastMs) const 1206dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi{ 1207dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi nsecs_t sysTime = systemTime(); 1208dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi for (size_t i = 0; i < mOutputs.size(); i++) { 1209dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 121080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 121180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent outputDesc->isStreamActive((AudioSystem::stream_type)stream, inPastMs, sysTime)) { 1212dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi return true; 1213dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi } 1214dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi } 1215dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi return false; 1216dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi} 1217dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi 1218abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivibool AudioPolicyManagerBase::isSourceActive(audio_source_t source) const 1219abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi{ 1220abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi for (size_t i = 0; i < mInputs.size(); i++) { 1221abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi const AudioInputDescriptor * inputDescriptor = mInputs.valueAt(i); 1222abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi if ((inputDescriptor->mInputSource == (int) source) 1223abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi && (inputDescriptor->mRefCount > 0)) { 1224abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi return true; 1225abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi } 1226abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi } 1227abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi return false; 1228abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi} 1229abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi 1230abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi 1231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::dump(int fd) 1233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 1237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 1239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1240b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 124170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput); 1242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string()); 1244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string()); 1246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1247599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " USB audio ALSA %s\n", mUsbCardAndDevice.string()); 1248599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent result.append(buffer); 1249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices); 1250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices); 1252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 1254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]); 1256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]); 1258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]); 1260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]); 1262f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1263738207def5f691d605ae33d041116829a74513a9Eric Laurent snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AudioSystem::FOR_SYSTEM]); 1264738207def5f691d605ae33d041116829a74513a9Eric Laurent result.append(buffer); 1265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 1266f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 12675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 126870c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 12695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, buffer, strlen(buffer)); 127070c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 127170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, "- HW Module %d:\n", i + 1); 12725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, buffer, strlen(buffer)); 127370c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules[i]->dump(fd); 12745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 12755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 1276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nOutputs dump:\n"); 1277f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 1280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueAt(i)->dump(fd); 1282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1283f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1284f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nInputs dump:\n"); 1285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 1288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.valueAt(i)->dump(fd); 1290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nStreams dump:\n"); 1293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1294c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, 1295c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 1296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1297f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 1298c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, " %02d ", i); 1299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1300c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[i].dump(fd); 1301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 1304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 1305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "Registered effects:\n"); 1308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mEffects.size(); i++) { 1310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 1311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.valueAt(i)->dump(fd); 1313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyManagerBase 1321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface) 1324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin : 1325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Thread(false), 1327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 132870c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput((audio_io_handle_t)0), 1329ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableOutputDevices(AUDIO_DEVICE_NONE), 1330ca0657a1ca087a6d474a75fcfedd6aac3901d587Glenn Kasten mPhoneState(AudioSystem::MODE_NORMAL), 1331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 1332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 133348387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi mA2dpSuspended(false), mHasA2dp(false), mHasUsb(false), mHasRemoteSubmix(false) 1334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface = clientInterface; 1336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) { 1338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[i] = AudioSystem::FORCE_NONE; 1339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin initializeVolumeCurves(); 1342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpDeviceAddress = String8(""); 1344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mScoDeviceAddress = String8(""); 1345599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mUsbCardAndDevice = String8(""); 1346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 13475ec145df7708564d385fd3fb764085321cf4c253Dima Zavin if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { 13485ec145df7708564d385fd3fb764085321cf4c253Dima Zavin if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { 1349739022f26a7127ba76a98dda65411496086114a7Dima Zavin ALOGE("could not load audio policy configuration file, setting defaults"); 1350739022f26a7127ba76a98dda65411496086114a7Dima Zavin defaultAudioPolicyConfig(); 13515ec145df7708564d385fd3fb764085321cf4c253Dima Zavin } 13525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 13535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 1354b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // open all output streams needed to access attached devices 135570c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 135670c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 135770c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 135870c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGW("could not open HW module %s", mHwModules[i]->mName); 135970c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 136070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 136170c236c9290732782d5267935af1475b8d5ae602Eric Laurent // open all output streams needed to access attached devices 136270c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 136370c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 136470c236c9290732782d5267935af1475b8d5ae602Eric Laurent const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j]; 136570c236c9290732782d5267935af1475b8d5ae602Eric Laurent 136670c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (outProfile->mSupportedDevices & mAttachedOutputDevices) { 136770c236c9290732782d5267935af1475b8d5ae602Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile); 136870c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice & 136970c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mSupportedDevices); 137070c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput( 137170c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mModule->mHandle, 137270c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 137370c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mSamplingRate, 137470c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mFormat, 137570c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 137670c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mLatency, 137770c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mFlags); 137870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (output == 0) { 137970c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete outputDesc; 138070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } else { 138170c236c9290732782d5267935af1475b8d5ae602Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | 138270c236c9290732782d5267935af1475b8d5ae602Eric Laurent (outProfile->mSupportedDevices & mAttachedOutputDevices)); 138370c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mPrimaryOutput == 0 && 13840977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 138570c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput = output; 138670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 138770c236c9290732782d5267935af1475b8d5ae602Eric Laurent addOutput(output, outputDesc); 138870c236c9290732782d5267935af1475b8d5ae602Eric Laurent setOutputDevice(output, 138970c236c9290732782d5267935af1475b8d5ae602Eric Laurent (audio_devices_t)(mDefaultOutputDevice & 139070c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mSupportedDevices), 139170c236c9290732782d5267935af1475b8d5ae602Eric Laurent true); 1392b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1393b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1394b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 13975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE_IF((mAttachedOutputDevices & ~mAvailableOutputDevices), 1398b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent "Not output found for attached devices %08x", 13995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (mAttachedOutputDevices & ~mAvailableOutputDevices)); 1400b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1401b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 1402b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1403c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 14043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 1405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1406b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput != 0) { 1407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1409b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1411c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi mTestDevice = AUDIO_DEVICE_OUT_SPEAKER; 1412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = 44100; 1413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = AudioSystem::PCM_16_BIT; 1414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = AudioSystem::CHANNEL_OUT_STEREO; 1415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestLatencyMs = 0; 1416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = 0; 1417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[i] = 0; 1420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 1425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin run(buffer, ANDROID_PRIORITY_AUDIO); 1426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::~AudioPolicyManagerBase() 1431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1432f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin exit(); 1434f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1435f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1436f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(mOutputs.keyAt(i)); 1437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(i); 1438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(mInputs.keyAt(i)); 1441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(i); 1442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 144370c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 144470c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mHwModules[i]; 14455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 1446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::initCheck() 1449f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1450b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; 1451f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1452f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1453f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1454f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::threadLoop() 1455f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 14566a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("entering threadLoop()"); 1457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin while (!exitPending()) 1458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 command; 1460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int valueInt; 1461f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 value; 1462f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Mutex::Autolock _l(mLock); 1464f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 1465f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1466f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 1467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(command); 1468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 1470f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin valueInt != 0) { 14716a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("Test command %s received", command.string()); 1472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 target; 1473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("target"), target) != NO_ERROR) { 1474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin target = "Manager"; 1475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 1477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_output")); 1478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = valueInt; 1479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 1481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_direct")); 1482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "false") { 1483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "true") { 1485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = true; 1486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 1489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_input")); 1490f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestInput = valueInt; 1491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 1494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_format")); 1495f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int format = AudioSystem::INVALID_FORMAT; 1496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "PCM 16 bits") { 1497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_16_BIT; 1498f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "PCM 8 bits") { 1499f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_8_BIT; 1500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Compressed MP3") { 1501f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::MP3; 1502f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1503f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (format != AudioSystem::INVALID_FORMAT) { 1504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = format; 1506f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("format"), format); 1509f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1510f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1511f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1512f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1513f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 1514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_channels")); 1515f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int channels = 0; 1516f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "Channels Stereo") { 1518f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_STEREO; 1519f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Channels Mono") { 1520f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_MONO; 1521f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1522f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (channels != 0) { 1523f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1524f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = channels; 1525f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1526f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1527f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("channels"), channels); 1528f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1529f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1530f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1531f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1532f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 1533f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_sampleRate")); 1534f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (valueInt >= 0 && valueInt <= 96000) { 1535f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int samplingRate = valueInt; 1536f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1537f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = samplingRate; 1538f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1539f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1540f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("sampling_rate"), samplingRate); 1541f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 1547f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_reopen")); 1548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 154970c236c9290732782d5267935af1475b8d5ae602Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 1550b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(mPrimaryOutput); 155170c236c9290732782d5267935af1475b8d5ae602Eric Laurent 155270c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; 155370c236c9290732782d5267935af1475b8d5ae602Eric Laurent 1554b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(mPrimaryOutput); 1555b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(mPrimaryOutput); 1556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1557b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 1558c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; 155970c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput = mpClientInterface->openOutput(moduleHandle, 156070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 1561f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 1562f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 156370c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 1564f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 1565f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 1566b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput == 0) { 15675efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d", 156870c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); 1569f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1570f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1571f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1572b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1573b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent addOutput(mPrimaryOutput, outputDesc); 1574f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1575f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1576f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1577f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1578f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 1579f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1580f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1581f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1582f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1583f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1584f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::exit() 1585f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1586f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1587f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AutoMutex _l(mLock); 1588f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExit(); 1589f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.signal(); 1590f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1591f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExitAndWait(); 1592f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1593f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1594f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinint AudioPolicyManagerBase::testOutputIndex(audio_io_handle_t output) 1595f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1596f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1597f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == mTestOutputs[i]) return i; 1598f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1599f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 1600f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1601f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1602f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1603f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- 1604f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1605f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc) 1606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1607f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mId = id; 1608f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.add(id, outputDesc); 1609f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1610f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1611f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 16123cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurentstatus_t AudioPolicyManagerBase::checkOutputsForDevice(audio_devices_t device, 16133cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioSystem::device_connection_state state, 16143cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent SortedVector<audio_io_handle_t>& outputs) 1615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 16163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *desc; 1617b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1618b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (state == AudioSystem::DEVICE_STATE_AVAILABLE) { 16193cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // first list already open outputs that can be routed to this device 1620b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 16213cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(i); 16223cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices & device)) { 16233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i)); 16243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(mOutputs.keyAt(i)); 1625b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1626b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 16273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // then look for output profiles that can be routed to this device 16283cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent SortedVector<IOProfile *> profiles; 162970c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 1630b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent { 163170c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 163270c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 163370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 163470c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 163570c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 163670c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices & device) { 16373cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): adding profile %d from module %d", j, i); 16383cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profiles.add(mHwModules[i]->mOutputProfiles[j]); 163970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 164070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 1641b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 164270c236c9290732782d5267935af1475b8d5ae602Eric Laurent 16433cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profiles.isEmpty() && outputs.isEmpty()) { 16443cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 16453cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return BAD_VALUE; 164670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 164770c236c9290732782d5267935af1475b8d5ae602Eric Laurent 16483cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // open outputs for matching profiles if needed. Direct outputs are also opened to 16493cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 16503cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 16513cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = profiles[profile_index]; 1652b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 16533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // nothing to do if one output is already opened for this profile 16543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent size_t j; 1655fd8cecbee6843b444d56a1db40af76027e2b19f1Eric Laurent for (j = 0; j < mOutputs.size(); j++) { 16563cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(j); 16573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && desc->mProfile == profile) { 16583cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent break; 16593cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16603cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1661fd8cecbee6843b444d56a1db40af76027e2b19f1Eric Laurent if (j != mOutputs.size()) { 16623cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent continue; 16633cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16643cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 16653cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("opening output for device %08x", device); 16663cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = new AudioOutputDescriptor(profile); 16673cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc->mDevice = device; 16683cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle, 16693cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mDevice, 16703cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mSamplingRate, 16713cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mFormat, 16723cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mChannelMask, 16733cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mLatency, 16743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc->mFlags); 16753cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (output != 0) { 16763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { 16773cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8 reply; 16783cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent char *value; 16793cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mSamplingRates[0] == 0) { 16803cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply = mpClientInterface->getParameters(output, 16813cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 16823cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice() direct output sup sampling rates %s", 16833cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply.string()); 16843cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent value = strpbrk((char *)reply.string(), "="); 16853cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (value != NULL) { 16865debe92591363de3d73bc32b62f23df707b1aecfJohn Grossman loadSamplingRates(value + 1, profile); 16873cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16883cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16893cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mFormats[0] == 0) { 16903cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply = mpClientInterface->getParameters(output, 16913cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 16923cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice() direct output sup formats %s", 16933cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply.string()); 16943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent value = strpbrk((char *)reply.string(), "="); 16953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (value != NULL) { 16965debe92591363de3d73bc32b62f23df707b1aecfJohn Grossman loadFormats(value + 1, profile); 16973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 16993cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mChannelMasks[0] == 0) { 17003cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply = mpClientInterface->getParameters(output, 17013cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 17023cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice() direct output sup channel masks %s", 17033cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply.string()); 17043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent value = strpbrk((char *)reply.string(), "="); 17053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (value != NULL) { 17063cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent loadOutChannels(value + 1, profile); 17073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (((profile->mSamplingRates[0] == 0) && 17103cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mSamplingRates.size() < 2)) || 17113cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ((profile->mFormats[0] == 0) && 17123cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mFormats.size() < 2)) || 17133cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ((profile->mFormats[0] == 0) && 17143cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mChannelMasks.size() < 2))) { 17153cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice() direct output missing param"); 171610705c404c48ec9ac4ce47912e7731f9249cce1dJason Simmons mpClientInterface->closeOutput(output); 17173cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent output = 0; 17183cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } else { 17193cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent addOutput(output, desc); 17203cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17213cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } else { 17223cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_io_handle_t duplicatedOutput = 0; 17233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // add output descriptor 17243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent addOutput(output, desc); 17253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // set initial stream volume for device 17264366b4a6735e5da342b56773073f0b41197c777fEric Laurent applyStreamVolumes(output, device, 0, true); 17273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 17283cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent //TODO: configure audio effect output stage here 17293cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 17303cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // open a duplicating output thread for the new output and the primary output 17313cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent duplicatedOutput = mpClientInterface->openDuplicateOutput(output, 17323cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mPrimaryOutput); 17333cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (duplicatedOutput != 0) { 17343cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // add duplicated output descriptor 17353cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL); 17363cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); 17373cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mOutput2 = mOutputs.valueFor(output); 17383cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mSamplingRate = desc->mSamplingRate; 17393cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mFormat = desc->mFormat; 17403cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mChannelMask = desc->mChannelMask; 17413cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mLatency = desc->mLatency; 17423cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent addOutput(duplicatedOutput, dupOutputDesc); 17434366b4a6735e5da342b56773073f0b41197c777fEric Laurent applyStreamVolumes(duplicatedOutput, device, 0, true); 17443cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } else { 17453cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice() could not open dup output for %d and %d", 17463cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mPrimaryOutput, output); 17473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mpClientInterface->closeOutput(output); 17483cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mOutputs.removeItem(output); 17493cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent output = 0; 17503cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17513cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17523cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (output == 0) { 17543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice() could not open output for device %x", device); 17553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent delete desc; 17563cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profiles.removeAt(profile_index); 17573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile_index--; 1758b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 17593cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(output); 17603cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): adding output %d", output); 1761f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 17623cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17633cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 17643cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profiles.isEmpty()) { 17653cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 17663cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return BAD_VALUE; 1767f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1768f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1769b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // check if one opened output is not needed any more after disconnecting one device 1770b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 17713cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(i); 17723cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && 17733cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent !(desc->mProfile->mSupportedDevices & mAvailableOutputDevices)) { 17743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i)); 17753cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(mOutputs.keyAt(i)); 17763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17773cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17783cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 17793cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent { 17803cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (mHwModules[i]->mHandle == 0) { 17813cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent continue; 17823cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17833cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 17843cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent { 17853cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; 17863cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if ((profile->mSupportedDevices & device) && 17873cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) { 17883cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): clearing direct output profile %d on module %d", 17893cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent j, i); 17903cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mSamplingRates[0] == 0) { 17913cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.clear(); 17923cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.add(0); 17933cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mFormats[0] == 0) { 17953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mFormats.clear(); 17963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mFormats.add((audio_format_t)0); 17973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 17983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mChannelMasks[0] == 0) { 17993cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.clear(); 18003cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.add((audio_channel_mask_t)0); 18013cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18023cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1803b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1804f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1805f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 18063cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return NO_ERROR; 1807f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1808f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1809b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::closeOutput(audio_io_handle_t output) 1810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1811b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput(%d)", output); 1812f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1813b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 1814b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputDesc == NULL) { 1815b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGW("closeOutput() unknown output %d", output); 1816b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1819b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // look for duplicated outputs connected to the output being removed. 1820b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1821b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i); 1822b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->isDuplicated() && 1823b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (dupOutputDesc->mOutput1 == outputDesc || 1824b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent dupOutputDesc->mOutput2 == outputDesc)) { 1825b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc2; 1826b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->mOutput1 == outputDesc) { 1827b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput2; 1828b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 1829b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput1; 1830b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1831b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // As all active tracks on duplicated output will be deleted, 1832b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // and as they were also referenced on the other output, the reference 1833b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // count for their stream type must be adjusted accordingly on 1834b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // the other output. 1835b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (int j = 0; j < (int)AudioSystem::NUM_STREAM_TYPES; j++) { 1836b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent int refCount = dupOutputDesc->mRefCount[j]; 1837b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2->changeRefCount((AudioSystem::stream_type)j,-refCount); 1838b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1839b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i); 1840b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); 1841f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1842b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(duplicatedOutput); 1843b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(duplicatedOutput); 1844b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(duplicatedOutput); 1845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1847b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1848b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioParameter param; 1849b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent param.add(String8("closing"), String8("true")); 1850b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(output, param.toString()); 1851b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1852b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(output); 18535a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent delete outputDesc; 1854b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(output); 18555a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent mPreviousOutputs = mOutputs; 1856f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1857f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1858c952527e6f89d5427881462823514be9d79f13e6Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManagerBase::getOutputsForDevice(audio_devices_t device, 1859c952527e6f89d5427881462823514be9d79f13e6Eric Laurent DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs) 1860f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1861b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t> outputs; 1862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 18633cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getOutputsForDevice() device %04x", device); 1864c952527e6f89d5427881462823514be9d79f13e6Eric Laurent for (size_t i = 0; i < openOutputs.size(); i++) { 18653cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("output %d isDuplicated=%d device=%04x", 1866c952527e6f89d5427881462823514be9d79f13e6Eric Laurent i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices()); 1867c952527e6f89d5427881462823514be9d79f13e6Eric Laurent if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) { 1868c952527e6f89d5427881462823514be9d79f13e6Eric Laurent ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i)); 1869c952527e6f89d5427881462823514be9d79f13e6Eric Laurent outputs.add(openOutputs.keyAt(i)); 1870f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1871f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1872b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return outputs; 1873f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1874f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1875b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentbool AudioPolicyManagerBase::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, 1876b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t>& outputs2) 1877f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1878b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1.size() != outputs2.size()) { 1879b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 1880f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1881b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < outputs1.size(); i++) { 1882b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1[i] != outputs2[i]) { 1883b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 1884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1885f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1886b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return true; 1887b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 1888b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1889b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy) 1890b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 189101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); 189201e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); 1893c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs); 1894c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); 1895b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1896b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!vectorsEqual(srcOutputs,dstOutputs)) { 1897b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", 1898b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent strategy, srcOutputs[0], dstOutputs[0]); 18995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // mute strategy while moving tracks from one output to another 19005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < srcOutputs.size(); i++) { 1901fa3697d716b444bbea6be480801536c44bf69214Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]); 190280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (desc->isStrategyActive(strategy)) { 1903fa3697d716b444bbea6be480801536c44bf69214Eric Laurent setStrategyMute(strategy, true, srcOutputs[i]); 1904fa3697d716b444bbea6be480801536c44bf69214Eric Laurent setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); 1905fa3697d716b444bbea6be480801536c44bf69214Eric Laurent } 19065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 1907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Move effects associated to this strategy from previous output to new output 19094660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (strategy == STRATEGY_MEDIA) { 19104660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen int outIdx = 0; 19114660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen for (size_t i = 0; i < dstOutputs.size(); i++) { 19124660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen AudioOutputDescriptor *desc = mOutputs.valueFor(dstOutputs[i]); 19134660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) { 19144660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen outIdx = i; 19154660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 19164660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 19174660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen SortedVector<audio_io_handle_t> moved; 19184660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen for (size_t i = 0; i < mEffects.size(); i++) { 19194660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen EffectDescriptor *desc = mEffects.valueAt(i); 19204660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX && 19214660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen desc->mIo != dstOutputs[outIdx]) { 19224660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (moved.indexOf(desc->mIo) < 0) { 19234660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen ALOGV("checkOutputForStrategy() moving effect %d to output %d", 19244660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen mEffects.keyAt(i), dstOutputs[outIdx]); 19254660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, desc->mIo, 19264660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen dstOutputs[outIdx]); 19274660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen moved.add(desc->mIo); 19284660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 19294660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen desc->mIo = dstOutputs[outIdx]; 19304660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 19314660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 19324660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 19335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // Move tracks associated to this strategy from previous output to new output 1934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 1935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)i) == strategy) { 193612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi //FIXME see fixme on name change 19374660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, 19384660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen dstOutputs[0] /* ignored */); 1939f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1940f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1943f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1944f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkOutputForAllStrategies() 1945f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1946c16ac09f510437e8340be691720177a490ae78f0Eric Laurent checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 1947f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_PHONE); 1948f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_SONIFICATION); 194912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 1950f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_MEDIA); 1951f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_DTMF); 1952f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1953f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1954b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::getA2dpOutput() 1955b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 19565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp) { 1957b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1958b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1959b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1960b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1961b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 1962b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 1963b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mOutputs.keyAt(i); 1964b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1965b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1966b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1967b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1968b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 1969b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1970f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkA2dpSuspend() 1971f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 19725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp) { 1973b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1974b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1975b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t a2dpOutput = getA2dpOutput(); 1976b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (a2dpOutput == 0) { 1977b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1978b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1979b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1980f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // suspend A2DP output if: 1981f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (NOT already suspended) && 1982f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is connected && 1983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage for communication || for record is SCO))) || 1984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is ringing || in call) 1985f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1986f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // restore A2DP output if: 1987f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (Already suspended) && 1988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is NOT connected || 1989f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage NOT for communication && NOT for record is SCO))) && 1990f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is NOT ringing && NOT in call) 1991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1992f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpSuspended) { 1993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress == "") || 1994f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) && 1995f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) && 1996f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState != AudioSystem::MODE_IN_CALL) && 1997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState != AudioSystem::MODE_RINGTONE))) { 1998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1999b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->restoreOutput(a2dpOutput); 2000f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = false; 2001f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2002f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2003f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress != "") && 2004f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 2005f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) || 2006f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState == AudioSystem::MODE_IN_CALL) || 2007f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState == AudioSystem::MODE_RINGTONE))) { 2008f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2009b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->suspendOutput(a2dpOutput); 2010f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = true; 2011f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2012f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2013f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2014f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2015f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache) 2016f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2017ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent audio_devices_t device = AUDIO_DEVICE_NONE; 2018f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2019f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2020f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check the following by order of priority to request a routing change if necessary: 2021c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 1: the strategy enforced audible is active on the output: 2022c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // use device for strategy enforced audible 2023c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 2: we are in call or the strategy phone is active on the output: 2024f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy phone 2025c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 3: the strategy sonification is active on the output: 2026f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy sonification 202712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 4: the strategy "respectful" sonification is active on the output: 202812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // use device for strategy "respectful" sonification 202912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 5: the strategy media is active on the output: 2030f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy media 203112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 6: the strategy DTMF is active on the output: 2032f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy DTMF 203380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { 2034c16ac09f510437e8340be691720177a490ae78f0Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 2035c16ac09f510437e8340be691720177a490ae78f0Eric Laurent } else if (isInCall() || 203680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent outputDesc->isStrategyActive(STRATEGY_PHONE)) { 2037f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 203880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) { 2039f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 204080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { 20415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); 204280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { 2043f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 204480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { 2045f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 2046f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2047f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 20486a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getNewDevice() selected device %x", device); 2049f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return device; 2050f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2051f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2052f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getStrategyForStream(AudioSystem::stream_type stream) { 2053f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return (uint32_t)getStrategy(stream); 2054f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2055f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2056f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDevicesForStream(AudioSystem::stream_type stream) { 2057f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t devices; 2058f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // By checking the range of stream before calling getStrategy, we avoid 20595efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 2060f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and then return STRATEGY_MEDIA, but we want to return the empty set. 2061f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream < (AudioSystem::stream_type) 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 2062ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent devices = AUDIO_DEVICE_NONE; 2063f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2064f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioPolicyManagerBase::routing_strategy strategy = getStrategy(stream); 20655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devices = getDeviceForStrategy(strategy, true /*fromCache*/); 2066f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2067f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return devices; 2068f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2069f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2070f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy( 2071f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream) { 2072f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // stream to strategy mapping 2073f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (stream) { 2074f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::VOICE_CALL: 2075f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::BLUETOOTH_SCO: 2076f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_PHONE; 2077f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::RING: 2078f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::ALARM: 2079f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_SONIFICATION; 208012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::NOTIFICATION: 208112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi return STRATEGY_SONIFICATION_RESPECTFUL; 2082f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DTMF: 2083f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_DTMF; 2084f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 20855efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("unknown stream type"); 2086f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::SYSTEM: 2087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 2088f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // while key clicks are played produces a poor result 2089f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::TTS: 2090f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::MUSIC: 2091f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_MEDIA; 2092c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case AudioSystem::ENFORCED_AUDIBLE: 2093c16ac09f510437e8340be691720177a490ae78f0Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 2094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2095f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2096f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 209712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivivoid AudioPolicyManagerBase::handleNotificationRoutingForStream(AudioSystem::stream_type stream) { 209812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi switch(stream) { 209912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::MUSIC: 210012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 2101c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 210212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 210312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi default: 210412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 210512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 210612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi} 210712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 21085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, 21095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool fromCache) 2110f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2111ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 2112f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (fromCache) { 21143cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x", 21155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent strategy, mDeviceForStrategy[strategy]); 2116f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mDeviceForStrategy[strategy]; 2117f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2118f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2119f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (strategy) { 212012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 212112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case STRATEGY_SONIFICATION_RESPECTFUL: 212212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if (isInCall()) { 21235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 2124dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi } else if (isStreamActiveRemotely(AudioSystem::MUSIC, 2125dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 2126dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // while media is playing on a remote device, use the the sonification behavior. 2127dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // Note that we test this usecase before testing if media is playing because 2128dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // the isStreamActive() method only informs about the activity of a stream, not 2129dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // if it's for local playback. Note also that we use the same delay between both tests 2130dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 213112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 213212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // while media is playing (or has recently played), use the same device 21335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 213412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else { 213512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // when media is not playing anymore, fall back on the sonification behavior 21365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 213712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 213812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 213912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 214012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 2141f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_DTMF: 2142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall()) { 2143f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when off call, DTMF strategy follows the same rules as MEDIA strategy 21445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 2145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2147f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when in call, DTMF and PHONE strategies follow the same rules 2148f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2149f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_PHONE: 2151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // for phone strategy, we first consider the forced use and then the available devices by order 2152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // of priority 2153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { 2154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_BT_SCO: 2155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall() || strategy != STRATEGY_DTMF) { 2156c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 2157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2159c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 2160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2161c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; 2162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if SCO device is requested but no SCO device is available, fall back to default case 2164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: // FORCE_NONE 2167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 21681afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (mHasA2dp && !isInCall() && 21691afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 2170ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 2171c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 2172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2173c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2176c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 21771afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (device) break; 2178c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET; 21791afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (device) break; 2180b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (mPhoneState != AudioSystem::MODE_IN_CALL) { 2181b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2182b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2183b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2184b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2185b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2186b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2187b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2188b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2189b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2190b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2191b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent } 2192c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_EARPIECE; 21935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 21945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2195ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 21965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); 2197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2198f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_SPEAKER: 2201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 2202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // A2DP speaker when forcing to speaker output 22031afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (mHasA2dp && !isInCall() && 22041afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 2205ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 2206c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2209b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (mPhoneState != AudioSystem::MODE_IN_CALL) { 2210b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2211b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2212b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2213b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2214b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2215b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2216b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2217b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2218b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2219b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2220b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent } 2221c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; 22225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 22235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2224ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 22255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); 2226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_SONIFICATION: 2232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 2234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handleIncallSonification(). 2235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 22365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); 2237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2239c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // FALL THROUGH 2240c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 2241c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 2242c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 2243ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // except: 2244ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // - when in call where it doesn't default to STRATEGY_PHONE behavior 2245ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // - in countries where not enforced in which case it follows STRATEGY_MEDIA 2246c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 2247738207def5f691d605ae33d041116829a74513a9Eric Laurent if ((strategy == STRATEGY_SONIFICATION) || 2248738207def5f691d605ae33d041116829a74513a9Eric Laurent (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED)) { 2249c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; 2250ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2251ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); 2252ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent } 2253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // The second device used for sonification is the same as the device used by media strategy 2255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_MEDIA: { 2258ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent uint32_t device2 = AUDIO_DEVICE_NONE; 225931363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi if (strategy != STRATEGY_SONIFICATION) { 226031363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi // no sonification on remote submix (e.g. WFD) 226148387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; 226248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 2263ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 226448387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 2265ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 2266c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 2267ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2268c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2269f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2270ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2271c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2274ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2275c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 22761afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent } 2277ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2278c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET; 22791afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent } 2280ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2281599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2282599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 2283ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2284599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2285599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 2286ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2287c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 228931363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { 229031363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi // no sonification on aux digital (e.g. HDMI) 2291c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 22935a484b753cc72d6a50c1dd3bbf68b3403c741a3aEric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 22945a484b753cc72d6a50c1dd3bbf68b3403c741a3aEric Laurent (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_ANALOG_DOCK)) { 2295c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2297ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2298c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; 2299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2301c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 2302ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise 2303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device |= device2; 23045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 23055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2306ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 23075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); 2308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 2310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 231264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 2313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 23163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 2317c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi return device; 2318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2320c952527e6f89d5427881462823514be9d79f13e6Eric Laurentvoid AudioPolicyManagerBase::updateDevicesAndOutputs() 2321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_STRATEGIES; i++) { 23235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 23245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2325c952527e6f89d5427881462823514be9d79f13e6Eric Laurent mPreviousOutputs = mOutputs; 23265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 23275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2328b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurentuint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc, 23299029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent audio_devices_t prevDevice, 23305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t delayMs) 23315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 23329029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // mute/unmute strategies using an incompatible device combination 23339029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // if muting, wait for the audio in pcm buffer to be drained before proceeding 23349029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // if unmuting, unmute only after the specified delay 23355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->isDuplicated()) { 2336b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return 0; 23375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 23385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 23395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t muteWaitMs = 0; 23405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t device = outputDesc->device(); 234180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent bool shouldMute = outputDesc->isActive() && (AudioSystem::popCount(device) >= 2); 23429029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // temporary mute output if device selection changes to avoid volume bursts due to 23439029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // different per device volumes 234480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent bool tempMute = outputDesc->isActive() && (device != prevDevice); 23455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 23465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 23475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 23485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool mute = shouldMute && (curDevice & device) && (curDevice != device); 23495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool doMute = false; 23505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 23515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mute && !outputDesc->mStrategyMutedByDevice[i]) { 23525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent doMute = true; 23535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = true; 23545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){ 23555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent doMute = true; 23565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = false; 23575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 23589029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (doMute || tempMute) { 23595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t j = 0; j < mOutputs.size(); j++) { 23605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(j); 2361f32e38e24db196671d3ea43427125a4e212466faEric Laurent // skip output if it does not share any device with current output 2362c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if ((desc->supportedDevices() & outputDesc->supportedDevices()) 2363ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent == AUDIO_DEVICE_NONE) { 23645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent continue; 23655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 23665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(j); 23673cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", 23685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mute ? "muting" : "unmuting", i, curDevice, curOutput); 23695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); 237080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (desc->isStrategyActive((routing_strategy)i)) { 2371f32e38e24db196671d3ea43427125a4e212466faEric Laurent // do tempMute only for current output 2372f32e38e24db196671d3ea43427125a4e212466faEric Laurent if (tempMute && (desc == outputDesc)) { 237301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStrategyMute((routing_strategy)i, true, curOutput); 237401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStrategyMute((routing_strategy)i, false, curOutput, 237501e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent desc->latency() * 2, device); 23769029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent } 2377f32e38e24db196671d3ea43427125a4e212466faEric Laurent if ((tempMute && (desc == outputDesc)) || mute) { 23789029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (muteWaitMs < desc->latency()) { 23799029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent muteWaitMs = desc->latency(); 23809029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent } 23815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 23825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 23835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 23845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 23855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 23865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 23875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // FIXME: should not need to double latency if volume could be applied immediately by the 23885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // audioflinger mixer. We must account for the delay between now and the next time 23895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // the audioflinger thread for this output will process a buffer (which corresponds to 23905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // one buffer size, usually 1/2 or 1/4 of the latency). 23915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent muteWaitMs *= 2; 23925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // wait for the PCM output buffers to empty before proceeding with the rest of the command 23935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (muteWaitMs > delayMs) { 2394b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs -= delayMs; 2395b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent usleep(muteWaitMs * 1000); 2396b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2398b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return 0; 2399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2401b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurentuint32_t AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, 2402f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2403f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent bool force, 2404f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent int delayMs) 2405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 24065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); 2407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 24085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioParameter param; 2409f32e38e24db196671d3ea43427125a4e212466faEric Laurent uint32_t muteWaitMs; 2410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->isDuplicated()) { 2412b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); 2413b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); 2414b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2416f32e38e24db196671d3ea43427125a4e212466faEric Laurent // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current 2417f32e38e24db196671d3ea43427125a4e212466faEric Laurent // output profile 2418f32e38e24db196671d3ea43427125a4e212466faEric Laurent if ((device != AUDIO_DEVICE_NONE) && 2419f32e38e24db196671d3ea43427125a4e212466faEric Laurent ((device & outputDesc->mProfile->mSupportedDevices) == 0)) { 2420f32e38e24db196671d3ea43427125a4e212466faEric Laurent return 0; 2421f32e38e24db196671d3ea43427125a4e212466faEric Laurent } 2422f32e38e24db196671d3ea43427125a4e212466faEric Laurent 2423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // filter devices according to output selected 2424f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices); 2425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t prevDevice = outputDesc->mDevice; 24275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 24285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() prevDevice %04x", prevDevice); 24295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2430ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device != AUDIO_DEVICE_NONE) { 24315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mDevice = device; 24325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 24339029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); 24345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2435f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Do not change the routing if: 2436ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent // - the requested device is AUDIO_DEVICE_NONE 2437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the requested device is the same as current device and force is not specified. 2438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Doing this check here allows the caller to call setOutputDevice() without conditions 2439ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) { 24405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); 2441b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() changing device"); 2445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do the routing 2446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)device); 24475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mpClientInterface->setParameters(output, param.toString(), delayMs); 24485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2449f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // update stream volumes according to new device 2450f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin applyStreamVolumes(output, device, delayMs); 2451b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent 2452b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 24535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 2454f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getInputProfile(audio_devices_t device, 24565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t samplingRate, 24575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t format, 24585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t channelMask) 24595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 24605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // Choose an input profile based on the requested capture parameters: select the first available 24615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // profile supporting all requested parameters. 24625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 246370c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 24645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent { 246570c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 24665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent continue; 24675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 246870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 24695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent { 247070c236c9290732782d5267935af1475b8d5ae602Eric Laurent IOProfile *profile = mHwModules[i]->mInputProfiles[j]; 247170c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 24720977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent channelMask,(audio_output_flags_t)0)) { 247370c236c9290732782d5267935af1475b8d5ae602Eric Laurent return profile; 24745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 24755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 247770c236c9290732782d5267935af1475b8d5ae602Eric Laurent return NULL; 2478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2480f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) 2481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2482ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 2483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24849641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent switch (inputSource) { 24859641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 24869641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { 24879641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 24889641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent break; 24899641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent } 24909641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent // FALL THROUGH 24919641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent 2492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_DEFAULT: 2493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_MIC: 2494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_RECOGNITION: 2495f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_COMMUNICATION: 2496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO && 2497c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 2498c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 2499c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_WIRED_HEADSET) { 2500c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_WIRED_HEADSET; 2501c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { 2502c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BUILTIN_MIC; 2503f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_CAMCORDER: 2506c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (mAvailableInputDevices & AUDIO_DEVICE_IN_BACK_MIC) { 2507c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BACK_MIC; 2508c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { 2509c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BUILTIN_MIC; 2510f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2511f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2512f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 2513f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 2514c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { 2515c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_VOICE_CALL; 25165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 251848387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi case AUDIO_SOURCE_REMOTE_SUBMIX: 251948387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi if (mAvailableInputDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { 252048387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; 252148387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 252248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi break; 2523f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 252464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 2525f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2526f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 25276a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 2528c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi return device; 2529f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2530f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 25316d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivibool AudioPolicyManagerBase::isVirtualInputDevice(audio_devices_t device) 25326d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi{ 25336d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi if ((device & AUDIO_DEVICE_BIT_IN) != 0) { 25346d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi device &= ~AUDIO_DEVICE_BIT_IN; 25356d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) 25366d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi return true; 25376d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi } 25386d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi return false; 25396d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi} 25406d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi 25416d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Triviaudio_io_handle_t AudioPolicyManagerBase::getActiveInput(bool ignoreVirtualInputs) 2542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 25446d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi const AudioInputDescriptor * input_descriptor = mInputs.valueAt(i); 25456d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi if ((input_descriptor->mRefCount > 0) 25466d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) { 2547f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mInputs.keyAt(i); 2548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2549f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2550f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 2551f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2552f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2553e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2554c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForVolume(audio_devices_t device) 2555e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2556ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2557e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // this happens when forcing a route update and no track is active on an output. 2558e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // In this case the returned category is not important. 2559c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 2560c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else if (AudioSystem::popCount(device) > 1) { 2561e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // Multiple device selection is either: 2562e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - speaker + one other device: give priority to speaker in this case. 2563e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 2564e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 2565e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // selection if not the speaker. 2566c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 2567c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 2568c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else { 2569c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 2570c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 2571e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 2572e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 257364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW_IF(AudioSystem::popCount(device) != 1, 2574c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 2575e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device); 2576e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2577c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return device; 2578c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 2579c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2580f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric LaurentAudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(audio_devices_t device) 2581c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 2582f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent switch(getDeviceForVolume(device)) { 2583e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 2584e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_EARPIECE; 2585e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 2586e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 2587e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 2588e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 2589e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 2590e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 2591e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_HEADSET; 2592e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 2593e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 2594e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 2595c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent case AUDIO_DEVICE_OUT_AUX_DIGITAL: 2596599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent case AUDIO_DEVICE_OUT_USB_ACCESSORY: 2597599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent case AUDIO_DEVICE_OUT_USB_DEVICE: 259848387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi case AUDIO_DEVICE_OUT_REMOTE_SUBMIX: 2599e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent default: 2600e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_SPEAKER; 2601e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 2602e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent} 2603e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2604f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentfloat AudioPolicyManagerBase::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, 2605e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int indexInUi) 2606e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2607e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device_category deviceCategory = getDeviceCategory(device); 2608e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 2609e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2610f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // the volume index in the UI is relative to the min and max volume indices for this stream type 2611e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 2612e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[VOLMIN].mIndex; 2613f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 2614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (streamDesc.mIndexMax - streamDesc.mIndexMin); 2615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2616f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // find what part of the curve this index volume belongs to, or if it's out of bounds 2617f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int segment = 0; 2618e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 2619f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0.0f; 2620e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 2621f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 0; 2622e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 2623f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 1; 2624e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 2625f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 2; 2626f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { // out of bounds 2627f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0f; 2628f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2629f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // linear interpolation in the attenuation table in dB 2631e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent float decibels = curve[segment].mDBAttenuation + 2632e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 2633e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ( (curve[segment+1].mDBAttenuation - 2634e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation) / 2635e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(curve[segment+1].mIndex - 2636e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex)) ); 2637f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2638f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 2639f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 26403cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 2641e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex, volIdx, 2642e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mIndex, 2643e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation, 2644cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent decibels, 2645e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mDBAttenuation, 2646f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin amplification); 2647f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return amplification; 2649f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2650f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2651cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2652e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2653e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 2654e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2655e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2656e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2657e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2658e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 2659cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent}; 2660cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent 2661e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2662e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2663e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 2664e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2665e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2666e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2667e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2668e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 2669e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2670e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2671ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks 2672ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets (See AudioService.java). 2673123897874418f9f0e48bb89386d8c470e6975f28Jean-Michel Trivi// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset. 2674ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2675ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent AudioPolicyManagerBase::sDefaultSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2676123897874418f9f0e48bb89386d8c470e6975f28Jean-Michel Trivi {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f} 2677ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent}; 2678ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent 2679ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2680ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent AudioPolicyManagerBase::sHeadsetSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 26817465678e0d5711ebcd78ae47b3a76821534a23eaEric Laurent {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f} 2682ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent}; 2683e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2684e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 26850d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent AudioPolicyManagerBase::sDefaultVoiceVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 26860d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f} 26870d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent}; 26880d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent 26890d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 26900d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent AudioPolicyManagerBase::sSpeakerVoiceVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 26910d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f} 26920d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent}; 26930d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent 26940d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2695ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent *AudioPolicyManagerBase::sVolumeProfiles[AUDIO_STREAM_CNT] 2696e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent [AudioPolicyManagerBase::DEVICE_CATEGORY_CNT] = { 2697ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_VOICE_CALL 26980d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 26990d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 27000d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 2701e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2702ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_SYSTEM 2703ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2704ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2705ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2706ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2707ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_RING 2708e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2709e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2710e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2711e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2712ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_MUSIC 2713ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 2714ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2715ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 2716ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2717ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_ALARM 271812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 271912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 272012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 272112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi }, 2722ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_NOTIFICATION 2723e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2724ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2725e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2726c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2727ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_BLUETOOTH_SCO 27280d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 27290d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 27300d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 2731c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2732ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_ENFORCED_AUDIBLE 2733ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2734ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2735ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2736ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2737ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_DTMF 2738ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2739ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2740ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2741ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2742ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_TTS 2743ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 2744ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2745ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 2746ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2747e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2748e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2749e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentvoid AudioPolicyManagerBase::initializeVolumeCurves() 2750e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2751ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 2752e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 2753cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent mStreams[i].mVolumeCurve[j] = 2754ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sVolumeProfiles[i][j]; 2755cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2756cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2759c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentfloat AudioPolicyManagerBase::computeVolume(int stream, 2760c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2761c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2762f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device) 2763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2764f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = 1.0; 2765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2766f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 2767f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2768ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2769f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = outputDesc->device(); 2770f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2772f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if volume is not 0 (not muted), force media volume to max on digital output 2773f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::MUSIC && 2774f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin index != mStreams[stream].mIndexMin && 2775f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent (device == AUDIO_DEVICE_OUT_AUX_DIGITAL || 2776599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET || 2777599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_USB_ACCESSORY || 2778599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_USB_DEVICE)) { 2779f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0; 2780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2782f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = volIndexToAmpl(device, streamDesc, index); 2783f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2784f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if a headset is connected, apply the following rules to ring tones and notifications 2785f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // to avoid sound level bursts in user's ears: 2786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - always attenuate ring tones and notifications volume by 6dB 2787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - if music is playing, always limit the volume to current music volume, 2788f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // with a minimum threshold at -36dB so that notification is always perceived. 278912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 2790c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | 2791c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 2792c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi AUDIO_DEVICE_OUT_WIRED_HEADSET | 2793c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) && 279412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION) 279512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) 2796738207def5f691d605ae33d041116829a74513a9Eric Laurent || (stream == AudioSystem::SYSTEM) 2797738207def5f691d605ae33d041116829a74513a9Eric Laurent || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) && 2798738207def5f691d605ae33d041116829a74513a9Eric Laurent (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_NONE))) && 2799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin streamDesc.mCanBeMuted) { 2800f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 2801f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when the phone is ringing we must consider that music could have been paused just before 2802f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // by the music application and behave as if music was active if the last music track was 2803f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // just stopped 2804ac3cf10ef6de12e69540a1244ac7255f93fa7502Eric Laurent if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || 2805ac3cf10ef6de12e69540a1244ac7255f93fa7502Eric Laurent mLimitRingtoneVolume) { 280617a73c3394547692457299dc512b5c2312ea0344Eric Laurent audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/); 2807c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float musicVol = computeVolume(AudioSystem::MUSIC, 280817a73c3394547692457299dc512b5c2312ea0344Eric Laurent mStreams[AudioSystem::MUSIC].getVolumeIndex(musicDevice), 2809c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 281017a73c3394547692457299dc512b5c2312ea0344Eric Laurent musicDevice); 2811c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 2812c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 2813f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume > minVol) { 2814f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = minVol; 28156a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 2816f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2819f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2820f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return volume; 2821f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2822f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2823c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::checkAndSetVolume(int stream, 2824c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2825c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2826f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2827c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 2828c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 2829f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2830f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2831f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change actual stream volume if the stream is muted 2832f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 28333cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkAndSetVolume() stream %d muted count %d", 28345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent stream, mOutputs.valueFor(output)->mMuteCount[stream]); 2835f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2836f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2837f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2838f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change in call volume if bluetooth is connected and vice versa 2839f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 2840f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) { 28416a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 2842f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, mForceUse[AudioSystem::FOR_COMMUNICATION]); 2843f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 2844f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = computeVolume(stream, index, output, device); 2847f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // We actually change the volume if: 2848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the float value returned by computeVolume() changed 2849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the force flag is set 2850f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 2851f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force) { 2852f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueFor(output)->mCurVolume[stream] = volume; 28533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 28540d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 28550d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent // enabled 28560d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent if (stream == AudioSystem::BLUETOOTH_SCO) { 28570d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs); 2858f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2859f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); 2860f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2861f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL || 2863f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::BLUETOOTH_SCO) { 2864f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float voiceVolume; 2865f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force voice volume to max for bluetooth SCO as volume is managed by the headset 2866f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL) { 2867f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 2868f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2869f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = 1.0; 2870f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2871f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2872b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { 2873f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 2874f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLastVoiceVolume = voiceVolume; 2875f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2876f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2877f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2878f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2879f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2880f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2881c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, 2882f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2883c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 2884c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 2885f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 28863cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("applyStreamVolumes() for output %d and device %x", output, device); 2887f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2888f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 2889c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 2890f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mStreams[stream].getVolumeIndex(device), 2891c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2892c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 2893c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs, 2894c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent force); 2895f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2896f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2897f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 289801e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurentvoid AudioPolicyManagerBase::setStrategyMute(routing_strategy strategy, 289901e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent bool on, 290001e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_io_handle_t output, 290101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent int delayMs, 290201e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t device) 2903f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 29043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 2905f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 2906f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)stream) == strategy) { 290701e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStreamMute(stream, on, output, delayMs, device); 2908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2910f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2911f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 291201e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurentvoid AudioPolicyManagerBase::setStreamMute(int stream, 291301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent bool on, 291401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_io_handle_t output, 291501e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent int delayMs, 291601e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t device) 2917f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2918f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 2919f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2920ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 292101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent device = outputDesc->device(); 292201e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent } 2923f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 29243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x", 292501e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent stream, on, output, outputDesc->mMuteCount[stream], device); 2926f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (on) { 2928f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 2929738207def5f691d605ae33d041116829a74513a9Eric Laurent if (streamDesc.mCanBeMuted && 2930738207def5f691d605ae33d041116829a74513a9Eric Laurent ((stream != AudioSystem::ENFORCED_AUDIBLE) || 2931738207def5f691d605ae33d041116829a74513a9Eric Laurent (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_NONE))) { 2932c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 2933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 2936f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mMuteCount[stream]++; 2937f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2938f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 29393cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("setStreamMute() unmuting non muted stream!"); 2940f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 2941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (--outputDesc->mMuteCount[stream] == 0) { 2943c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 2944c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi streamDesc.getVolumeIndex(device), 2945c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2946c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 2947c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs); 2948f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2949f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2950f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2951f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2952f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, bool stateChange) 2953f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2954f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if the stream pertains to sonification strategy and we are in call we must 2955f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // mute the stream if it is low visibility. If it is high visibility, we must play a tone 2956f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // in the device used for phone strategy and play the tone if the selected device does not 2957f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // interfere with the device used for phone strategy 2958f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 2959f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // many times as there are active tracks on the output 296012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 296112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if ((stream_strategy == STRATEGY_SONIFICATION) || 296212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { 2963b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 29646a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 2965f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, starting, outputDesc->mDevice, stateChange); 2966f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream]) { 2967f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int muteCount = 1; 2968f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stateChange) { 2969f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin muteCount = outputDesc->mRefCount[stream]; 2970f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2971f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) { 29726a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 2973f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 2974b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 2975f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2976f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 29776a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility"); 29785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->device() & 29795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) { 29806a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 2981f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 2982b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 2983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2985f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (starting) { 2986f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL); 2987f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->stopTone(); 2989f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2990f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2992f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2994f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2995f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isInCall() 2996f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return isStateInCall(mPhoneState); 2998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2999f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3000f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStateInCall(int state) { 3001f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((state == AudioSystem::MODE_IN_CALL) || 3002f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (state == AudioSystem::MODE_IN_COMMUNICATION)); 3003f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3004f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 300570c236c9290732782d5267935af1475b8d5ae602Eric Laurentbool AudioPolicyManagerBase::needsDirectOuput(audio_stream_type_t stream, 300670c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 300770c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_format_t format, 300870c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_channel_mask_t channelMask, 30090977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags, 301070c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_devices_t device) 3011f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3012f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) || 3013b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (format != 0 && !AudioSystem::isLinearPCM(format))); 3014f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3015f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3016f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsCpuLoad() 3017f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3018f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_CPU_LOAD; 3019f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3020f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3021f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsMemory() 3022f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3023f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_MEMORY; 3024f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3025f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3026f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioOutputDescriptor class implementation 3027f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3028b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric LaurentAudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor( 30295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const IOProfile *profile) 303070c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mId(0), mSamplingRate(0), mFormat((audio_format_t)0), 303170c236c9290732782d5267935af1475b8d5ae602Eric Laurent mChannelMask((audio_channel_mask_t)0), mLatency(0), 3032ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), 30335a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0) 3034f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3035f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // clear usage count for all stream types 3036f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 3037f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[i] = 0; 3038f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurVolume[i] = -1.0; 3039f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mMuteCount[i] = 0; 3040f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStopTime[i] = 0; 3041f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 304285ad78f27ca032e90af0f2100659d12c16322c76Marco Nelissen for (int i = 0; i < NUM_STRATEGIES; i++) { 304385ad78f27ca032e90af0f2100659d12c16322c76Marco Nelissen mStrategyMutedByDevice[i] = false; 304485ad78f27ca032e90af0f2100659d12c16322c76Marco Nelissen } 30453cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile != NULL) { 30463cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mSamplingRate = profile->mSamplingRates[0]; 30473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mFormat = profile->mFormats[0]; 30483cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mChannelMask = profile->mChannelMasks[0]; 30493cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mFlags = profile->mFlags; 30503cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 3051f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3052f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3053dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Triviaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::device() const 3054f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3055f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 3056f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 3057f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 3058f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return mDevice; 3059f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3060f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3061f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 30625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::latency() 30635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 30645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isDuplicated()) { 30655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 30665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 30675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return mLatency; 30685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 30695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 30705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 30715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::sharesHwModuleWith( 30725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const AudioOutputDescriptor *outputDesc) 30735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 30745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isDuplicated()) { 30755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 30765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (outputDesc->isDuplicated()){ 30775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2); 30785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 307970c236c9290732782d5267935af1475b8d5ae602Eric Laurent return (mProfile->mModule == outputDesc->mProfile->mModule); 30805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 30815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 30825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 3083f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta) 3084f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3085f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // forward usage count change to attached outputs 3086f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 3087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput1->changeRefCount(stream, delta); 3088f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput2->changeRefCount(stream, delta); 3089f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3090f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((delta + (int)mRefCount[stream]) < 0) { 309164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]); 3092f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] = 0; 3093f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 3094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3095f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] += delta; 30966a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 3097f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3098f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3099f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::supportedDevices() 3100b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 3101b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (isDuplicated()) { 3102f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 3103b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 3104b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mProfile->mSupportedDevices ; 3105b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 3106b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 3107b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 310842fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::isActive(uint32_t inPastMs) const 310942fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent{ 311080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return isStrategyActive(NUM_STRATEGIES, inPastMs); 311180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent} 311280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent 311380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy, 311480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent uint32_t inPastMs, 311580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent nsecs_t sysTime) const 311680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent{ 311780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if ((sysTime == 0) && (inPastMs != 0)) { 311880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime = systemTime(); 311980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 312042fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 312180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (((getStrategy((AudioSystem::stream_type)i) == strategy) || 312280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent (NUM_STRATEGIES == strategy)) && 312380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent isStreamActive((AudioSystem::stream_type)i, inPastMs, sysTime)) { 312442fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent return true; 312542fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent } 312642fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent } 312742fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent return false; 312842fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent} 312942fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent 313080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::isStreamActive(AudioSystem::stream_type stream, 313180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent uint32_t inPastMs, 313280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent nsecs_t sysTime) const 313380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent{ 313480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (mRefCount[stream] != 0) { 313580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return true; 313680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 313780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (inPastMs == 0) { 313880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return false; 313980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 314080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (sysTime == 0) { 314180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime = systemTime(); 314280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 314380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 314480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return true; 314580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 314680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return false; 314780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent} 314880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent 314980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent 3150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd) 3151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 3153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 3154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 3155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 3157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 3159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 316070c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 3161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 3163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 3165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", device()); 3167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 3169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 3171f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 3172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3173f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3178f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3179f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioInputDescriptor class implementation 3180f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 31815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor(const IOProfile *profile) 318270c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mSamplingRate(0), mFormat((audio_format_t)0), mChannelMask((audio_channel_mask_t)0), 3183ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mDevice(AUDIO_DEVICE_NONE), mRefCount(0), 31845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mInputSource(0), mProfile(profile) 3185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd) 3189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 3191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 3192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 3193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 3195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3196f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 3197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 319870c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 3199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 3201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 3203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3206f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- StreamDescriptor class implementation 3210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3211c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric LaurentAudioPolicyManagerBase::StreamDescriptor::StreamDescriptor() 3212c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 3213c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 3214c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 3215c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 3216c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3217c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentint AudioPolicyManagerBase::StreamDescriptor::getVolumeIndex(audio_devices_t device) 3218c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 3219c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AudioPolicyManagerBase::getDeviceForVolume(device); 3220c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 3221c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 3222c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 3223c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 3224c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return mIndexCur.valueFor(device); 3225c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 3226c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3227c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::StreamDescriptor::dump(int fd) 3228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3229c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent const size_t SIZE = 256; 3230c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent char buffer[SIZE]; 3231c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent String8 result; 3232c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3233c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 3234c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 3235c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 3236c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 3237c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 3238c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.keyAt(i), 3239c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.valueAt(i)); 3240c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 3241c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 3242c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append("\n"); 3243c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3244c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent write(fd, result.string(), result.size()); 3245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- EffectDescriptor class implementation 3248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::EffectDescriptor::dump(int fd) 3250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 3252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 3253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 3254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 32551c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 3256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 3258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Session: %d\n", mSession); 3260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 3262f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3263582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 3264582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent result.append(buffer); 3265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3266f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3267f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3269f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 32705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// --- IOProfile class implementation 32715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 327270c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::HwModule::HwModule(const char *name) 327370c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0) 327470c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 327570c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 327670c236c9290732782d5267935af1475b8d5ae602Eric Laurent 327770c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::HwModule::~HwModule() 327870c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 327970c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 328070c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mOutputProfiles[i]; 328170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 328270c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 328370c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mInputProfiles[i]; 328470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 328570c236c9290732782d5267935af1475b8d5ae602Eric Laurent free((void *)mName); 328670c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 328770c236c9290732782d5267935af1475b8d5ae602Eric Laurent 328870c236c9290732782d5267935af1475b8d5ae602Eric Laurentvoid AudioPolicyManagerBase::HwModule::dump(int fd) 328970c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 329070c236c9290732782d5267935af1475b8d5ae602Eric Laurent const size_t SIZE = 256; 329170c236c9290732782d5267935af1475b8d5ae602Eric Laurent char buffer[SIZE]; 329270c236c9290732782d5267935af1475b8d5ae602Eric Laurent String8 result; 329370c236c9290732782d5267935af1475b8d5ae602Eric Laurent 329470c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - name: %s\n", mName); 329570c236c9290732782d5267935af1475b8d5ae602Eric Laurent result.append(buffer); 329670c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 329770c236c9290732782d5267935af1475b8d5ae602Eric Laurent result.append(buffer); 329870c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, result.string(), result.size()); 329970c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mOutputProfiles.size()) { 330070c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, " - outputs:\n", sizeof(" - outputs:\n")); 330170c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 3302599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " output %d:\n", i); 3303599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent write(fd, buffer, strlen(buffer)); 330470c236c9290732782d5267935af1475b8d5ae602Eric Laurent mOutputProfiles[i]->dump(fd); 330570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 330670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 330770c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mInputProfiles.size()) { 330870c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, " - inputs:\n", sizeof(" - inputs:\n")); 330970c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 3310599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " input %d:\n", i); 3311599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent write(fd, buffer, strlen(buffer)); 331270c236c9290732782d5267935af1475b8d5ae602Eric Laurent mInputProfiles[i]->dump(fd); 331370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 331470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 331570c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 331670c236c9290732782d5267935af1475b8d5ae602Eric Laurent 331770c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::IOProfile::IOProfile(HwModule *module) 33180977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent : mFlags((audio_output_flags_t)0), mModule(module) 33195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 33205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 33215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::IOProfile::~IOProfile() 33235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 332470c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 332570c236c9290732782d5267935af1475b8d5ae602Eric Laurent 332670c236c9290732782d5267935af1475b8d5ae602Eric Laurent// checks if the IO profile is compatible with specified parameters. By convention a value of 0 332770c236c9290732782d5267935af1475b8d5ae602Eric Laurent// means a parameter is don't care 332870c236c9290732782d5267935af1475b8d5ae602Eric Laurentbool AudioPolicyManagerBase::IOProfile::isCompatibleProfile(audio_devices_t device, 332970c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 333070c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t format, 333170c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 33320977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags) const 333370c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 333470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if ((mSupportedDevices & device) != device) { 333570c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 333670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 333770c236c9290732782d5267935af1475b8d5ae602Eric Laurent if ((mFlags & flags) != flags) { 333870c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 333970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 334070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (samplingRate != 0) { 334170c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 334270c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mSamplingRates.size(); i++) 334370c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 334470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mSamplingRates[i] == samplingRate) { 334570c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 334670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 334770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 334870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mSamplingRates.size()) { 334970c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 335070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 335170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 335270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (format != 0) { 335370c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 335470c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mFormats.size(); i++) 335570c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 335670c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mFormats[i] == format) { 335770c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 335870c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 335970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 336070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mFormats.size()) { 336170c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 336270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 336370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 336470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (channelMask != 0) { 336570c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 336670c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mChannelMasks.size(); i++) 336770c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 336870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mChannelMasks[i] == channelMask) { 336970c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 337070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 337170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 337270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mChannelMasks.size()) { 337370c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 337470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 337570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 337670c236c9290732782d5267935af1475b8d5ae602Eric Laurent return true; 33775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 33785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 33795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::IOProfile::dump(int fd) 33805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 33815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const size_t SIZE = 256; 33825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char buffer[SIZE]; 33835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent String8 result; 33845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 338570c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - sampling rates: "); 33865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 33875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 33885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent snprintf(buffer, SIZE, "%d", mSamplingRates[i]); 33895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 33905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mSamplingRates.size() - 1) ? "\n" : ", "); 33915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 33925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 339370c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - channel masks: "); 33945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 33955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 33965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent snprintf(buffer, SIZE, "%04x", mChannelMasks[i]); 33975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 33985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mChannelMasks.size() - 1) ? "\n" : ", "); 33995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 340170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - formats: "); 34025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 34035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 34045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent snprintf(buffer, SIZE, "%d", mFormats[i]); 34055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 34065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mFormats.size() - 1) ? "\n" : ", "); 34075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 340970c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - devices: %04x\n", mSupportedDevices); 34105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 341170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - flags: %04x\n", mFlags); 34125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 34135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, result.string(), result.size()); 34155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 34165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// --- audio_policy.conf file parsing 34185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentstruct StringToEnum { 34205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *name; 34215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t value; 34225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 34235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#define STRING_TO_ENUM(string) { #string, string } 34255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 34265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sDeviceNameToEnumTable[] = { 34285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE), 34295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER), 34305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET), 34315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE), 34325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO), 34335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP), 34345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL), 34355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET), 3436599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET), 3437599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE), 3438599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY), 3439599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB), 344048387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX), 34415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), 34425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), 34435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET), 34445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL), 34455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL), 34465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC), 344748387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX), 3448ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET), 3449ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET), 3450ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY), 34515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 34525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sFlagNameToEnumTable[] = { 34540977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT), 34550977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), 3456b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), 3457b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), 34585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 34595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sFormatNameToEnumTable[] = { 34615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT), 34625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT), 34635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_MP3), 34645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AAC), 34655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_VORBIS), 34665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 34675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sOutChannelsNameToEnumTable[] = { 34695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO), 34705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 34715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 34725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 34735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 34745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sInChannelsNameToEnumTable[] = { 34765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), 34775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), 347860758e27a4be8fc9ac1180f8a4055234e1702cc9Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK), 34795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 34805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentuint32_t AudioPolicyManagerBase::stringToEnum(const struct StringToEnum *table, 34835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent size_t size, 34845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *name) 34855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 34865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < size; i++) { 34875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(table[i].name, name) == 0) { 34885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("stringToEnum() found %s", table[i].name); 34895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return table[i].value; 34905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 34925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 34935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 34945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34950977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurentaudio_output_flags_t AudioPolicyManagerBase::parseFlagNames(char *name) 34965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 34975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t flag = 0; 34985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // it is OK to cast name to non const here as we are not going to use it after 35005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // strtok() modifies it 35015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *flagName = strtok(name, "|"); 35025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (flagName != NULL) { 35035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strlen(flagName) != 0) { 35045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flag |= stringToEnum(sFlagNameToEnumTable, 35055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sFlagNameToEnumTable), 35065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flagName); 35075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flagName = strtok(NULL, "|"); 35095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35100977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent return (audio_output_flags_t)flag; 35115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_devices_t AudioPolicyManagerBase::parseDeviceNames(char *name) 35145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 35155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t device = 0; 35165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *devName = strtok(name, "|"); 35185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (devName != NULL) { 35195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strlen(devName) != 0) { 35205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device |= stringToEnum(sDeviceNameToEnumTable, 35215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 35225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devName); 35235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devName = strtok(NULL, "|"); 35255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 3526c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi return device; 35275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadSamplingRates(char *name, IOProfile *profile) 35305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 35315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *str = strtok(name, "|"); 35325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35333cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling 35343cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // rates should be read from the output stream after it is opened for the first time 35353cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 35363cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.add(0); 35373cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 35383cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 35393cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 35405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 35415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t rate = atoi(str); 35425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (rate != 0) { 35435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadSamplingRates() adding rate %d", rate); 35445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSamplingRates.add(rate); 35455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 35475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 35495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadFormats(char *name, IOProfile *profile) 35525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 35535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *str = strtok(name, "|"); 35545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mFormats indicates the supported formats 35563cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // should be read from the output stream after it is opened for the first time 35573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 35583cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mFormats.add((audio_format_t)0); 35593cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 35603cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 35613cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 35625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 35635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable, 35645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 35655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str); 35665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (format != 0) { 35675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mFormats.add(format); 35685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 35705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 35725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadInChannels(char *name, IOProfile *profile) 35755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 35765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *str = strtok(name, "|"); 35775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInChannels() %s", name); 35793cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 35803cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 35813cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.add((audio_channel_mask_t)0); 35823cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 35833cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 35843cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 35855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 35865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_channel_mask_t channelMask = 35875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 35885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 35895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str); 35905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (channelMask != 0) { 35915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInChannels() adding channelMask %04x", channelMask); 35925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mChannelMasks.add(channelMask); 35935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 35955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 35975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadOutChannels(char *name, IOProfile *profile) 36005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 36015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *str = strtok(name, "|"); 36023cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 36033cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("loadOutChannels() %s", name); 36043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 36053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mChannelMasks indicates the supported channel 36063cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // masks should be read from the output stream after it is opened for the first time 36073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 36083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.add((audio_channel_mask_t)0); 36093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 36103cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 36115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 36133cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_channel_mask_t channelMask = 36143cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 36153cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 36163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent str); 36175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (channelMask != 0) { 36185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mChannelMasks.add(channelMask); 36195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 36215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 36235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 36245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 362570c236c9290732782d5267935af1475b8d5ae602Eric Laurentstatus_t AudioPolicyManagerBase::loadInput(cnode *root, HwModule *module) 36265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 36275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = root->first_child; 36285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = new IOProfile(module); 36305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 36325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 36335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadSamplingRates((char *)node->value, profile); 36345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 36355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadFormats((char *)node->value, profile); 36365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 36375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadInChannels((char *)node->value, profile); 36385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 36395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices = parseDeviceNames((char *)node->value); 36405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 36425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 3643ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(profile->mSupportedDevices == AUDIO_DEVICE_NONE, 36445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported devices"); 36455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 36465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported channel masks"); 36475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 36485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported sampling rates"); 36495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 36505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported formats"); 3651ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((profile->mSupportedDevices != AUDIO_DEVICE_NONE) && 36525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mChannelMasks.size() != 0) && 36535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mSamplingRates.size() != 0) && 36545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mFormats.size() != 0)) { 36555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInput() adding input mSupportedDevices %04x", profile->mSupportedDevices); 36575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 365870c236c9290732782d5267935af1475b8d5ae602Eric Laurent module->mInputProfiles.add(profile); 36595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 36605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 36615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent delete profile; 36625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return BAD_VALUE; 36635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 36655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 366670c236c9290732782d5267935af1475b8d5ae602Eric Laurentstatus_t AudioPolicyManagerBase::loadOutput(cnode *root, HwModule *module) 36675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 36685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = root->first_child; 36695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = new IOProfile(module); 36715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 36735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 36745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadSamplingRates((char *)node->value, profile); 36755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 36765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadFormats((char *)node->value, profile); 36775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 36785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadOutChannels((char *)node->value, profile); 36795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 36805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices = parseDeviceNames((char *)node->value); 36815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FLAGS_TAG) == 0) { 36825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mFlags = parseFlagNames((char *)node->value); 36835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 36855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 3686ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(profile->mSupportedDevices == AUDIO_DEVICE_NONE, 36875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported devices"); 36885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 36895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported channel masks"); 36905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 36915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported sampling rates"); 36925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 36935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported formats"); 3694ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((profile->mSupportedDevices != AUDIO_DEVICE_NONE) && 36955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mChannelMasks.size() != 0) && 36965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mSamplingRates.size() != 0) && 36975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mFormats.size() != 0)) { 36985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadOutput() adding output mSupportedDevices %04x, mFlags %04x", 37005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices, profile->mFlags); 37015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 370270c236c9290732782d5267935af1475b8d5ae602Eric Laurent module->mOutputProfiles.add(profile); 37035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 37045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 37055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent delete profile; 37065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return BAD_VALUE; 37075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 37095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadHwModule(cnode *root) 37115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 37125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, OUTPUTS_TAG); 37135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status_t status = NAME_NOT_FOUND; 371470c236c9290732782d5267935af1475b8d5ae602Eric Laurent 371570c236c9290732782d5267935af1475b8d5ae602Eric Laurent HwModule *module = new HwModule(root->name); 371670c236c9290732782d5267935af1475b8d5ae602Eric Laurent 37175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node != NULL) { 37185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_A2DP) == 0) { 37195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mHasA2dp = true; 3720599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } else if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_USB) == 0) { 3721599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mHasUsb = true; 372248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } else if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX) == 0) { 372348387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi mHasRemoteSubmix = true; 37245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 3725599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent 37265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 37275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 37285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModule() loading output %s", node->name); 372970c236c9290732782d5267935af1475b8d5ae602Eric Laurent status_t tmpStatus = loadOutput(node, module); 37305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 37315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status = tmpStatus; 37325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 37345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = config_find(root, INPUTS_TAG); 37375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node != NULL) { 37385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 37395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 37405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModule() loading input %s", node->name); 374170c236c9290732782d5267935af1475b8d5ae602Eric Laurent status_t tmpStatus = loadInput(node, module); 37425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 37435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status = tmpStatus; 37445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 37465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NO_ERROR) { 374970c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules.add(module); 375070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } else { 375170c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete module; 37525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 37545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadHwModules(cnode *root) 37565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 37575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); 37585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node == NULL) { 37595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 37605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 37635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 37645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModules() loading module %s", node->name); 37655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadHwModule(node); 37665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 37675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 37695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadGlobalConfig(cnode *root) 37715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 37725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, GLOBAL_CONFIG_TAG); 37735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node == NULL) { 37745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 37755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 37775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 37785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { 37795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAttachedOutputDevices = parseDeviceNames((char *)node->value); 3780ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(mAttachedOutputDevices == AUDIO_DEVICE_NONE, 3781c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi "loadGlobalConfig() no attached output devices"); 37825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mAttachedOutputDevices %04x", mAttachedOutputDevices); 37835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { 37845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mDefaultOutputDevice = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable, 37855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 37865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (char *)node->value); 3787ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(mDefaultOutputDevice == AUDIO_DEVICE_NONE, 3788c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi "loadGlobalConfig() default device not specified"); 37895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mDefaultOutputDevice %04x", mDefaultOutputDevice); 37905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { 3791ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableInputDevices = parseDeviceNames((char *)node->value) & ~AUDIO_DEVICE_BIT_IN; 37925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mAvailableInputDevices %04x", mAvailableInputDevices); 37935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 37955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 37975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentstatus_t AudioPolicyManagerBase::loadAudioPolicyConfig(const char *path) 37995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 38005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *root; 38015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *data; 38025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 38035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent data = (char *)load_file(path, NULL); 38045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (data == NULL) { 38055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return -ENODEV; 38065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 38075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent root = config_node("", ""); 38085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent config_load(root, data); 38095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 38105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadGlobalConfig(root); 38115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadHwModules(root); 38125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 38135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent config_free(root); 38145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent free(root); 38155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent free(data); 38165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 38175ec145df7708564d385fd3fb764085321cf4c253Dima Zavin ALOGI("loadAudioPolicyConfig() loaded %s\n", path); 38185ec145df7708564d385fd3fb764085321cf4c253Dima Zavin 38195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 38205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 3821f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3822739022f26a7127ba76a98dda65411496086114a7Dima Zavinvoid AudioPolicyManagerBase::defaultAudioPolicyConfig(void) 3823739022f26a7127ba76a98dda65411496086114a7Dima Zavin{ 3824739022f26a7127ba76a98dda65411496086114a7Dima Zavin HwModule *module; 3825739022f26a7127ba76a98dda65411496086114a7Dima Zavin IOProfile *profile; 3826739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3827739022f26a7127ba76a98dda65411496086114a7Dima Zavin mDefaultOutputDevice = AUDIO_DEVICE_OUT_SPEAKER; 3828739022f26a7127ba76a98dda65411496086114a7Dima Zavin mAttachedOutputDevices = AUDIO_DEVICE_OUT_SPEAKER; 3829ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableInputDevices = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; 3830739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3831739022f26a7127ba76a98dda65411496086114a7Dima Zavin module = new HwModule("primary"); 3832739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3833739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile = new IOProfile(module); 3834739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSamplingRates.add(44100); 3835739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 3836739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO); 3837739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSupportedDevices = AUDIO_DEVICE_OUT_SPEAKER; 3838739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY; 3839739022f26a7127ba76a98dda65411496086114a7Dima Zavin module->mOutputProfiles.add(profile); 3840739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3841739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile = new IOProfile(module); 3842739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSamplingRates.add(8000); 3843739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 3844739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO); 3845739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSupportedDevices = AUDIO_DEVICE_IN_BUILTIN_MIC; 3846739022f26a7127ba76a98dda65411496086114a7Dima Zavin module->mInputProfiles.add(profile); 3847739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3848739022f26a7127ba76a98dda65411496086114a7Dima Zavin mHwModules.add(module); 3849739022f26a7127ba76a98dda65411496086114a7Dima Zavin} 3850f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3851f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin}; // namespace android 3852