AudioPolicyManagerBase.cpp revision 727fef1b1a8cb6d6609ec99a749fcd9573a3417d
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" 184e57a1d4979c2644dd8999dc5759b10ed0af56e9Eric Laurent//#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> 40a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald#include <cutils/properties.h> 41f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 42e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinnamespace android_audio_legacy { 43f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 44f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 45f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyInterface implementation 46f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 47f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 48f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 49c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivistatus_t AudioPolicyManagerBase::setDeviceConnectionState(audio_devices_t device, 50f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state, 51f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 52f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent SortedVector <audio_io_handle_t> outputs; 54f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 556a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); 56f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 57f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // connect/disconnect only 1 device at a time 58ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; 59f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 60f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { 615efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid address: %s", device_address); 62f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 63f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 64f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 65f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output devices 66c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_output_device(device)) { 67f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 68c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (!mHasA2dp && audio_is_a2dp_device(device)) { 6948387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("setDeviceConnectionState() invalid A2DP device: %x", device); 70f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 71f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 72c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (!mHasUsb && audio_is_usb_device(device)) { 7348387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("setDeviceConnectionState() invalid USB audio device: %x", device); 7448387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi return BAD_VALUE; 7548387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 7648387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi if (!mHasRemoteSubmix && audio_is_remote_submix_device((audio_devices_t)device)) { 7748387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("setDeviceConnectionState() invalid remote submix audio device: %x", device); 78599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent return BAD_VALUE; 79599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 80f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 81c952527e6f89d5427881462823514be9d79f13e6Eric Laurent // save a copy of the opened output descriptors before any output is opened or closed 82c952527e6f89d5427881462823514be9d79f13e6Eric Laurent // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() 83c952527e6f89d5427881462823514be9d79f13e6Eric Laurent mPreviousOutputs = mOutputs; 84f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 85f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 86f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device connection 87f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: 88f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableOutputDevices & device) { 8964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %x", device); 90f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 91f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 926a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() connecting device %x", device); 93f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 94c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) { 953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return INVALID_OPERATION; 963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %d outputs", 983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.size()); 99f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // register new device as available 100f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device); 101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1023cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!outputs.isEmpty()) { 1033cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8 paramStr; 104c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (mHasA2dp && audio_is_a2dp_device(device)) { 1053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle A2DP device connection 1063cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioParameter param; 1073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), String8(device_address)); 1083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent paramStr = param.toString(); 1093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 1103cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mA2dpSuspended = false; 111c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (audio_is_bluetooth_sco_device(device)) { 1123cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle SCO device connection 1133cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 114c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mHasUsb && audio_is_usb_device(device)) { 1153cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle USB device connection 1163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mUsbCardAndDevice = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 1173cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent paramStr = mUsbCardAndDevice; 1183cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 11948387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi // not currently handling multiple simultaneous submixes: ignoring remote submix 12048387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi // case and address 1213cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!paramStr.isEmpty()) { 1223cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t i = 0; i < outputs.size(); i++) { 1233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mpClientInterface->setParameters(outputs[i], paramStr); 1243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 126f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 127f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 128f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device disconnection 129f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 130f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableOutputDevices & device)) { 13164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %x", device); 132f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 133f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 134f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1356a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() disconnecting device %x", device); 136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // remove device from available output devices 137f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device); 138f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 139c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi checkOutputsForDevice(device, state, outputs); 140c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (mHasA2dp && audio_is_a2dp_device(device)) { 1413cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle A2DP device disconnection 142b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpDeviceAddress = ""; 143b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpSuspended = false; 144c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (audio_is_bluetooth_sco_device(device)) { 1453cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle SCO device disconnection 146b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mScoDeviceAddress = ""; 147c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mHasUsb && audio_is_usb_device(device)) { 1483cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle USB device disconnection 149599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mUsbCardAndDevice = ""; 150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 15148387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi // not currently handling multiple simultaneous submixes: ignoring remote submix 15248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi // case and address 153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 1565efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 162b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // outputs must be closed after checkOutputForAllStrategies() is executed 1633cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!outputs.isEmpty()) { 1643cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t i = 0; i < outputs.size(); i++) { 165a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]); 1663cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // close unused outputs after device disconnection or direct outputs that have been 1673cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // opened by checkOutputsForDevice() to query dynamic parameters 1683cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if ((state == AudioSystem::DEVICE_STATE_UNAVAILABLE) || 169a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) && 170a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald (desc->mDirectOpenCount == 0))) { 1713cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent closeOutput(outputs[i]); 1723cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1733cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 176c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 1775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1782c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent // do not force device change on duplicated output because if device is 0, it will 1792c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent // also force a device 0 for the two outputs it is duplicated to which may override 1802c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent // a valid device selection on those outputs. 18176e97d3950f2654adbb0a415218b6d048200c395Eric Laurent setOutputDevice(mOutputs.keyAt(i), 18276e97d3950f2654adbb0a415218b6d048200c395Eric Laurent getNewDevice(mOutputs.keyAt(i), true /*fromCache*/), 1832c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent !mOutputs.valueAt(i)->isDuplicated(), 18476e97d3950f2654adbb0a415218b6d048200c395Eric Laurent 0); 1855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 187c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET) { 188c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_WIRED_HEADSET; 189c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO || 190c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET || 191c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 192c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 196f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input devices 198c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_input_device(device)) { 199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device connection 203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: { 204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableInputDevices & device) { 20564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %d", device); 206f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 208ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableInputDevices = mAvailableInputDevices | (device & ~AUDIO_DEVICE_BIT_IN); 209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 211f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device disconnection 213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableInputDevices & device)) { 21564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %d", device); 216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAvailableInputDevices = (audio_devices_t) (mAvailableInputDevices & ~device); 219f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 2225efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 229f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 230ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { 2316a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() changing device from %x to %x for input %d", 232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() invalid device: %x", device); 244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 247c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel TriviAudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(audio_devices_t device, 248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE; 251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 address = String8(device_address); 252c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_output_device(device)) { 253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableOutputDevices) { 254c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_a2dp_device(device) && 2555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (!mHasA2dp || (address != "" && mA2dpDeviceAddress != address))) { 256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 258c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_bluetooth_sco_device(device) && 259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin address != "" && mScoDeviceAddress != address) { 260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 262c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_usb_device(device) && 263599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent (!mHasUsb || (address != "" && mUsbCardAndDevice != address))) { 26448387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("getDeviceConnectionState() invalid device: %x", device); 26548387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi return state; 26648387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 26748387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi if (audio_is_remote_submix_device((audio_devices_t)device) && !mHasRemoteSubmix) { 268599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent return state; 269599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 271f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 272c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (audio_is_input_device(device)) { 273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableInputDevices) { 274f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 275f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 277f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setPhoneState(int state) 282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2836a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() state %d", state); 284ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent audio_devices_t newDevice = AUDIO_DEVICE_NONE; 285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state < 0 || state >= AudioSystem::NUM_MODES) { 28664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() invalid state %d", state); 287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == mPhoneState ) { 29164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() setting same state %d", state); 292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 295f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if leaving call state, handle special case of active streams 296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 297f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 2986a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, true); 301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store previous phone state for management of sonification strategy below 305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int oldState = mPhoneState; 306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mPhoneState = state; 307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool force = false; 308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // are we entering or starting a call 310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isStateInCall(oldState) && isStateInCall(state)) { 3116a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Entering call in setPhoneState()"); 312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when starting a call 313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(oldState) && !isStateInCall(state)) { 3166a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Exiting call in setPhoneState()"); 317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when exiting a call 318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(state) && (state != oldState)) { 3216a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when switching between telephony and VoIP 323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check for device and output changes triggered by new phone state 3285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/); 329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 331c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 333b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when ending call 336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 337ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) { 338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin newDevice = hwOutputDesc->device(); 339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int delayMs = 0; 342772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani if (isStateInCall(state)) { 34380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent nsecs_t sysTime = systemTime(); 344772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani for (size_t i = 0; i < mOutputs.size(); i++) { 345772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani AudioOutputDescriptor *desc = mOutputs.valueAt(i); 34680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent // mute media and sonification strategies and delay device switch by the largest 34780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent // latency of any output where either strategy is active. 34880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent // This avoid sending the ring tone or music tail into the earpiece or headset. 34980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if ((desc->isStrategyActive(STRATEGY_MEDIA, 35080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 35180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime) || 35280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent desc->isStrategyActive(STRATEGY_SONIFICATION, 35380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 35480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime)) && 35580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent (delayMs < (int)desc->mLatency*2)) { 35680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent delayMs = desc->mLatency*2; 357772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani } 35880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); 35980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, 36080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); 36180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i)); 36280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS, 36380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/)); 364772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani } 365772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani } 366772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani 367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // change routing is necessary 368b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setOutputDevice(mPrimaryOutput, newDevice, force, delayMs); 369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 370f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if entering in call state, handle special case of active streams 371f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 372f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(state)) { 3736a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, true, true); 376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == AudioSystem::MODE_RINGTONE && 381f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 382f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = true; 383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = false; 385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) 389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3906a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool forceVolumeReeval = false; 393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(usage) { 394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_COMMUNICATION: 395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO && 396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 39764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_MEDIA: 404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP && 405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 4071afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE && 40831363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi config != AudioSystem::FORCE_NO_BT_A2DP) { 40964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_RECORD: 415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY && 416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 41764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_DOCK: 423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK && 424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_BT_DESK_DOCK && 425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_DIGITAL_DOCK) { 42864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 432f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 433738207def5f691d605ae33d041116829a74513a9Eric Laurent case AudioSystem::FOR_SYSTEM: 434738207def5f691d605ae33d041116829a74513a9Eric Laurent if (config != AudioSystem::FORCE_NONE && 435738207def5f691d605ae33d041116829a74513a9Eric Laurent config != AudioSystem::FORCE_SYSTEM_ENFORCED) { 436738207def5f691d605ae33d041116829a74513a9Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config); 437738207def5f691d605ae33d041116829a74513a9Eric Laurent } 438738207def5f691d605ae33d041116829a74513a9Eric Laurent forceVolumeReeval = true; 439738207def5f691d605ae33d041116829a74513a9Eric Laurent mForceUse[usage] = config; 440738207def5f691d605ae33d041116829a74513a9Eric Laurent break; 441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 44264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid usage %d", usage); 443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 444f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // check for device and output changes triggered by new force usage 447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 449c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 4505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 4515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 4525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, true /*fromCache*/); 453ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE)); 454ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) { 4555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent applyStreamVolumes(output, newDevice, 0, true); 4565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 461f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 4625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 463ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { 4646a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() changing device from %x to %x for input %d", 465f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 466f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 470f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage) 476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mForceUse[usage]; 478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setSystemProperty(const char* property, const char* value) 481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 4826a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setSystemProperty() property %s, value %s", property, value); 483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4853cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric LaurentAudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getProfileForDirectOutput( 4863cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_devices_t device, 48770c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 48870c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t format, 48970c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 4900977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags) 49170c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 49270c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 49370c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 49470c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 49570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 49670c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { 497a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; 498a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { 499a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (profile->isCompatibleProfile(device, samplingRate, format, 500a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald channelMask, 501a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) { 502a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (mAvailableOutputDevices & profile->mSupportedDevices) { 503a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return mHwModules[i]->mOutputProfiles[j]; 504a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 505a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 506a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } else if (flags & AUDIO_OUTPUT_FLAG_DIRECT) { 507a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (profile->isCompatibleProfile(device, samplingRate, format, 5083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent channelMask, 5093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AUDIO_OUTPUT_FLAG_DIRECT)) { 510a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (mAvailableOutputDevices & profile->mSupportedDevices) { 511a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return mHwModules[i]->mOutputProfiles[j]; 512a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 513a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 514a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 51570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 51670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 51770c236c9290732782d5267935af1475b8d5ae602Eric Laurent return 0; 51870c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 51970c236c9290732782d5267935af1475b8d5ae602Eric Laurent 520f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream, 521f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 522f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 52370c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 524b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald AudioSystem::output_flags flags, 525b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald const audio_offload_info_t *offloadInfo) 526f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 527f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t output = 0; 528f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t latency = 0; 529f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); 5305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 531a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x", 532a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald device, stream, samplingRate, format, channelMask, flags); 533f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 534f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 535f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mCurOutput != 0) { 53670c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", 537f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 538f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 539f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput] == 0) { 5406a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() opening test output"); 5413cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = mTestDevice; 543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = mTestSamplingRate; 544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFormat = mTestFormat; 54570c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mChannelMask = mTestChannels; 546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = mTestLatencyMs; 5470977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent outputDesc->mFlags = (audio_output_flags_t)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0); 548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 54970c236c9290732782d5267935af1475b8d5ae602Eric Laurent mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice, 550f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 551f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 55270c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 553f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 554b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald outputDesc->mFlags, 555b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald offloadInfo); 556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput]) { 557f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 558f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"),mCurOutput); 559f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(mTestOutputs[mCurOutput], outputDesc); 561f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 562f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 563f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mTestOutputs[mCurOutput]; 564f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 565f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 566f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 567f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a direct output if required by specified parameters 568a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald //force direct flag if offload flag is set: offloading implies a direct output stream 569a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // and all common behaviors are driven by checking only the direct flag 570a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // this should normally be set appropriately in the policy configuration file 571a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 572a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald flags = (AudioSystem::output_flags)(flags | AUDIO_OUTPUT_FLAG_DIRECT); 573a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 574a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 5753cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = getProfileForDirectOutput(device, 5763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent samplingRate, 5773cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent format, 5783cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent channelMask, 5793cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (audio_output_flags_t)flags); 5803cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile != NULL) { 5815a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent AudioOutputDescriptor *outputDesc = NULL; 582f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5835a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 5845a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 5855a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (!desc->isDuplicated() && (profile == desc->mProfile)) { 5865a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc = desc; 5875a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent // reuse direct output if currently open and configured with same parameters 5885a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if ((samplingRate == outputDesc->mSamplingRate) && 5895a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent (format == outputDesc->mFormat) && 5905a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent (channelMask == outputDesc->mChannelMask)) { 5915a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc->mDirectOpenCount++; 592a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i)); 5935a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent return mOutputs.keyAt(i); 5945a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 5955a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 5965a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 5975a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent // close direct output if currently open and configured with different parameters 5985a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (outputDesc != NULL) { 5995a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent closeOutput(outputDesc->mId); 6005a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 6015a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc = new AudioOutputDescriptor(profile); 602f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = device; 603f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = samplingRate; 60470c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mFormat = (audio_format_t)format; 60570c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mChannelMask = (audio_channel_mask_t)channelMask; 606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = 0; 607a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags); 608f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 609f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mStopTime[stream] = 0; 6105a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc->mDirectOpenCount = 1; 6113cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent output = mpClientInterface->openOutput(profile->mModule->mHandle, 61270c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 613f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 61570c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 616f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 617a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald outputDesc->mFlags, 618a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo); 619f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6209f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi // only accept an output with the requested parameters 621f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == 0 || 622f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || 623f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != 0 && format != outputDesc->mFormat) || 62470c236c9290732782d5267935af1475b8d5ae602Eric Laurent (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { 6253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," 6263cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent "format %d %d, channelMask %04x %04x", output, samplingRate, 6273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, 6283cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputDesc->mChannelMask); 629f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output != 0) { 630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 631f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 632f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete outputDesc; 633f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 63545c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t srcOutput = getOutputForEffect(); 636f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(output, outputDesc); 63745c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 63845c763947b657b347211dc9388754e05d30d0467Eric Laurent if (dstOutput == output) { 63945c763947b657b347211dc9388754e05d30d0467Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput); 64045c763947b657b347211dc9388754e05d30d0467Eric Laurent } 6415a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent mPreviousOutputs = mOutputs; 6425a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent ALOGV("getOutput() returns new direct output %d", output); 643f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 644f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 645f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6469f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi // ignoring channel mask due to downmix capability in mixer 6479f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi 648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a non direct output 649f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 650a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // for non direct outputs, only PCM is supported 651a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (audio_is_linear_pcm((audio_format_t)format)) { 652a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // get which output is suitable for the specified stream. The actual 653a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // routing change will happen when startOutput() will be called 654a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs); 655f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 656a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald output = selectOutput(outputs, flags); 657a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 658a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d," 65970c236c9290732782d5267935af1475b8d5ae602Eric Laurent "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); 660f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("getOutput() returns output %d", output); 6625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 665f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::selectOutput(const SortedVector<audio_io_handle_t>& outputs, 6675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioSystem::output_flags flags) 6685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 6695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // select one output among several that provide a path to a particular device or set of 6705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // devices (the list was previously build by getOutputsForDevice()). 6715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // The priority is as follows: 6725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 1: the output with the highest number of requested policy flags 6735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 2: the primary output 6745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 3: the first output in the list 6755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputs.size() == 0) { 6775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 6785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputs.size() == 1) { 6805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputs[0]; 6815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent int maxCommonFlags = 0; 6845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t outputFlags = 0; 6855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t outputPrimary = 0; 6865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 6875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 6885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]); 6895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!outputDesc->isDuplicated()) { 6905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent int commonFlags = (int)AudioSystem::popCount(outputDesc->mProfile->mFlags & flags); 6915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (commonFlags > maxCommonFlags) { 6925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputFlags = outputs[i]; 6935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent maxCommonFlags = commonFlags; 6945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); 6955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6960977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 6975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputPrimary = outputs[i]; 6985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 6995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 7025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputFlags != 0) { 7035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputFlags; 7045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputPrimary != 0) { 7065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputPrimary; 7075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 7095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputs[0]; 7105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 7115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 712f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, 713f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 715f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7166a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 717f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 71964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startOutput() unknow output %d", output); 720f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 722f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 723f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 724f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // increment usage count for this stream on the requested output: 726f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE that the usage count is the same for duplicated output and hardware output which is 7275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // necessary for a correct control of hardware output routing by startOutput() and stopOutput() 728f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, 1); 729f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->mRefCount[stream] == 1) { 7315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 732b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent routing_strategy strategy = getStrategy(stream); 733b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent bool shouldWait = (strategy == STRATEGY_SONIFICATION) || 734b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent (strategy == STRATEGY_SONIFICATION_RESPECTFUL); 735b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t waitMs = 0; 7365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool force = false; 7375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 7385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 739b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (desc != outputDesc) { 740b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // force a device change if any other output is managed by the same hw 741b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // module and has a current device selection that differs from selected device. 742b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // In this case, the audio HAL must receive the new device selection so that it can 743b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // change the device currently selected by the other active output. 744b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (outputDesc->sharesHwModuleWith(desc) && 7455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent desc->device() != newDevice) { 746b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent force = true; 747b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 748b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // wait for audio on other active outputs to be presented when starting 749b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // a notification so that audio focus effect can propagate. 75042fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent uint32_t latency = desc->latency(); 75142fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { 75242fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent waitMs = latency; 753b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 7545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 756b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); 757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // handle special case for sonification while in call 7595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isInCall()) { 7605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleIncallSonification(stream, true, false); 7615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 762c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 7635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // apply volume rules for current stream and device if necessary 7645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent checkAndSetVolume(stream, 765c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi mStreams[stream].getVolumeIndex(newDevice), 7665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent output, 7675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice); 76812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 7695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // update the outputs if starting an output with a stream that can affect notification 7705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // routing 7715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleNotificationRoutingForStream(stream); 772b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (waitMs > muteWaitMs) { 773b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent usleep((waitMs - muteWaitMs) * 2 * 1000); 774b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 7755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 776f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 777f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 778f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, 781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 782f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 783f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7846a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 785f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 78764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() unknow output %d", output); 788f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 789f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 790f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 791f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 792f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 793f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle special case for sonification while in call 794f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 795f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, false); 796f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 797f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 798f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream] > 0) { 799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // decrement usage count of this stream on the output 800f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, -1); 801f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store time at which the stream was stopped - see isStreamActive() 8025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->mRefCount[stream] == 0) { 8035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStopTime[stream] = systemTime(); 8045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 8055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // delay the device switch by twice the latency because stopOutput() is executed when 8065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // the track stop() command is received and at that time the audio track buffer can 8075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // still contain data that needs to be drained. The latency only covers the audio HAL 8085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // and kernel buffers. Also the latency does not always include additional delay in the 8095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // audio path (audio DSP, CODEC ...) 8105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); 8115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 8125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // force restoring the device selection on other active outputs if it differs from the 8135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // one being selected for this output 8145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 8155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(i); 8165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 8175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (curOutput != output && 81880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent desc->isActive() && 8195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->sharesHwModuleWith(desc) && 820a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald (newDevice != desc->device())) { 8215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(curOutput, 8225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent getNewDevice(curOutput, false /*fromCache*/), 8235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent true, 8245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mLatency*2); 8255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 8265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 8275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // update the outputs if stopping one with a stream that can affect notification routing 8285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleNotificationRoutingForStream(stream); 829f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 830f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 831f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 83264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() refcount is already 0 for output %d", output); 833f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 834f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 835f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 836f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 837f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output) 838f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8396a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseOutput() %d", output); 840f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 841f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 84264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseOutput() releasing unknown output %d", output); 843f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 844f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 847f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int testIndex = testOutputIndex(output); 848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (testIndex != 0) { 849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 85080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (outputDesc->isActive()) { 851f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 852f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(index); 853f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(output); 854f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[testIndex] = 0; 855f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 856f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 857f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 858f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 859f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 8605a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(index); 8615a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (desc->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) { 8625a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (desc->mDirectOpenCount <= 0) { 8635a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent ALOGW("releaseOutput() invalid open count %d for output %d", 8645a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent desc->mDirectOpenCount, output); 8655a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent return; 8665a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 8675a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (--desc->mDirectOpenCount == 0) { 8685a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent closeOutput(output); 86945c763947b657b347211dc9388754e05d30d0467Eric Laurent // If effects where present on the output, audioflinger moved them to the primary 87045c763947b657b347211dc9388754e05d30d0467Eric Laurent // output by default: move them back to the appropriate output. 87145c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 87245c763947b657b347211dc9388754e05d30d0467Eric Laurent if (dstOutput != mPrimaryOutput) { 87345c763947b657b347211dc9388754e05d30d0467Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput); 87445c763947b657b347211dc9388754e05d30d0467Eric Laurent } 8755a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 876f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 877f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 878f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 87945c763947b657b347211dc9388754e05d30d0467Eric Laurent 880f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource, 881f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 882f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 88370c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::audio_in_acoustics acoustics) 885f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 886f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t input = 0; 887f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device = getDeviceForInputSource(inputSource); 888f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 88970c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x", 89070c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputSource, samplingRate, format, channelMask, acoustics); 891f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 892ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 8935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW("getInput() could not find device for inputSource %d", inputSource); 894f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 895f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 896f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 897f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // adapt channel selection to input source 898f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(inputSource) { 899f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 90070c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = AudioSystem::CHANNEL_IN_VOICE_UPLINK; 901f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 902f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 90370c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = AudioSystem::CHANNEL_IN_VOICE_DNLINK; 904f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 905f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 90670c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK); 907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 910f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 911f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 9125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = getInputProfile(device, 9135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent samplingRate, 9145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent format, 91570c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask); 9165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (profile == NULL) { 9175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d," 91870c236c9290732782d5267935af1475b8d5ae602Eric Laurent "channelMask %04x", 91970c236c9290732782d5267935af1475b8d5ae602Eric Laurent device, samplingRate, format, channelMask); 92070c236c9290732782d5267935af1475b8d5ae602Eric Laurent return 0; 92170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 92270c236c9290732782d5267935af1475b8d5ae602Eric Laurent 92370c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (profile->mModule->mHandle == 0) { 9243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); 9255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 9265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 9275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 9285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile); 929f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 930f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mInputSource = inputSource; 931f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = device; 932f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mSamplingRate = samplingRate; 93370c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputDesc->mFormat = (audio_format_t)format; 93470c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputDesc->mChannelMask = (audio_channel_mask_t)channelMask; 935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 93670c236c9290732782d5267935af1475b8d5ae602Eric Laurent input = mpClientInterface->openInput(profile->mModule->mHandle, 93770c236c9290732782d5267935af1475b8d5ae602Eric Laurent &inputDesc->mDevice, 938f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mSamplingRate, 939f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mFormat, 94070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &inputDesc->mChannelMask); 941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // only accept input with the exact requested set of parameters 943f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input == 0 || 944f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != inputDesc->mSamplingRate) || 945f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != inputDesc->mFormat) || 94670c236c9290732782d5267935af1475b8d5ae602Eric Laurent (channelMask != inputDesc->mChannelMask)) { 94770c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getInput() failed opening input: samplingRate %d, format %d, channelMask %d", 94870c236c9290732782d5267935af1475b8d5ae602Eric Laurent samplingRate, format, channelMask); 949f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input != 0) { 950f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 951f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 952f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete inputDesc; 953f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 954f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 955f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.add(input, inputDesc); 956f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return input; 957f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 958f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 959f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startInput(audio_io_handle_t input) 960f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 9616a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startInput() input %d", input); 962f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 963f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 96464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startInput() unknow input %d", input); 965f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 966f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 967f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 968f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 969f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 970f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestInput == 0) 971f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 972f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 973fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent // refuse 2 active AudioRecord clients at the same time except if the active input 974fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent // uses AUDIO_SOURCE_HOTWORD in which case it is closed. 975fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent audio_io_handle_t activeInput = getActiveInput(); 976fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent if (!isVirtualInputDevice(inputDesc->mDevice) && activeInput != 0) { 977fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput); 978fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) { 979fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent ALOGW("startInput() preempting already started low-priority input %d", activeInput); 980fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent stopInput(activeInput); 981fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent releaseInput(activeInput); 982fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent } else { 983fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent ALOGW("startInput() input %d failed: other input already started..", input); 984fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent return INVALID_OPERATION; 985fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent } 986f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 987f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 98966707435156d8d99d795271a7bd54943065b4c2dEric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 99066707435156d8d99d795271a7bd54943065b4c2dEric Laurent if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { 99166707435156d8d99d795271a7bd54943065b4c2dEric Laurent inputDesc->mDevice = newDevice; 99266707435156d8d99d795271a7bd54943065b4c2dEric Laurent } 993b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown 994b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown // automatically enable the remote submix output when input is started 995b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown if (audio_is_remote_submix_device(inputDesc->mDevice)) { 996b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 997b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown AudioSystem::DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 998b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown } 999b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown 1000f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 1001f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice); 1002f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1003fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent int aliasSource = (inputDesc->mInputSource == AUDIO_SOURCE_HOTWORD) ? 1004fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent AUDIO_SOURCE_VOICE_RECOGNITION : inputDesc->mInputSource; 1005fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent 1006fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent param.addInt(String8(AudioParameter::keyInputSource), aliasSource); 10076a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 1008f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1009f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 1010f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1011f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 1; 1012f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1013f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1014f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1015f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopInput(audio_io_handle_t input) 1016f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 10176a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopInput() input %d", input); 1018f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 1019f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 102064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() unknow input %d", input); 1021f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 1022f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1023f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 1024f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1025f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (inputDesc->mRefCount == 0) { 102664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() input %d already stopped", input); 1027f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1028f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1029b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown // automatically disable the remote submix output when input is stopped 1030b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1031b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 1032b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown AudioSystem::DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 1033b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown } 1034b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown 1035f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 1036f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), 0); 1037f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 1038f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 1039f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1040f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1041f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1042f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1043f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseInput(audio_io_handle_t input) 1044f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 10456a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() %d", input); 1046f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 1047f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 104864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseInput() releasing unknown input %d", input); 1049f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 1050f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1051f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 1052f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(index); 1053f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.removeItem(input); 10546a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() exit"); 1055f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1056f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1057f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream, 1058f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMin, 1059f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMax) 1060f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 10616a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 1062f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (indexMin < 0 || indexMin >= indexMax) { 106364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 1064f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 1065f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1066f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMin = indexMin; 1067f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMax = indexMax; 1068f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1069f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1070c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, 1071c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 1072c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 1073f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1074f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1075f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 1076f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 1077f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1078c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 1079c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 1080c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1081f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1082f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force max volume if stream cannot be muted 1083f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 1084f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1085b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", 1086c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent stream, device, index); 1087c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 1088c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 1089c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // clear all device specific values 1090c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1091c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.clear(); 1092c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1093c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 1094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1095f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // compute and apply stream volume on all outputs according to connected device 1096f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin status_t status = NO_ERROR; 1097f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1098c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent audio_devices_t curDevice = 1099c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi getDeviceForVolume(mOutputs.valueAt(i)->device()); 1100e92d623811f3fd3e7cc5e5dd8bc93c0c0a8fdf50Eric Laurent if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) { 1101c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); 1102c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent if (volStatus != NO_ERROR) { 1103c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status = volStatus; 1104c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent } 1105f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1106f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1107f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return status; 1108f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1109f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1110c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, 1111c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int *index, 1112c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 1113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1114c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (index == NULL) { 1115f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 1116f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1117c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 1118c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 1119c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1120c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 1121c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // the strategy the stream belongs to. 1122c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1123c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); 1124c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1125c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = getDeviceForVolume(device); 1126c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 1127c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 1128c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 1129f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1130f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1131f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 113245c763947b657b347211dc9388754e05d30d0467Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::selectOutputForEffects( 113345c763947b657b347211dc9388754e05d30d0467Eric Laurent const SortedVector<audio_io_handle_t>& outputs) 113445c763947b657b347211dc9388754e05d30d0467Eric Laurent{ 113545c763947b657b347211dc9388754e05d30d0467Eric Laurent // select one output among several suitable for global effects. 113645c763947b657b347211dc9388754e05d30d0467Eric Laurent // The priority is as follows: 113745c763947b657b347211dc9388754e05d30d0467Eric Laurent // 1: An offloaded output. If the effect ends up not being offloadable, 113845c763947b657b347211dc9388754e05d30d0467Eric Laurent // AudioFlinger will invalidate the track and the offloaded output 113945c763947b657b347211dc9388754e05d30d0467Eric Laurent // will be closed causing the effect to be moved to a PCM output. 114045c763947b657b347211dc9388754e05d30d0467Eric Laurent // 2: A deep buffer output 114145c763947b657b347211dc9388754e05d30d0467Eric Laurent // 3: the first output in the list 114245c763947b657b347211dc9388754e05d30d0467Eric Laurent 114345c763947b657b347211dc9388754e05d30d0467Eric Laurent if (outputs.size() == 0) { 114445c763947b657b347211dc9388754e05d30d0467Eric Laurent return 0; 114545c763947b657b347211dc9388754e05d30d0467Eric Laurent } 114645c763947b657b347211dc9388754e05d30d0467Eric Laurent 114745c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t outputOffloaded = 0; 114845c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t outputDeepBuffer = 0; 114945c763947b657b347211dc9388754e05d30d0467Eric Laurent 115045c763947b657b347211dc9388754e05d30d0467Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 115145c763947b657b347211dc9388754e05d30d0467Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]); 115245c763947b657b347211dc9388754e05d30d0467Eric Laurent ALOGV("selectOutputForEffects outputs[%d] flags %x", i, desc->mFlags); 115345c763947b657b347211dc9388754e05d30d0467Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 115445c763947b657b347211dc9388754e05d30d0467Eric Laurent outputOffloaded = outputs[i]; 115545c763947b657b347211dc9388754e05d30d0467Eric Laurent } 115645c763947b657b347211dc9388754e05d30d0467Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) { 115745c763947b657b347211dc9388754e05d30d0467Eric Laurent outputDeepBuffer = outputs[i]; 115845c763947b657b347211dc9388754e05d30d0467Eric Laurent } 115945c763947b657b347211dc9388754e05d30d0467Eric Laurent } 116045c763947b657b347211dc9388754e05d30d0467Eric Laurent 116145c763947b657b347211dc9388754e05d30d0467Eric Laurent ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d", 116245c763947b657b347211dc9388754e05d30d0467Eric Laurent outputOffloaded, outputDeepBuffer); 116345c763947b657b347211dc9388754e05d30d0467Eric Laurent if (outputOffloaded != 0) { 116445c763947b657b347211dc9388754e05d30d0467Eric Laurent return outputOffloaded; 116545c763947b657b347211dc9388754e05d30d0467Eric Laurent } 116645c763947b657b347211dc9388754e05d30d0467Eric Laurent if (outputDeepBuffer != 0) { 116745c763947b657b347211dc9388754e05d30d0467Eric Laurent return outputDeepBuffer; 116845c763947b657b347211dc9388754e05d30d0467Eric Laurent } 116945c763947b657b347211dc9388754e05d30d0467Eric Laurent 117045c763947b657b347211dc9388754e05d30d0467Eric Laurent return outputs[0]; 117145c763947b657b347211dc9388754e05d30d0467Eric Laurent} 117245c763947b657b347211dc9388754e05d30d0467Eric Laurent 1173c94dccc97cc3ed5171b45f46a0f7f8762d37156fGlenn Kastenaudio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(const effect_descriptor_t *desc) 1174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // apply simple rule where global effects are attached to the same output as MUSIC streams 11764660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen 11774660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen routing_strategy strategy = getStrategy(AudioSystem::MUSIC); 11784660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 1179c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs); 118045c763947b657b347211dc9388754e05d30d0467Eric Laurent 118145c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t output = selectOutputForEffects(dstOutputs); 118245c763947b657b347211dc9388754e05d30d0467Eric Laurent ALOGV("getOutputForEffect() got output %d for fx %s flags %x", 118345c763947b657b347211dc9388754e05d30d0467Eric Laurent output, (desc == NULL) ? "unspecified" : desc->name, (desc == NULL) ? 0 : desc->flags); 118445c763947b657b347211dc9388754e05d30d0467Eric Laurent 118545c763947b657b347211dc9388754e05d30d0467Eric Laurent return output; 1186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1188c94dccc97cc3ed5171b45f46a0f7f8762d37156fGlenn Kastenstatus_t AudioPolicyManagerBase::registerEffect(const effect_descriptor_t *desc, 11891c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent audio_io_handle_t io, 1190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t strategy, 1191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session, 1192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int id) 1193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 11941c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 1195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 11961c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent index = mInputs.indexOfKey(io); 11971c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent if (index < 0) { 119864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() unknown io %d", io); 11991c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent return INVALID_OPERATION; 12001c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent } 1201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 120464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 1205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin desc->name, desc->memoryUsage); 1206f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory += desc->memoryUsage; 12096a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 12101c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent desc->name, io, strategy, session, id); 12116a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 1212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = new EffectDescriptor(); 1214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t)); 12151c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent pDesc->mIo = io; 1216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mStrategy = (routing_strategy)strategy; 1217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mSession = session; 1218582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = false; 1219582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.add(id, pDesc); 1221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1222f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::unregisterEffect(int id) 1226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mEffects.indexOfKey(id); 1228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 122964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 1230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = mEffects.valueAt(index); 1234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1235582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent setEffectEnabled(pDesc, false); 1236582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) { 123864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() memory %d too big for total %d", 1239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage = mTotalEffectsMemory; 1241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory -= pDesc->mDesc.memoryUsage; 12436a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 1244582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.removeItem(id); 1247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete pDesc; 1248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1252582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(int id, bool enabled) 1253582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 1254582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1255582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (index < 0) { 125664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 1257582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1258582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1259582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1260582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 1261582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 1262582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1263582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(EffectDescriptor *pDesc, bool enabled) 1264582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 1265582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled == pDesc->mEnabled) { 12666a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(%s) effect already %s", 1267582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 1268582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1269582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1270582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1271582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled) { 1272582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 127364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 1274582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10); 1275582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1276582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1277582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad; 12786a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 1279582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } else { 1280582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) { 128164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 1282582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 1283582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 1284582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1285582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad; 12866a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 1287582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1288582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = enabled; 1289582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return NO_ERROR; 1290582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 1291582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const 1293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin nsecs_t sysTime = systemTime(); 1295f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 129680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 129780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (outputDesc->isStreamActive((AudioSystem::stream_type)stream, inPastMs, sysTime)) { 1298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return true; 1299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1304dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivibool AudioPolicyManagerBase::isStreamActiveRemotely(int stream, uint32_t inPastMs) const 1305dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi{ 1306dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi nsecs_t sysTime = systemTime(); 1307dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi for (size_t i = 0; i < mOutputs.size(); i++) { 1308dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 130980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 131080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent outputDesc->isStreamActive((AudioSystem::stream_type)stream, inPastMs, sysTime)) { 1311dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi return true; 1312dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi } 1313dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi } 1314dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi return false; 1315dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi} 1316dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi 1317abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivibool AudioPolicyManagerBase::isSourceActive(audio_source_t source) const 1318abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi{ 1319abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi for (size_t i = 0; i < mInputs.size(); i++) { 1320abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi const AudioInputDescriptor * inputDescriptor = mInputs.valueAt(i); 1321fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent if ((inputDescriptor->mInputSource == (int)source || 1322fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent (source == (audio_source_t)AUDIO_SOURCE_VOICE_RECOGNITION && 1323fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) 1324fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent && (inputDescriptor->mRefCount > 0)) { 1325abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi return true; 1326abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi } 1327abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi } 1328abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi return false; 1329abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi} 1330abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi 1331abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi 1332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::dump(int fd) 1333f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 1337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 1339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1340b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 134170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput); 1342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string()); 1344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string()); 1346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1347599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " USB audio ALSA %s\n", mUsbCardAndDevice.string()); 1348599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent result.append(buffer); 1349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices); 1350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices); 1352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1353f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 1354f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]); 1356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]); 1358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]); 1360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1361f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]); 1362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1363738207def5f691d605ae33d041116829a74513a9Eric Laurent snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AudioSystem::FOR_SYSTEM]); 1364738207def5f691d605ae33d041116829a74513a9Eric Laurent result.append(buffer); 1365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 1366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 13675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 136870c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 13695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, buffer, strlen(buffer)); 137070c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 137170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, "- HW Module %d:\n", i + 1); 13725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, buffer, strlen(buffer)); 137370c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules[i]->dump(fd); 13745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 13755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 1376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nOutputs dump:\n"); 1377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 1380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1381f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueAt(i)->dump(fd); 1382f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nInputs dump:\n"); 1385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 1388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.valueAt(i)->dump(fd); 1390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nStreams dump:\n"); 1393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1394c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, 1395c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 1396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 1398c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, " %02d ", i); 1399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1400c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[i].dump(fd); 1401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 1404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 1405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "Registered effects:\n"); 1408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mEffects.size(); i++) { 1410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 1411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.valueAt(i)->dump(fd); 1413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1419a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald// This function checks for the parameters which can be offloaded. 1420a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald// This can be enhanced depending on the capability of the DSP and policy 1421a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald// of the system. 1422b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgeraldbool AudioPolicyManagerBase::isOffloadSupported(const audio_offload_info_t& offloadInfo) 1423b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald{ 1424a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d," 1425a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald " BitRate=%u, duration=%lld us, has_video=%d", 1426a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.sample_rate, offloadInfo.channel_mask, 1427a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.format, 1428a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us, 1429a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.has_video); 1430a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 1431a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // Check if offload has been disabled 1432a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald char propValue[PROPERTY_VALUE_MAX]; 1433a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (property_get("audio.offload.disable", propValue, "0")) { 1434a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (atoi(propValue) != 0) { 1435a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("offload disabled by audio.offload.disable=%s", propValue ); 1436a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return false; 1437a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 1438a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 1439a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 1440a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // Check if stream type is music, then only allow offload as of now. 1441a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC) 1442a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald { 144341b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent ALOGV("isOffloadSupported: stream_type != MUSIC, returning false"); 144441b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent return false; 144541b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent } 144641b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent 144741b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent //TODO: enable audio offloading with video when ready 144841b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent if (offloadInfo.has_video) 144941b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent { 145041b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent ALOGV("isOffloadSupported: has_video == true, returning false"); 1451a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return false; 1452a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 1453a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 1454a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald //If duration is less than minimum value defined in property, return false 1455a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (property_get("audio.offload.min.duration.secs", propValue, NULL)) { 1456a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) { 1457a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue); 1458a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return false; 1459a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 1460a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) { 1461a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS); 1462a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return false; 1463a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 1464a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 1465a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // See if there is a profile to support this. 1466a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // AUDIO_DEVICE_NONE 1467a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald IOProfile *profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */, 1468a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.sample_rate, 1469a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.format, 1470a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.channel_mask, 1471a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD); 1472a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("isOffloadSupported() profile %sfound", profile != NULL ? "" : "NOT "); 1473a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return (profile != NULL); 1474b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald} 1475b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald 1476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyManagerBase 1478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface) 1481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin : 1482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Thread(false), 1484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 148570c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput((audio_io_handle_t)0), 1486ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableOutputDevices(AUDIO_DEVICE_NONE), 1487ca0657a1ca087a6d474a75fcfedd6aac3901d587Glenn Kasten mPhoneState(AudioSystem::MODE_NORMAL), 1488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 1489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 149048387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi mA2dpSuspended(false), mHasA2dp(false), mHasUsb(false), mHasRemoteSubmix(false) 1491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface = clientInterface; 1493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) { 1495f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[i] = AudioSystem::FORCE_NONE; 1496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1498f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin initializeVolumeCurves(); 1499f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpDeviceAddress = String8(""); 1501f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mScoDeviceAddress = String8(""); 1502599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mUsbCardAndDevice = String8(""); 1503f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 15045ec145df7708564d385fd3fb764085321cf4c253Dima Zavin if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { 15055ec145df7708564d385fd3fb764085321cf4c253Dima Zavin if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { 1506739022f26a7127ba76a98dda65411496086114a7Dima Zavin ALOGE("could not load audio policy configuration file, setting defaults"); 1507739022f26a7127ba76a98dda65411496086114a7Dima Zavin defaultAudioPolicyConfig(); 15085ec145df7708564d385fd3fb764085321cf4c253Dima Zavin } 15095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 15105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 1511b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // open all output streams needed to access attached devices 151270c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 151370c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 151470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 151570c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGW("could not open HW module %s", mHwModules[i]->mName); 151670c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 151770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 151870c236c9290732782d5267935af1475b8d5ae602Eric Laurent // open all output streams needed to access attached devices 1519a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // except for direct output streams that are only opened when they are actually 1520a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // required by an app. 152170c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 152270c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 152370c236c9290732782d5267935af1475b8d5ae602Eric Laurent const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j]; 152470c236c9290732782d5267935af1475b8d5ae602Eric Laurent 1525a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if ((outProfile->mSupportedDevices & mAttachedOutputDevices) && 1526a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) { 152770c236c9290732782d5267935af1475b8d5ae602Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile); 152870c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice & 152970c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mSupportedDevices); 153070c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput( 153170c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mModule->mHandle, 153270c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 153370c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mSamplingRate, 153470c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mFormat, 153570c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 153670c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mLatency, 153770c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mFlags); 153870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (output == 0) { 153970c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete outputDesc; 154070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } else { 154170c236c9290732782d5267935af1475b8d5ae602Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | 154270c236c9290732782d5267935af1475b8d5ae602Eric Laurent (outProfile->mSupportedDevices & mAttachedOutputDevices)); 154370c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mPrimaryOutput == 0 && 15440977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 154570c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput = output; 154670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 154770c236c9290732782d5267935af1475b8d5ae602Eric Laurent addOutput(output, outputDesc); 154870c236c9290732782d5267935af1475b8d5ae602Eric Laurent setOutputDevice(output, 154970c236c9290732782d5267935af1475b8d5ae602Eric Laurent (audio_devices_t)(mDefaultOutputDevice & 155070c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mSupportedDevices), 155170c236c9290732782d5267935af1475b8d5ae602Eric Laurent true); 1552b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1553b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1554b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1555f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 15575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE_IF((mAttachedOutputDevices & ~mAvailableOutputDevices), 1558b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent "Not output found for attached devices %08x", 15595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (mAttachedOutputDevices & ~mAvailableOutputDevices)); 1560b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1561b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 1562b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1563c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 15643cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 1565f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1566b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput != 0) { 1567f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1568f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1569b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1570f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1571c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi mTestDevice = AUDIO_DEVICE_OUT_SPEAKER; 1572f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = 44100; 1573f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = AudioSystem::PCM_16_BIT; 1574f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = AudioSystem::CHANNEL_OUT_STEREO; 1575f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestLatencyMs = 0; 1576f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = 0; 1577f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1578f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1579f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[i] = 0; 1580f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1581f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1582f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1583f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1584f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 1585f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin run(buffer, ANDROID_PRIORITY_AUDIO); 1586f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1587f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1588f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1589f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1590f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::~AudioPolicyManagerBase() 1591f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1592f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1593f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin exit(); 1594f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1595f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1596f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(mOutputs.keyAt(i)); 1597f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(i); 1598f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1599f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1600f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(mInputs.keyAt(i)); 1601f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(i); 1602f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 160370c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 160470c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mHwModules[i]; 16055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 1606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1607f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1608f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::initCheck() 1609f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1610b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; 1611f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1612f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1613f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::threadLoop() 1615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 16166a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("entering threadLoop()"); 1617f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin while (!exitPending()) 1618f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1619f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 command; 1620f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int valueInt; 1621f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 value; 1622f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1623f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Mutex::Autolock _l(mLock); 1624f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 1625f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1626f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 1627f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(command); 1628f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1629f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 1630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin valueInt != 0) { 16316a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("Test command %s received", command.string()); 1632f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 target; 1633f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("target"), target) != NO_ERROR) { 1634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin target = "Manager"; 1635f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1636f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 1637f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_output")); 1638f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = valueInt; 1639f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1640f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 1641f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_direct")); 1642f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "false") { 1643f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1644f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "true") { 1645f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = true; 1646f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1647f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 1649f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_input")); 1650f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestInput = valueInt; 1651f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1652f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1653f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 1654f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_format")); 1655f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int format = AudioSystem::INVALID_FORMAT; 1656f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "PCM 16 bits") { 1657f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_16_BIT; 1658f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "PCM 8 bits") { 1659f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_8_BIT; 1660f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Compressed MP3") { 1661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::MP3; 1662f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (format != AudioSystem::INVALID_FORMAT) { 1664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1665f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = format; 1666f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1667f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1668f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("format"), format); 1669f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1670f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1671f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1673f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 1674f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_channels")); 1675f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int channels = 0; 1676f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "Channels Stereo") { 1678f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_STEREO; 1679f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Channels Mono") { 1680f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_MONO; 1681f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1682f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (channels != 0) { 1683f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1684f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = channels; 1685f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1686f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1687f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("channels"), channels); 1688f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1689f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1690f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 1693f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_sampleRate")); 1694f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (valueInt >= 0 && valueInt <= 96000) { 1695f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int samplingRate = valueInt; 1696f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1697f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = samplingRate; 1698f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1699f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1700f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("sampling_rate"), samplingRate); 1701f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1702f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1703f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1704f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1705f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1706f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 1707f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_reopen")); 1708f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 170970c236c9290732782d5267935af1475b8d5ae602Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 1710b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(mPrimaryOutput); 171170c236c9290732782d5267935af1475b8d5ae602Eric Laurent 171270c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; 171370c236c9290732782d5267935af1475b8d5ae602Eric Laurent 1714b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(mPrimaryOutput); 1715b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(mPrimaryOutput); 1716f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1717b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 1718c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; 171970c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput = mpClientInterface->openOutput(moduleHandle, 172070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 1721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 1722f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 172370c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 1724f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 1725f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 1726b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput == 0) { 17275efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d", 172870c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); 1729f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1730f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1731f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1732b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1733b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent addOutput(mPrimaryOutput, outputDesc); 1734f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1735f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1736f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1737f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1738f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 1739f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1740f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1741f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1742f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1743f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1744f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::exit() 1745f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1746f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1747f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AutoMutex _l(mLock); 1748f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExit(); 1749f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.signal(); 1750f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1751f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExitAndWait(); 1752f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1753f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1754f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinint AudioPolicyManagerBase::testOutputIndex(audio_io_handle_t output) 1755f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1756f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == mTestOutputs[i]) return i; 1758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 1760f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1761f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1762f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- 1764f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc) 1766f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1767f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mId = id; 1768f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.add(id, outputDesc); 1769f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1770f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 17723cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurentstatus_t AudioPolicyManagerBase::checkOutputsForDevice(audio_devices_t device, 17733cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioSystem::device_connection_state state, 17743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent SortedVector<audio_io_handle_t>& outputs) 1775f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 17763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *desc; 1777b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1778b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (state == AudioSystem::DEVICE_STATE_AVAILABLE) { 17793cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // first list already open outputs that can be routed to this device 1780b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 17813cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(i); 17823cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices & device)) { 17833cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i)); 17843cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(mOutputs.keyAt(i)); 1785b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1786b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 17873cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // then look for output profiles that can be routed to this device 17883cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent SortedVector<IOProfile *> profiles; 178970c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 1790b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent { 179170c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 179270c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 179370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 179470c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 179570c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 179670c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices & device) { 17973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): adding profile %d from module %d", j, i); 17983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profiles.add(mHwModules[i]->mOutputProfiles[j]); 179970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 180070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 1801b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 180270c236c9290732782d5267935af1475b8d5ae602Eric Laurent 18033cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profiles.isEmpty() && outputs.isEmpty()) { 18043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 18053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return BAD_VALUE; 180670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 180770c236c9290732782d5267935af1475b8d5ae602Eric Laurent 18083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // open outputs for matching profiles if needed. Direct outputs are also opened to 18093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 18103cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 18113cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = profiles[profile_index]; 1812b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 18133cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // nothing to do if one output is already opened for this profile 18143cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent size_t j; 1815fd8cecbee6843b444d56a1db40af76027e2b19f1Eric Laurent for (j = 0; j < mOutputs.size(); j++) { 18163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(j); 18173cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && desc->mProfile == profile) { 18183cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent break; 18193cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18203cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1821fd8cecbee6843b444d56a1db40af76027e2b19f1Eric Laurent if (j != mOutputs.size()) { 18223cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent continue; 18233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 18253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("opening output for device %08x", device); 18263cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = new AudioOutputDescriptor(profile); 18273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc->mDevice = device; 1828727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; 1829727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent offloadInfo.sample_rate = desc->mSamplingRate; 1830727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent offloadInfo.format = desc->mFormat; 1831727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent offloadInfo.channel_mask = desc->mChannelMask; 1832727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent 18333cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle, 18343cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mDevice, 18353cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mSamplingRate, 18363cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mFormat, 18373cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mChannelMask, 18383cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mLatency, 1839727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent desc->mFlags, 1840727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent &offloadInfo); 18413cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (output != 0) { 18423cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { 18433cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8 reply; 18443cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent char *value; 18453cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mSamplingRates[0] == 0) { 18463cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply = mpClientInterface->getParameters(output, 18473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 18483cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice() direct output sup sampling rates %s", 18493cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply.string()); 18503cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent value = strpbrk((char *)reply.string(), "="); 18513cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (value != NULL) { 18525debe92591363de3d73bc32b62f23df707b1aecfJohn Grossman loadSamplingRates(value + 1, profile); 18533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mFormats[0] == 0) { 18563cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply = mpClientInterface->getParameters(output, 18573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 18583cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice() direct output sup formats %s", 18593cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply.string()); 18603cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent value = strpbrk((char *)reply.string(), "="); 18613cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (value != NULL) { 18625debe92591363de3d73bc32b62f23df707b1aecfJohn Grossman loadFormats(value + 1, profile); 18633cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18643cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18653cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mChannelMasks[0] == 0) { 18663cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply = mpClientInterface->getParameters(output, 18673cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 18683cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice() direct output sup channel masks %s", 18693cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent reply.string()); 18703cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent value = strpbrk((char *)reply.string(), "="); 18713cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (value != NULL) { 18723cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent loadOutChannels(value + 1, profile); 18733cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18753cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (((profile->mSamplingRates[0] == 0) && 18763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mSamplingRates.size() < 2)) || 18773cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ((profile->mFormats[0] == 0) && 18783cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mFormats.size() < 2)) || 18793cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ((profile->mFormats[0] == 0) && 18803cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mChannelMasks.size() < 2))) { 18813cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice() direct output missing param"); 188210705c404c48ec9ac4ce47912e7731f9249cce1dJason Simmons mpClientInterface->closeOutput(output); 18833cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent output = 0; 18843cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } else { 18853cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent addOutput(output, desc); 18863cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18873cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } else { 18883cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_io_handle_t duplicatedOutput = 0; 18893cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // add output descriptor 18903cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent addOutput(output, desc); 18913cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // set initial stream volume for device 18924366b4a6735e5da342b56773073f0b41197c777fEric Laurent applyStreamVolumes(output, device, 0, true); 18933cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 18943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent //TODO: configure audio effect output stage here 18953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 18963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // open a duplicating output thread for the new output and the primary output 18973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent duplicatedOutput = mpClientInterface->openDuplicateOutput(output, 18983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mPrimaryOutput); 18993cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (duplicatedOutput != 0) { 19003cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // add duplicated output descriptor 19013cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL); 19023cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); 19033cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mOutput2 = mOutputs.valueFor(output); 19043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mSamplingRate = desc->mSamplingRate; 19053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mFormat = desc->mFormat; 19063cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mChannelMask = desc->mChannelMask; 19073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent dupOutputDesc->mLatency = desc->mLatency; 19083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent addOutput(duplicatedOutput, dupOutputDesc); 19094366b4a6735e5da342b56773073f0b41197c777fEric Laurent applyStreamVolumes(duplicatedOutput, device, 0, true); 19103cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } else { 19113cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice() could not open dup output for %d and %d", 19123cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mPrimaryOutput, output); 19133cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mpClientInterface->closeOutput(output); 19143cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mOutputs.removeItem(output); 19153cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent output = 0; 19163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 19173cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 19183cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 19193cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (output == 0) { 19203cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice() could not open output for device %x", device); 19213cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent delete desc; 19223cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profiles.removeAt(profile_index); 19233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile_index--; 1924b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 19253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(output); 19263cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): adding output %d", output); 1927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 19283cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 19293cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 19303cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profiles.isEmpty()) { 19313cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 19323cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return BAD_VALUE; 1933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1935b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // check if one opened output is not needed any more after disconnecting one device 1936b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 19373cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(i); 19383cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && 19393cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent !(desc->mProfile->mSupportedDevices & mAvailableOutputDevices)) { 19403cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i)); 19413cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(mOutputs.keyAt(i)); 19423cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 19433cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 19443cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 19453cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent { 19463cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (mHwModules[i]->mHandle == 0) { 19473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent continue; 19483cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 19493cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 19503cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent { 19513cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; 19523cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if ((profile->mSupportedDevices & device) && 19533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (profile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) { 19543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): clearing direct output profile %d on module %d", 19553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent j, i); 19563cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mSamplingRates[0] == 0) { 19573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.clear(); 19583cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.add(0); 19593cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 19603cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mFormats[0] == 0) { 19613cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mFormats.clear(); 19623cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mFormats.add((audio_format_t)0); 19633cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 19643cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mChannelMasks[0] == 0) { 19653cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.clear(); 19663cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.add((audio_channel_mask_t)0); 19673cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 19683cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1969b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1970f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1971f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 19723cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return NO_ERROR; 1973f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1974f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1975b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::closeOutput(audio_io_handle_t output) 1976f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1977b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput(%d)", output); 1978f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1979b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 1980b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputDesc == NULL) { 1981b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGW("closeOutput() unknown output %d", output); 1982b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1985b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // look for duplicated outputs connected to the output being removed. 1986b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1987b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i); 1988b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->isDuplicated() && 1989b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (dupOutputDesc->mOutput1 == outputDesc || 1990b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent dupOutputDesc->mOutput2 == outputDesc)) { 1991b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc2; 1992b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->mOutput1 == outputDesc) { 1993b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput2; 1994b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 1995b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput1; 1996b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1997b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // As all active tracks on duplicated output will be deleted, 1998b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // and as they were also referenced on the other output, the reference 1999b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // count for their stream type must be adjusted accordingly on 2000b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // the other output. 2001b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (int j = 0; j < (int)AudioSystem::NUM_STREAM_TYPES; j++) { 2002b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent int refCount = dupOutputDesc->mRefCount[j]; 2003b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2->changeRefCount((AudioSystem::stream_type)j,-refCount); 2004b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2005b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i); 2006b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); 2007f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2008b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(duplicatedOutput); 2009b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(duplicatedOutput); 2010b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(duplicatedOutput); 2011f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2012f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2013b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2014b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioParameter param; 2015b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent param.add(String8("closing"), String8("true")); 2016b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(output, param.toString()); 2017b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2018b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(output); 20195a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent delete outputDesc; 2020b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(output); 20215a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent mPreviousOutputs = mOutputs; 2022f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2023f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2024c952527e6f89d5427881462823514be9d79f13e6Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManagerBase::getOutputsForDevice(audio_devices_t device, 2025c952527e6f89d5427881462823514be9d79f13e6Eric Laurent DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs) 2026f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2027b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t> outputs; 2028f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 20293cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getOutputsForDevice() device %04x", device); 2030c952527e6f89d5427881462823514be9d79f13e6Eric Laurent for (size_t i = 0; i < openOutputs.size(); i++) { 20313cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("output %d isDuplicated=%d device=%04x", 2032c952527e6f89d5427881462823514be9d79f13e6Eric Laurent i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices()); 2033c952527e6f89d5427881462823514be9d79f13e6Eric Laurent if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) { 2034c952527e6f89d5427881462823514be9d79f13e6Eric Laurent ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i)); 2035c952527e6f89d5427881462823514be9d79f13e6Eric Laurent outputs.add(openOutputs.keyAt(i)); 2036f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2037f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2038b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return outputs; 2039f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2040f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2041b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentbool AudioPolicyManagerBase::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, 2042b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t>& outputs2) 2043f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2044b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1.size() != outputs2.size()) { 2045b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 2046f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2047b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < outputs1.size(); i++) { 2048b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1[i] != outputs2[i]) { 2049b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 2050f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2051f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2052b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return true; 2053b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 2054b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2055b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy) 2056b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 205701e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); 205801e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); 2059c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs); 2060c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); 2061b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2062b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!vectorsEqual(srcOutputs,dstOutputs)) { 2063b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", 2064b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent strategy, srcOutputs[0], dstOutputs[0]); 20655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // mute strategy while moving tracks from one output to another 20665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < srcOutputs.size(); i++) { 2067fa3697d716b444bbea6be480801536c44bf69214Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]); 206880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (desc->isStrategyActive(strategy)) { 2069fa3697d716b444bbea6be480801536c44bf69214Eric Laurent setStrategyMute(strategy, true, srcOutputs[i]); 2070fa3697d716b444bbea6be480801536c44bf69214Eric Laurent setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); 2071fa3697d716b444bbea6be480801536c44bf69214Eric Laurent } 20725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2073f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2074f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Move effects associated to this strategy from previous output to new output 20754660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (strategy == STRATEGY_MEDIA) { 207645c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs); 20774660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen SortedVector<audio_io_handle_t> moved; 20784660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen for (size_t i = 0; i < mEffects.size(); i++) { 20794660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen EffectDescriptor *desc = mEffects.valueAt(i); 20804660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX && 208145c763947b657b347211dc9388754e05d30d0467Eric Laurent desc->mIo != fxOutput) { 20824660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (moved.indexOf(desc->mIo) < 0) { 20834660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen ALOGV("checkOutputForStrategy() moving effect %d to output %d", 208445c763947b657b347211dc9388754e05d30d0467Eric Laurent mEffects.keyAt(i), fxOutput); 20854660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, desc->mIo, 208645c763947b657b347211dc9388754e05d30d0467Eric Laurent fxOutput); 20874660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen moved.add(desc->mIo); 20884660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 208945c763947b657b347211dc9388754e05d30d0467Eric Laurent desc->mIo = fxOutput; 20904660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 20914660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 20924660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 20935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // Move tracks associated to this strategy from previous output to new output 2094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 2095f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)i) == strategy) { 209612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi //FIXME see fixme on name change 20974660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, 20984660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen dstOutputs[0] /* ignored */); 2099f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2103f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2104f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkOutputForAllStrategies() 2105f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2106c16ac09f510437e8340be691720177a490ae78f0Eric Laurent checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 2107f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_PHONE); 2108f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_SONIFICATION); 210912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 2110f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_MEDIA); 2111f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_DTMF); 2112f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2114b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::getA2dpOutput() 2115b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 21165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp) { 2117b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 2118b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2119b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2120b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2121b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 2122b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 2123b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mOutputs.keyAt(i); 2124b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2125b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2126b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2127b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 2128b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 2129b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2130f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkA2dpSuspend() 2131f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 21325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp) { 2133b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 2134b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2135b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t a2dpOutput = getA2dpOutput(); 2136b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (a2dpOutput == 0) { 2137b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 2138b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2139b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2140f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // suspend A2DP output if: 2141f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (NOT already suspended) && 2142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is connected && 2143f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage for communication || for record is SCO))) || 2144f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is ringing || in call) 2145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 2146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // restore A2DP output if: 2147f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (Already suspended) && 2148f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is NOT connected || 2149f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage NOT for communication && NOT for record is SCO))) && 2150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is NOT ringing && NOT in call) 2151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 2152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpSuspended) { 2153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress == "") || 2154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) && 2155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) && 2156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState != AudioSystem::MODE_IN_CALL) && 2157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState != AudioSystem::MODE_RINGTONE))) { 2158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2159b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->restoreOutput(a2dpOutput); 2160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = false; 2161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress != "") && 2164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 2165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) || 2166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState == AudioSystem::MODE_IN_CALL) || 2167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState == AudioSystem::MODE_RINGTONE))) { 2168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2169b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->suspendOutput(a2dpOutput); 2170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = true; 2171f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2173f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2175f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache) 2176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2177ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent audio_devices_t device = AUDIO_DEVICE_NONE; 2178f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2179f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2180f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check the following by order of priority to request a routing change if necessary: 2181c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 1: the strategy enforced audible is active on the output: 2182c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // use device for strategy enforced audible 2183c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 2: we are in call or the strategy phone is active on the output: 2184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy phone 2185c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 3: the strategy sonification is active on the output: 2186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy sonification 218712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 4: the strategy "respectful" sonification is active on the output: 218812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // use device for strategy "respectful" sonification 218912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 5: the strategy media is active on the output: 2190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy media 219112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 6: the strategy DTMF is active on the output: 2192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy DTMF 219380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { 2194c16ac09f510437e8340be691720177a490ae78f0Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 2195c16ac09f510437e8340be691720177a490ae78f0Eric Laurent } else if (isInCall() || 219680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent outputDesc->isStrategyActive(STRATEGY_PHONE)) { 2197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 219880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) { 2199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 220080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { 22015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); 220280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { 2203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 220480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { 2205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 2206f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 22086a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getNewDevice() selected device %x", device); 2209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return device; 2210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2211f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getStrategyForStream(AudioSystem::stream_type stream) { 2213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return (uint32_t)getStrategy(stream); 2214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2215f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2216f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDevicesForStream(AudioSystem::stream_type stream) { 2217f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t devices; 2218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // By checking the range of stream before calling getStrategy, we avoid 22195efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 2220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and then return STRATEGY_MEDIA, but we want to return the empty set. 2221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream < (AudioSystem::stream_type) 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 2222ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent devices = AUDIO_DEVICE_NONE; 2223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioPolicyManagerBase::routing_strategy strategy = getStrategy(stream); 22255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devices = getDeviceForStrategy(strategy, true /*fromCache*/); 2226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return devices; 2228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy( 2231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream) { 2232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // stream to strategy mapping 2233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (stream) { 2234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::VOICE_CALL: 2235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::BLUETOOTH_SCO: 2236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_PHONE; 2237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::RING: 2238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::ALARM: 2239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_SONIFICATION; 224012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::NOTIFICATION: 224112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi return STRATEGY_SONIFICATION_RESPECTFUL; 2242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DTMF: 2243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_DTMF; 2244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 22455efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("unknown stream type"); 2246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::SYSTEM: 2247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 2248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // while key clicks are played produces a poor result 2249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::TTS: 2250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::MUSIC: 2251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_MEDIA; 2252c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case AudioSystem::ENFORCED_AUDIBLE: 2253c16ac09f510437e8340be691720177a490ae78f0Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 2254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 225712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivivoid AudioPolicyManagerBase::handleNotificationRoutingForStream(AudioSystem::stream_type stream) { 225812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi switch(stream) { 225912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::MUSIC: 226012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 2261c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 226212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 226312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi default: 226412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 226512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 226612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi} 226712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 22685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, 22695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool fromCache) 2270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2271ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 2272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (fromCache) { 22743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x", 22755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent strategy, mDeviceForStrategy[strategy]); 2276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mDeviceForStrategy[strategy]; 2277f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (strategy) { 228012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 228112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case STRATEGY_SONIFICATION_RESPECTFUL: 228212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if (isInCall()) { 22835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 2284dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi } else if (isStreamActiveRemotely(AudioSystem::MUSIC, 2285dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 2286dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // while media is playing on a remote device, use the the sonification behavior. 2287dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // Note that we test this usecase before testing if media is playing because 2288dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // the isStreamActive() method only informs about the activity of a stream, not 2289dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // if it's for local playback. Note also that we use the same delay between both tests 2290dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 229112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 229212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // while media is playing (or has recently played), use the same device 22935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 229412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else { 229512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // when media is not playing anymore, fall back on the sonification behavior 22965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 229712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 229812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 229912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 230012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 2301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_DTMF: 2302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall()) { 2303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when off call, DTMF strategy follows the same rules as MEDIA strategy 23045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 2305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when in call, DTMF and PHONE strategies follow the same rules 2308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_PHONE: 2311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // for phone strategy, we first consider the forced use and then the available devices by order 2312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // of priority 2313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { 2314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_BT_SCO: 2315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall() || strategy != STRATEGY_DTMF) { 2316c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 2317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2319c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 2320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2321c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; 2322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if SCO device is requested but no SCO device is available, fall back to default case 2324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: // FORCE_NONE 2327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 23281afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (mHasA2dp && !isInCall() && 23291afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 2330ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 2331c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 2332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2333c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2336c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 23371afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (device) break; 2338c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET; 23391afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (device) break; 2340b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (mPhoneState != AudioSystem::MODE_IN_CALL) { 2341b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2342b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2343b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2344b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2345b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2346b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2347b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2348b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2349b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2350b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2351b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent } 2352c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_EARPIECE; 23535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 23545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2355ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 23565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); 2357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_SPEAKER: 2361f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 2362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // A2DP speaker when forcing to speaker output 23631afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (mHasA2dp && !isInCall() && 23641afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 2365ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 2366c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2369b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (mPhoneState != AudioSystem::MODE_IN_CALL) { 2370b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2371b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2372b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2373b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2374b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2375b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2376b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2377b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2378b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2379b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2380b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent } 2381c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; 23825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 23835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2384ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 23855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); 2386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_SONIFICATION: 2392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 2394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handleIncallSonification(). 2395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 23965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); 2397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2399c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // FALL THROUGH 2400c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 2401c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 2402c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 2403ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // except: 2404ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // - when in call where it doesn't default to STRATEGY_PHONE behavior 2405ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // - in countries where not enforced in which case it follows STRATEGY_MEDIA 2406c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 2407738207def5f691d605ae33d041116829a74513a9Eric Laurent if ((strategy == STRATEGY_SONIFICATION) || 2408738207def5f691d605ae33d041116829a74513a9Eric Laurent (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED)) { 2409c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; 2410ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2411ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); 2412ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent } 2413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // The second device used for sonification is the same as the device used by media strategy 2415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_MEDIA: { 2418ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent uint32_t device2 = AUDIO_DEVICE_NONE; 241931363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi if (strategy != STRATEGY_SONIFICATION) { 242031363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi // no sonification on remote submix (e.g. WFD) 242148387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; 242248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 2423ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 242448387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 2425ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 2426c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 2427ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2428c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2430ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2431c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2432f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2434ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2435c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 24361afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent } 2437ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2438c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET; 24391afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent } 2440ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2441599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2442599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 2443ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2444599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2445599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 2446ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2447c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 244931363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { 245031363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi // no sonification on aux digital (e.g. HDMI) 2451c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2452f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 24535a484b753cc72d6a50c1dd3bbf68b3403c741a3aEric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 24545a484b753cc72d6a50c1dd3bbf68b3403c741a3aEric Laurent (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_ANALOG_DOCK)) { 2455c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2457ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2458c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; 2459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2461c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 2462ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise 2463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device |= device2; 24645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 24655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2466ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 24675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); 2468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 2470f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 247264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 2473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 2477c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi return device; 2478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2480c952527e6f89d5427881462823514be9d79f13e6Eric Laurentvoid AudioPolicyManagerBase::updateDevicesAndOutputs() 2481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_STRATEGIES; i++) { 24835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 24845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2485c952527e6f89d5427881462823514be9d79f13e6Eric Laurent mPreviousOutputs = mOutputs; 24865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 24875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2488b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurentuint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc, 24899029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent audio_devices_t prevDevice, 24905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t delayMs) 24915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 24929029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // mute/unmute strategies using an incompatible device combination 24939029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // if muting, wait for the audio in pcm buffer to be drained before proceeding 24949029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // if unmuting, unmute only after the specified delay 24955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->isDuplicated()) { 2496b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return 0; 24975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 24985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 24995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t muteWaitMs = 0; 25005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t device = outputDesc->device(); 250180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent bool shouldMute = outputDesc->isActive() && (AudioSystem::popCount(device) >= 2); 25029029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // temporary mute output if device selection changes to avoid volume bursts due to 25039029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // different per device volumes 250480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent bool tempMute = outputDesc->isActive() && (device != prevDevice); 25055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 25065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 25075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 25085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool mute = shouldMute && (curDevice & device) && (curDevice != device); 25095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool doMute = false; 25105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 25115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mute && !outputDesc->mStrategyMutedByDevice[i]) { 25125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent doMute = true; 25135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = true; 25145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){ 25155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent doMute = true; 25165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = false; 25175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 25189029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (doMute || tempMute) { 25195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t j = 0; j < mOutputs.size(); j++) { 25205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(j); 2521f32e38e24db196671d3ea43427125a4e212466faEric Laurent // skip output if it does not share any device with current output 2522c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if ((desc->supportedDevices() & outputDesc->supportedDevices()) 2523ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent == AUDIO_DEVICE_NONE) { 25245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent continue; 25255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 25265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(j); 25273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", 25285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mute ? "muting" : "unmuting", i, curDevice, curOutput); 25295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); 253080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (desc->isStrategyActive((routing_strategy)i)) { 2531f32e38e24db196671d3ea43427125a4e212466faEric Laurent // do tempMute only for current output 2532f32e38e24db196671d3ea43427125a4e212466faEric Laurent if (tempMute && (desc == outputDesc)) { 253301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStrategyMute((routing_strategy)i, true, curOutput); 253401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStrategyMute((routing_strategy)i, false, curOutput, 253501e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent desc->latency() * 2, device); 25369029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent } 2537f32e38e24db196671d3ea43427125a4e212466faEric Laurent if ((tempMute && (desc == outputDesc)) || mute) { 25389029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (muteWaitMs < desc->latency()) { 25399029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent muteWaitMs = desc->latency(); 25409029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent } 25415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 25425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 25435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 25445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 25455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 25465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 25475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // FIXME: should not need to double latency if volume could be applied immediately by the 25485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // audioflinger mixer. We must account for the delay between now and the next time 25495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // the audioflinger thread for this output will process a buffer (which corresponds to 25505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // one buffer size, usually 1/2 or 1/4 of the latency). 25515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent muteWaitMs *= 2; 25525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // wait for the PCM output buffers to empty before proceeding with the rest of the command 25535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (muteWaitMs > delayMs) { 2554b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs -= delayMs; 2555b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent usleep(muteWaitMs * 1000); 2556b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2557f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2558b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return 0; 2559f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2561b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurentuint32_t AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, 2562f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2563f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent bool force, 2564f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent int delayMs) 2565f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 25665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); 2567f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 25685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioParameter param; 2569f32e38e24db196671d3ea43427125a4e212466faEric Laurent uint32_t muteWaitMs; 2570f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2571f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->isDuplicated()) { 2572b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); 2573b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); 2574b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2575f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2576f32e38e24db196671d3ea43427125a4e212466faEric Laurent // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current 2577f32e38e24db196671d3ea43427125a4e212466faEric Laurent // output profile 2578f32e38e24db196671d3ea43427125a4e212466faEric Laurent if ((device != AUDIO_DEVICE_NONE) && 2579f32e38e24db196671d3ea43427125a4e212466faEric Laurent ((device & outputDesc->mProfile->mSupportedDevices) == 0)) { 2580f32e38e24db196671d3ea43427125a4e212466faEric Laurent return 0; 2581f32e38e24db196671d3ea43427125a4e212466faEric Laurent } 2582f32e38e24db196671d3ea43427125a4e212466faEric Laurent 2583f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // filter devices according to output selected 2584f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices); 2585f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 25865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t prevDevice = outputDesc->mDevice; 25875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 25885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() prevDevice %04x", prevDevice); 25895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2590ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device != AUDIO_DEVICE_NONE) { 25915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mDevice = device; 25925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 25939029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); 25945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2595f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Do not change the routing if: 2596ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent // - the requested device is AUDIO_DEVICE_NONE 2597f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the requested device is the same as current device and force is not specified. 2598f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Doing this check here allows the caller to call setOutputDevice() without conditions 2599ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) { 26005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); 2601b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2602f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2603f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 26045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() changing device"); 2605f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do the routing 2606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)device); 26075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mpClientInterface->setParameters(output, param.toString(), delayMs); 26085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2609f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // update stream volumes according to new device 2610f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin applyStreamVolumes(output, device, delayMs); 2611b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent 2612b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 26135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 2614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 26155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getInputProfile(audio_devices_t device, 26165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t samplingRate, 26175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t format, 26185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t channelMask) 26195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 26205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // Choose an input profile based on the requested capture parameters: select the first available 26215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // profile supporting all requested parameters. 26225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 262370c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 26245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent { 262570c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 26265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent continue; 26275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 262870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 26295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent { 263070c236c9290732782d5267935af1475b8d5ae602Eric Laurent IOProfile *profile = mHwModules[i]->mInputProfiles[j]; 263170c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 26320977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent channelMask,(audio_output_flags_t)0)) { 263370c236c9290732782d5267935af1475b8d5ae602Eric Laurent return profile; 26345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 26355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2636f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 263770c236c9290732782d5267935af1475b8d5ae602Eric Laurent return NULL; 2638f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2639f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2640f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) 2641f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2642ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 2643f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 26449641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent switch (inputSource) { 26459641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 26469641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { 26479641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 26489641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent break; 26499641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent } 26509641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent // FALL THROUGH 26519641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent 2652f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_DEFAULT: 2653f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_MIC: 2654f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_RECOGNITION: 2655fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent case AUDIO_SOURCE_HOTWORD: 2656f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_COMMUNICATION: 2657f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO && 2658c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 2659c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 2660c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_WIRED_HEADSET) { 2661c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_WIRED_HEADSET; 2662c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { 2663c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BUILTIN_MIC; 2664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2665f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2666f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_CAMCORDER: 2667c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (mAvailableInputDevices & AUDIO_DEVICE_IN_BACK_MIC) { 2668c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BACK_MIC; 2669c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { 2670c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BUILTIN_MIC; 2671f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2673f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 2674f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 2675c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { 2676c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_VOICE_CALL; 26775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2678f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 267948387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi case AUDIO_SOURCE_REMOTE_SUBMIX: 268048387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi if (mAvailableInputDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { 268148387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; 268248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 268348387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi break; 2684f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 268564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 2686f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2687f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 26886a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 2689c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi return device; 2690f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 26926d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivibool AudioPolicyManagerBase::isVirtualInputDevice(audio_devices_t device) 26936d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi{ 26946d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi if ((device & AUDIO_DEVICE_BIT_IN) != 0) { 26956d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi device &= ~AUDIO_DEVICE_BIT_IN; 26966d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) 26976d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi return true; 26986d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi } 26996d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi return false; 27006d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi} 27016d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi 27026d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Triviaudio_io_handle_t AudioPolicyManagerBase::getActiveInput(bool ignoreVirtualInputs) 2703f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2704f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 27056d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi const AudioInputDescriptor * input_descriptor = mInputs.valueAt(i); 27066d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi if ((input_descriptor->mRefCount > 0) 27076d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) { 2708f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mInputs.keyAt(i); 2709f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2710f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2711f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 2712f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2713f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2714e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2715c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForVolume(audio_devices_t device) 2716e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2717ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2718e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // this happens when forcing a route update and no track is active on an output. 2719e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // In this case the returned category is not important. 2720c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 2721c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else if (AudioSystem::popCount(device) > 1) { 2722e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // Multiple device selection is either: 2723e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - speaker + one other device: give priority to speaker in this case. 2724e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 2725e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 2726e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // selection if not the speaker. 2727c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 2728c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 2729c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else { 2730c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 2731c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 2732e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 2733e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 273464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW_IF(AudioSystem::popCount(device) != 1, 2735c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 2736e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device); 2737e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2738c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return device; 2739c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 2740c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2741f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric LaurentAudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(audio_devices_t device) 2742c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 2743f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent switch(getDeviceForVolume(device)) { 2744e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 2745e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_EARPIECE; 2746e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 2747e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 2748e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 2749e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 2750e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 2751e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 2752e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_HEADSET; 2753e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 2754e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 2755e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 2756c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent case AUDIO_DEVICE_OUT_AUX_DIGITAL: 2757599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent case AUDIO_DEVICE_OUT_USB_ACCESSORY: 2758599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent case AUDIO_DEVICE_OUT_USB_DEVICE: 275948387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi case AUDIO_DEVICE_OUT_REMOTE_SUBMIX: 2760e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent default: 2761e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_SPEAKER; 2762e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 2763e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent} 2764e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2765f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentfloat AudioPolicyManagerBase::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, 2766e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int indexInUi) 2767e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2768e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device_category deviceCategory = getDeviceCategory(device); 2769e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 2770e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // the volume index in the UI is relative to the min and max volume indices for this stream type 2772e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 2773e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[VOLMIN].mIndex; 2774f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 2775f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (streamDesc.mIndexMax - streamDesc.mIndexMin); 2776f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2777f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // find what part of the curve this index volume belongs to, or if it's out of bounds 2778f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int segment = 0; 2779e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 2780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0.0f; 2781e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 2782f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 0; 2783e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 2784f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 1; 2785e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 2786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 2; 2787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { // out of bounds 2788f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0f; 2789f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2790f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2791f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // linear interpolation in the attenuation table in dB 2792e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent float decibels = curve[segment].mDBAttenuation + 2793e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 2794e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ( (curve[segment+1].mDBAttenuation - 2795e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation) / 2796e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(curve[segment+1].mIndex - 2797e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex)) ); 2798f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 2800f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 28013cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 2802e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex, volIdx, 2803e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mIndex, 2804e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation, 2805cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent decibels, 2806e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mDBAttenuation, 2807f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin amplification); 2808f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2809f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return amplification; 2810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2811f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2812cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2813e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2814e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 2815e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2816e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2817e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2818e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2819e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 2820cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent}; 2821cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent 2822e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2823e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2824e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 2825e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2826e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2827e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2828e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2829e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 2830e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2831e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2832ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks 2833ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets (See AudioService.java). 2834123897874418f9f0e48bb89386d8c470e6975f28Jean-Michel Trivi// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset. 2835ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2836ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent AudioPolicyManagerBase::sDefaultSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2837123897874418f9f0e48bb89386d8c470e6975f28Jean-Michel Trivi {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f} 2838ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent}; 2839ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent 2840ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2841ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent AudioPolicyManagerBase::sHeadsetSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 28427465678e0d5711ebcd78ae47b3a76821534a23eaEric Laurent {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f} 2843ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent}; 2844e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2845e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 28460d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent AudioPolicyManagerBase::sDefaultVoiceVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 28470d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f} 28480d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent}; 28490d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent 28500d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 28510d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent AudioPolicyManagerBase::sSpeakerVoiceVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 28520d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f} 28530d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent}; 28540d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent 28550d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2856ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent *AudioPolicyManagerBase::sVolumeProfiles[AUDIO_STREAM_CNT] 2857e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent [AudioPolicyManagerBase::DEVICE_CATEGORY_CNT] = { 2858ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_VOICE_CALL 28590d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 28600d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 28610d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 2862e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2863ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_SYSTEM 2864ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2865ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2866ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2867ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2868ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_RING 2869e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2870e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2871e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2872e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2873ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_MUSIC 2874ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 2875ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2876ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 2877ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2878ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_ALARM 287912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 288012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 288112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 288212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi }, 2883ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_NOTIFICATION 2884e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2885ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2886e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2887c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2888ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_BLUETOOTH_SCO 28890d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 28900d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 28910d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 2892c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2893ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_ENFORCED_AUDIBLE 2894ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2895ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2896ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2897ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2898ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_DTMF 2899ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 2900ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2901ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 2902ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2903ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_TTS 2904ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 2905ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2906ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 2907ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 2908e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2909e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2910e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentvoid AudioPolicyManagerBase::initializeVolumeCurves() 2911e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2912ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 2913e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 2914cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent mStreams[i].mVolumeCurve[j] = 2915ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sVolumeProfiles[i][j]; 2916cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2917cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2918f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2919f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2920c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentfloat AudioPolicyManagerBase::computeVolume(int stream, 2921c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2922c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2923f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device) 2924f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2925f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = 1.0; 2926f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 2928f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2929ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2930f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = outputDesc->device(); 2931f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2932f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if volume is not 0 (not muted), force media volume to max on digital output 2934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::MUSIC && 2935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin index != mStreams[stream].mIndexMin && 2936f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent (device == AUDIO_DEVICE_OUT_AUX_DIGITAL || 2937599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET || 2938599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_USB_ACCESSORY || 2939599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device == AUDIO_DEVICE_OUT_USB_DEVICE)) { 2940f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0; 2941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2943f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = volIndexToAmpl(device, streamDesc, index); 2944f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2945f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if a headset is connected, apply the following rules to ring tones and notifications 2946f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // to avoid sound level bursts in user's ears: 2947f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - always attenuate ring tones and notifications volume by 6dB 2948f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - if music is playing, always limit the volume to current music volume, 2949f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // with a minimum threshold at -36dB so that notification is always perceived. 295012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 2951c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | 2952c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 2953c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi AUDIO_DEVICE_OUT_WIRED_HEADSET | 2954c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) && 295512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION) 295612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) 2957738207def5f691d605ae33d041116829a74513a9Eric Laurent || (stream == AudioSystem::SYSTEM) 2958738207def5f691d605ae33d041116829a74513a9Eric Laurent || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) && 2959738207def5f691d605ae33d041116829a74513a9Eric Laurent (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_NONE))) && 2960f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin streamDesc.mCanBeMuted) { 2961f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 2962f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when the phone is ringing we must consider that music could have been paused just before 2963f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // by the music application and behave as if music was active if the last music track was 2964f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // just stopped 2965ac3cf10ef6de12e69540a1244ac7255f93fa7502Eric Laurent if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || 2966ac3cf10ef6de12e69540a1244ac7255f93fa7502Eric Laurent mLimitRingtoneVolume) { 296717a73c3394547692457299dc512b5c2312ea0344Eric Laurent audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/); 2968c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float musicVol = computeVolume(AudioSystem::MUSIC, 296917a73c3394547692457299dc512b5c2312ea0344Eric Laurent mStreams[AudioSystem::MUSIC].getVolumeIndex(musicDevice), 2970c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 297117a73c3394547692457299dc512b5c2312ea0344Eric Laurent musicDevice); 2972c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 2973c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 2974f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume > minVol) { 2975f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = minVol; 29766a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 2977f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2978f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2979f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2980f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2981f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return volume; 2982f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2984c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::checkAndSetVolume(int stream, 2985c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2986c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2987f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2988c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 2989c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 2990f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2992f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change actual stream volume if the stream is muted 2993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 29943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkAndSetVolume() stream %d muted count %d", 29955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent stream, mOutputs.valueFor(output)->mMuteCount[stream]); 2996f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2999f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change in call volume if bluetooth is connected and vice versa 3000f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 3001f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) { 30026a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 3003f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, mForceUse[AudioSystem::FOR_COMMUNICATION]); 3004f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 3005f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3006f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3007f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = computeVolume(stream, index, output, device); 3008f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // We actually change the volume if: 3009f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the float value returned by computeVolume() changed 3010f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the force flag is set 3011f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 3012f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force) { 3013f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueFor(output)->mCurVolume[stream] = volume; 30143cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 30150d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 30160d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent // enabled 30170d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent if (stream == AudioSystem::BLUETOOTH_SCO) { 30180d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs); 3019f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3020f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); 3021f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3022f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3023f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL || 3024f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::BLUETOOTH_SCO) { 3025f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float voiceVolume; 3026f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force voice volume to max for bluetooth SCO as volume is managed by the headset 3027f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL) { 3028f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 3029f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 3030f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = 1.0; 3031f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3032f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3033b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { 3034f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 3035f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLastVoiceVolume = voiceVolume; 3036f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3037f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3038f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3039f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3040f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3041f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3042c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, 3043f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 3044c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 3045c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 3046f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 30473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("applyStreamVolumes() for output %d and device %x", output, device); 3048f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3049f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 3050c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 3051f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mStreams[stream].getVolumeIndex(device), 3052c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 3053c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 3054c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs, 3055c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent force); 3056f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3057f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3058f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 305901e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurentvoid AudioPolicyManagerBase::setStrategyMute(routing_strategy strategy, 306001e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent bool on, 306101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_io_handle_t output, 306201e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent int delayMs, 306301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t device) 3064f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 30653cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 3066f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 3067f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)stream) == strategy) { 306801e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStreamMute(stream, on, output, delayMs, device); 3069f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3070f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3071f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3072f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 307301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurentvoid AudioPolicyManagerBase::setStreamMute(int stream, 307401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent bool on, 307501e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_io_handle_t output, 307601e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent int delayMs, 307701e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t device) 3078f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3079f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 3080f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 3081ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 308201e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent device = outputDesc->device(); 308301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent } 3084f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 30853cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x", 308601e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent stream, on, output, outputDesc->mMuteCount[stream], device); 3087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3088f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (on) { 3089f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 3090738207def5f691d605ae33d041116829a74513a9Eric Laurent if (streamDesc.mCanBeMuted && 3091738207def5f691d605ae33d041116829a74513a9Eric Laurent ((stream != AudioSystem::ENFORCED_AUDIBLE) || 3092738207def5f691d605ae33d041116829a74513a9Eric Laurent (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_NONE))) { 3093c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 3094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3095f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3096f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 3097f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mMuteCount[stream]++; 3098f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 3099f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 31003cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("setStreamMute() unmuting non muted stream!"); 3101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 3102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3103f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (--outputDesc->mMuteCount[stream] == 0) { 3104c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 3105c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi streamDesc.getVolumeIndex(device), 3106c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 3107c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 3108c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs); 3109f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3110f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3111f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3112f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, bool stateChange) 3114f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3115f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if the stream pertains to sonification strategy and we are in call we must 3116f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // mute the stream if it is low visibility. If it is high visibility, we must play a tone 3117f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // in the device used for phone strategy and play the tone if the selected device does not 3118f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // interfere with the device used for phone strategy 3119f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 3120f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // many times as there are active tracks on the output 312112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 312212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if ((stream_strategy == STRATEGY_SONIFICATION) || 312312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { 3124b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 31256a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 3126f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, starting, outputDesc->mDevice, stateChange); 3127f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream]) { 3128f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int muteCount = 1; 3129f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stateChange) { 3130f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin muteCount = outputDesc->mRefCount[stream]; 3131f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3132f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) { 31336a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 3134f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 3135b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 3136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3137f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 31386a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility"); 31395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->device() & 31405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) { 31416a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 3142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 3143b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 3144f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (starting) { 3147f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL); 3148f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 3149f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->stopTone(); 3150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3153f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isInCall() 3157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return isStateInCall(mPhoneState); 3159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStateInCall(int state) { 3162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((state == AudioSystem::MODE_IN_CALL) || 3163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (state == AudioSystem::MODE_IN_COMMUNICATION)); 3164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsCpuLoad() 3167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_CPU_LOAD; 3169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3171f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsMemory() 3172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3173f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_MEMORY; 3174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioOutputDescriptor class implementation 3177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3178b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric LaurentAudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor( 31795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const IOProfile *profile) 318070c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mId(0), mSamplingRate(0), mFormat((audio_format_t)0), 318170c236c9290732782d5267935af1475b8d5ae602Eric Laurent mChannelMask((audio_channel_mask_t)0), mLatency(0), 3182ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), 31835a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0) 3184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // clear usage count for all stream types 3186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 3187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[i] = 0; 3188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurVolume[i] = -1.0; 3189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mMuteCount[i] = 0; 3190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStopTime[i] = 0; 3191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 319285ad78f27ca032e90af0f2100659d12c16322c76Marco Nelissen for (int i = 0; i < NUM_STRATEGIES; i++) { 319385ad78f27ca032e90af0f2100659d12c16322c76Marco Nelissen mStrategyMutedByDevice[i] = false; 319485ad78f27ca032e90af0f2100659d12c16322c76Marco Nelissen } 31953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile != NULL) { 31963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mSamplingRate = profile->mSamplingRates[0]; 31973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mFormat = profile->mFormats[0]; 31983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mChannelMask = profile->mChannelMasks[0]; 31993cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mFlags = profile->mFlags; 32003cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 3201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3203dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Triviaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::device() const 3204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 3206f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 3207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 3208f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return mDevice; 3209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3211f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 32125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::latency() 32135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 32145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isDuplicated()) { 32155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 32165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 32175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return mLatency; 32185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 32205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 32215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::sharesHwModuleWith( 32225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const AudioOutputDescriptor *outputDesc) 32235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 32245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isDuplicated()) { 32255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 32265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (outputDesc->isDuplicated()){ 32275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2); 32285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 322970c236c9290732782d5267935af1475b8d5ae602Eric Laurent return (mProfile->mModule == outputDesc->mProfile->mModule); 32305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 32315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 32325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 3233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta) 3234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // forward usage count change to attached outputs 3236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 3237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput1->changeRefCount(stream, delta); 3238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput2->changeRefCount(stream, delta); 3239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((delta + (int)mRefCount[stream]) < 0) { 324164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]); 3242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] = 0; 3243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 3244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] += delta; 32466a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 3247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3249f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::supportedDevices() 3250b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 3251b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (isDuplicated()) { 3252f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 3253b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 3254b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mProfile->mSupportedDevices ; 3255b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 3256b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 3257b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 325842fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::isActive(uint32_t inPastMs) const 325942fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent{ 326080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return isStrategyActive(NUM_STRATEGIES, inPastMs); 326180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent} 326280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent 326380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy, 326480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent uint32_t inPastMs, 326580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent nsecs_t sysTime) const 326680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent{ 326780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if ((sysTime == 0) && (inPastMs != 0)) { 326880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime = systemTime(); 326980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 327042fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 327180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (((getStrategy((AudioSystem::stream_type)i) == strategy) || 327280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent (NUM_STRATEGIES == strategy)) && 327380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent isStreamActive((AudioSystem::stream_type)i, inPastMs, sysTime)) { 327442fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent return true; 327542fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent } 327642fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent } 327742fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent return false; 327842fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent} 327942fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent 328080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::isStreamActive(AudioSystem::stream_type stream, 328180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent uint32_t inPastMs, 328280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent nsecs_t sysTime) const 328380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent{ 328480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (mRefCount[stream] != 0) { 328580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return true; 328680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 328780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (inPastMs == 0) { 328880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return false; 328980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 329080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (sysTime == 0) { 329180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime = systemTime(); 329280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 329380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 329480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return true; 329580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 329680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return false; 329780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent} 329880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent 329980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent 3300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd) 3301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 3303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 3304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 3305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 3307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3308a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 3309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 331070c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 3311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 3313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 3315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", device()); 3317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 3319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 3321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 3322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioInputDescriptor class implementation 3330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 33315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor(const IOProfile *profile) 333270c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mSamplingRate(0), mFormat((audio_format_t)0), mChannelMask((audio_channel_mask_t)0), 3333ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mDevice(AUDIO_DEVICE_NONE), mRefCount(0), 33345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mInputSource(0), mProfile(profile) 3335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd) 3339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 3341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 3342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 3343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 3345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 3347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 334870c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 3349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 3351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 3353f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3354f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- StreamDescriptor class implementation 3360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3361c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric LaurentAudioPolicyManagerBase::StreamDescriptor::StreamDescriptor() 3362c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 3363c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 3364c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 3365c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 3366c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3367c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentint AudioPolicyManagerBase::StreamDescriptor::getVolumeIndex(audio_devices_t device) 3368c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 3369c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AudioPolicyManagerBase::getDeviceForVolume(device); 3370c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 3371c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 3372c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 3373c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 3374c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return mIndexCur.valueFor(device); 3375c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 3376c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3377c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::StreamDescriptor::dump(int fd) 3378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3379c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent const size_t SIZE = 256; 3380c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent char buffer[SIZE]; 3381c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent String8 result; 3382c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3383c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 3384c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 3385c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 3386c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 3387c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 3388c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.keyAt(i), 3389c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.valueAt(i)); 3390c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 3391c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 3392c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append("\n"); 3393c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3394c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent write(fd, result.string(), result.size()); 3395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- EffectDescriptor class implementation 3398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::EffectDescriptor::dump(int fd) 3400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 3402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 3403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 3404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 34051c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 3406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 3408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Session: %d\n", mSession); 3410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 3412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3413582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 3414582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent result.append(buffer); 3415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 34205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// --- IOProfile class implementation 34215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 342270c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::HwModule::HwModule(const char *name) 342370c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0) 342470c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 342570c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 342670c236c9290732782d5267935af1475b8d5ae602Eric Laurent 342770c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::HwModule::~HwModule() 342870c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 342970c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 343070c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mOutputProfiles[i]; 343170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 343270c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 343370c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mInputProfiles[i]; 343470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 343570c236c9290732782d5267935af1475b8d5ae602Eric Laurent free((void *)mName); 343670c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 343770c236c9290732782d5267935af1475b8d5ae602Eric Laurent 343870c236c9290732782d5267935af1475b8d5ae602Eric Laurentvoid AudioPolicyManagerBase::HwModule::dump(int fd) 343970c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 344070c236c9290732782d5267935af1475b8d5ae602Eric Laurent const size_t SIZE = 256; 344170c236c9290732782d5267935af1475b8d5ae602Eric Laurent char buffer[SIZE]; 344270c236c9290732782d5267935af1475b8d5ae602Eric Laurent String8 result; 344370c236c9290732782d5267935af1475b8d5ae602Eric Laurent 344470c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - name: %s\n", mName); 344570c236c9290732782d5267935af1475b8d5ae602Eric Laurent result.append(buffer); 344670c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 344770c236c9290732782d5267935af1475b8d5ae602Eric Laurent result.append(buffer); 344870c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, result.string(), result.size()); 344970c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mOutputProfiles.size()) { 345070c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, " - outputs:\n", sizeof(" - outputs:\n")); 345170c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 3452599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " output %d:\n", i); 3453599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent write(fd, buffer, strlen(buffer)); 345470c236c9290732782d5267935af1475b8d5ae602Eric Laurent mOutputProfiles[i]->dump(fd); 345570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 345670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 345770c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mInputProfiles.size()) { 345870c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, " - inputs:\n", sizeof(" - inputs:\n")); 345970c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 3460599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent snprintf(buffer, SIZE, " input %d:\n", i); 3461599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent write(fd, buffer, strlen(buffer)); 346270c236c9290732782d5267935af1475b8d5ae602Eric Laurent mInputProfiles[i]->dump(fd); 346370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 346470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 346570c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 346670c236c9290732782d5267935af1475b8d5ae602Eric Laurent 346770c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::IOProfile::IOProfile(HwModule *module) 34680977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent : mFlags((audio_output_flags_t)0), mModule(module) 34695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 34705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 34715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 34725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::IOProfile::~IOProfile() 34735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 347470c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 347570c236c9290732782d5267935af1475b8d5ae602Eric Laurent 347670c236c9290732782d5267935af1475b8d5ae602Eric Laurent// checks if the IO profile is compatible with specified parameters. By convention a value of 0 347770c236c9290732782d5267935af1475b8d5ae602Eric Laurent// means a parameter is don't care 347870c236c9290732782d5267935af1475b8d5ae602Eric Laurentbool AudioPolicyManagerBase::IOProfile::isCompatibleProfile(audio_devices_t device, 347970c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 348070c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t format, 348170c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t channelMask, 34820977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags) const 348370c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 348470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if ((mSupportedDevices & device) != device) { 348570c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 348670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 348770c236c9290732782d5267935af1475b8d5ae602Eric Laurent if ((mFlags & flags) != flags) { 348870c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 348970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 349070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (samplingRate != 0) { 349170c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 349270c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mSamplingRates.size(); i++) 349370c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 349470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mSamplingRates[i] == samplingRate) { 349570c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 349670c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 349770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 349870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mSamplingRates.size()) { 349970c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 350070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 350170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 350270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (format != 0) { 350370c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 350470c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mFormats.size(); i++) 350570c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 350670c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mFormats[i] == format) { 350770c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 350870c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 350970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 351070c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mFormats.size()) { 351170c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 351270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 351370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 351470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (channelMask != 0) { 351570c236c9290732782d5267935af1475b8d5ae602Eric Laurent size_t i; 351670c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (i = 0; i < mChannelMasks.size(); i++) 351770c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 351870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mChannelMasks[i] == channelMask) { 351970c236c9290732782d5267935af1475b8d5ae602Eric Laurent break; 352070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 352170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 352270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (i == mChannelMasks.size()) { 352370c236c9290732782d5267935af1475b8d5ae602Eric Laurent return false; 352470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 352570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 352670c236c9290732782d5267935af1475b8d5ae602Eric Laurent return true; 35275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::IOProfile::dump(int fd) 35305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 35315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const size_t SIZE = 256; 35325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char buffer[SIZE]; 35335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent String8 result; 35345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 353570c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - sampling rates: "); 35365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 35375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 35385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent snprintf(buffer, SIZE, "%d", mSamplingRates[i]); 35395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 35405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mSamplingRates.size() - 1) ? "\n" : ", "); 35415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 354370c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - channel masks: "); 35445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 35455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 3546a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]); 35475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 35485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mChannelMasks.size() - 1) ? "\n" : ", "); 35495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 355170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - formats: "); 35525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 35535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 3554a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald snprintf(buffer, SIZE, "0x%08x", mFormats[i]); 35555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 35565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mFormats.size() - 1) ? "\n" : ", "); 35575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 3559a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald snprintf(buffer, SIZE, " - devices: 0x%04x\n", mSupportedDevices); 35605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 3561a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald snprintf(buffer, SIZE, " - flags: 0x%04x\n", mFlags); 35625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 35635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, result.string(), result.size()); 35655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// --- audio_policy.conf file parsing 35685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentstruct StringToEnum { 35705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *name; 35715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t value; 35725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 35735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#define STRING_TO_ENUM(string) { #string, string } 35755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 35765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sDeviceNameToEnumTable[] = { 35785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE), 35795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER), 35805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET), 35815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE), 35825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO), 35835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP), 35845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL), 35855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET), 3586599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET), 3587599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE), 3588599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY), 3589599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB), 359048387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX), 35915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), 35925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), 35935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET), 35945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL), 35955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL), 35965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC), 359748387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX), 3598ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET), 3599ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET), 3600ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY), 36015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 36025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sFlagNameToEnumTable[] = { 36040977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT), 36050977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), 3606b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), 3607b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), 3608b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD), 3609b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING), 36105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 36115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sFormatNameToEnumTable[] = { 36135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT), 36145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT), 36155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_MP3), 36165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AAC), 36175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_VORBIS), 36185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 36195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sOutChannelsNameToEnumTable[] = { 36215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO), 36225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 36235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 36245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 36255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 36265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sInChannelsNameToEnumTable[] = { 36285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), 36295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), 363060758e27a4be8fc9ac1180f8a4055234e1702cc9Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK), 36315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 36325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentuint32_t AudioPolicyManagerBase::stringToEnum(const struct StringToEnum *table, 36355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent size_t size, 36365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *name) 36375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 36385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < size; i++) { 36395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(table[i].name, name) == 0) { 36405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("stringToEnum() found %s", table[i].name); 36415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return table[i].value; 36425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 36455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 36465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36470977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurentaudio_output_flags_t AudioPolicyManagerBase::parseFlagNames(char *name) 36485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 36495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t flag = 0; 36505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // it is OK to cast name to non const here as we are not going to use it after 36525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // strtok() modifies it 36535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *flagName = strtok(name, "|"); 36545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (flagName != NULL) { 36555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strlen(flagName) != 0) { 36565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flag |= stringToEnum(sFlagNameToEnumTable, 36575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sFlagNameToEnumTable), 36585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flagName); 36595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flagName = strtok(NULL, "|"); 36615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 3662a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald //force direct flag if offload flag is set: offloading implies a direct output stream 3663a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // and all common behaviors are driven by checking only the direct flag 3664a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // this should normally be set appropriately in the policy configuration file 3665a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 3666a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald flag |= AUDIO_OUTPUT_FLAG_DIRECT; 3667a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 3668a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 36690977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent return (audio_output_flags_t)flag; 36705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 36715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_devices_t AudioPolicyManagerBase::parseDeviceNames(char *name) 36735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 36745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t device = 0; 36755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *devName = strtok(name, "|"); 36775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (devName != NULL) { 36785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strlen(devName) != 0) { 36795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device |= stringToEnum(sDeviceNameToEnumTable, 36805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 36815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devName); 36825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 36835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devName = strtok(NULL, "|"); 36845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 3685c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi return device; 36865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 36875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadSamplingRates(char *name, IOProfile *profile) 36895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 36905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *str = strtok(name, "|"); 36915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 36923cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling 36933cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // rates should be read from the output stream after it is opened for the first time 36943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 36953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.add(0); 36963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 36973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 36983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 36995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 37005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t rate = atoi(str); 37015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (rate != 0) { 37025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadSamplingRates() adding rate %d", rate); 37035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSamplingRates.add(rate); 37045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 37065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 37085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 37095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadFormats(char *name, IOProfile *profile) 37115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 37125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *str = strtok(name, "|"); 37135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37143cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mFormats indicates the supported formats 37153cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // should be read from the output stream after it is opened for the first time 37163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 37173cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mFormats.add((audio_format_t)0); 37183cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 37193cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 37203cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 37215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 37225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable, 37235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 37245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str); 37255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (format != 0) { 37265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mFormats.add(format); 37275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 37295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 37315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 37325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadInChannels(char *name, IOProfile *profile) 37345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 37355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *str = strtok(name, "|"); 37365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInChannels() %s", name); 37383cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 37393cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 37403cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.add((audio_channel_mask_t)0); 37413cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 37423cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 37433cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 37445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 37455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_channel_mask_t channelMask = 37465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 37475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 37485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str); 37495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (channelMask != 0) { 37505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInChannels() adding channelMask %04x", channelMask); 37515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mChannelMasks.add(channelMask); 37525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 37545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 37565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 37575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadOutChannels(char *name, IOProfile *profile) 37595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 37605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *str = strtok(name, "|"); 37613cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 37623cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("loadOutChannels() %s", name); 37633cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 37643cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mChannelMasks indicates the supported channel 37653cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // masks should be read from the output stream after it is opened for the first time 37663cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 37673cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.add((audio_channel_mask_t)0); 37683cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 37693cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 37705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 37723cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_channel_mask_t channelMask = 37733cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 37743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 37753cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent str); 37765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (channelMask != 0) { 37775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mChannelMasks.add(channelMask); 37785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 37805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 37815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 37825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 37835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 378470c236c9290732782d5267935af1475b8d5ae602Eric Laurentstatus_t AudioPolicyManagerBase::loadInput(cnode *root, HwModule *module) 37855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 37865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = root->first_child; 37875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = new IOProfile(module); 37895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 37915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 37925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadSamplingRates((char *)node->value, profile); 37935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 37945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadFormats((char *)node->value, profile); 37955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 37965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadInChannels((char *)node->value, profile); 37975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 37985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices = parseDeviceNames((char *)node->value); 37995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 38005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 38015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 3802ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(profile->mSupportedDevices == AUDIO_DEVICE_NONE, 38035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported devices"); 38045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 38055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported channel masks"); 38065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 38075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported sampling rates"); 38085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 38095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported formats"); 3810ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((profile->mSupportedDevices != AUDIO_DEVICE_NONE) && 38115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mChannelMasks.size() != 0) && 38125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mSamplingRates.size() != 0) && 38135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mFormats.size() != 0)) { 38145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 38155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInput() adding input mSupportedDevices %04x", profile->mSupportedDevices); 38165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 381770c236c9290732782d5267935af1475b8d5ae602Eric Laurent module->mInputProfiles.add(profile); 38185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 38195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 38205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent delete profile; 38215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return BAD_VALUE; 38225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 38235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 38245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 382570c236c9290732782d5267935af1475b8d5ae602Eric Laurentstatus_t AudioPolicyManagerBase::loadOutput(cnode *root, HwModule *module) 38265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 38275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = root->first_child; 38285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 38295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = new IOProfile(module); 38305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 38315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 38325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 38335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadSamplingRates((char *)node->value, profile); 38345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 38355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadFormats((char *)node->value, profile); 38365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 38375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadOutChannels((char *)node->value, profile); 38385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 38395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices = parseDeviceNames((char *)node->value); 38405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FLAGS_TAG) == 0) { 38415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mFlags = parseFlagNames((char *)node->value); 38425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 38435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 38445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 3845ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(profile->mSupportedDevices == AUDIO_DEVICE_NONE, 38465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported devices"); 38475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 38485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported channel masks"); 38495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 38505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported sampling rates"); 38515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 38525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported formats"); 3853ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((profile->mSupportedDevices != AUDIO_DEVICE_NONE) && 38545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mChannelMasks.size() != 0) && 38555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mSamplingRates.size() != 0) && 38565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mFormats.size() != 0)) { 38575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 38585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadOutput() adding output mSupportedDevices %04x, mFlags %04x", 38595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices, profile->mFlags); 38605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 386170c236c9290732782d5267935af1475b8d5ae602Eric Laurent module->mOutputProfiles.add(profile); 38625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 38635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 38645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent delete profile; 38655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return BAD_VALUE; 38665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 38675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 38685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 38695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadHwModule(cnode *root) 38705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 38715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, OUTPUTS_TAG); 38725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status_t status = NAME_NOT_FOUND; 387370c236c9290732782d5267935af1475b8d5ae602Eric Laurent 387470c236c9290732782d5267935af1475b8d5ae602Eric Laurent HwModule *module = new HwModule(root->name); 387570c236c9290732782d5267935af1475b8d5ae602Eric Laurent 38765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node != NULL) { 38775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_A2DP) == 0) { 38785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mHasA2dp = true; 3879599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } else if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_USB) == 0) { 3880599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mHasUsb = true; 388148387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } else if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX) == 0) { 388248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi mHasRemoteSubmix = true; 38835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 3884599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent 38855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 38865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 38875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModule() loading output %s", node->name); 388870c236c9290732782d5267935af1475b8d5ae602Eric Laurent status_t tmpStatus = loadOutput(node, module); 38895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 38905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status = tmpStatus; 38915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 38925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 38935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 38945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 38955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = config_find(root, INPUTS_TAG); 38965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node != NULL) { 38975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 38985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 38995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModule() loading input %s", node->name); 390070c236c9290732782d5267935af1475b8d5ae602Eric Laurent status_t tmpStatus = loadInput(node, module); 39015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 39025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status = tmpStatus; 39035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 39055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NO_ERROR) { 390870c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules.add(module); 390970c236c9290732782d5267935af1475b8d5ae602Eric Laurent } else { 391070c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete module; 39115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 39135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadHwModules(cnode *root) 39155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 39165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); 39175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node == NULL) { 39185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 39195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 39225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 39235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModules() loading module %s", node->name); 39245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadHwModule(node); 39255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 39265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 39285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadGlobalConfig(cnode *root) 39305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 39315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, GLOBAL_CONFIG_TAG); 39325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node == NULL) { 39335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 39345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 39365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 39375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { 39385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAttachedOutputDevices = parseDeviceNames((char *)node->value); 3939ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(mAttachedOutputDevices == AUDIO_DEVICE_NONE, 3940c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi "loadGlobalConfig() no attached output devices"); 39415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mAttachedOutputDevices %04x", mAttachedOutputDevices); 39425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { 39435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mDefaultOutputDevice = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable, 39445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 39455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (char *)node->value); 3946ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(mDefaultOutputDevice == AUDIO_DEVICE_NONE, 3947c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi "loadGlobalConfig() default device not specified"); 39485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mDefaultOutputDevice %04x", mDefaultOutputDevice); 39495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { 3950ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableInputDevices = parseDeviceNames((char *)node->value) & ~AUDIO_DEVICE_BIT_IN; 39515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mAvailableInputDevices %04x", mAvailableInputDevices); 39525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 39545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 39565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentstatus_t AudioPolicyManagerBase::loadAudioPolicyConfig(const char *path) 39585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 39595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *root; 39605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *data; 39615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent data = (char *)load_file(path, NULL); 39635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (data == NULL) { 39645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return -ENODEV; 39655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent root = config_node("", ""); 39675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent config_load(root, data); 39685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadGlobalConfig(root); 39705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadHwModules(root); 39715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent config_free(root); 39735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent free(root); 39745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent free(data); 39755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39765ec145df7708564d385fd3fb764085321cf4c253Dima Zavin ALOGI("loadAudioPolicyConfig() loaded %s\n", path); 39775ec145df7708564d385fd3fb764085321cf4c253Dima Zavin 39785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 39795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 3980f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3981739022f26a7127ba76a98dda65411496086114a7Dima Zavinvoid AudioPolicyManagerBase::defaultAudioPolicyConfig(void) 3982739022f26a7127ba76a98dda65411496086114a7Dima Zavin{ 3983739022f26a7127ba76a98dda65411496086114a7Dima Zavin HwModule *module; 3984739022f26a7127ba76a98dda65411496086114a7Dima Zavin IOProfile *profile; 3985739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3986739022f26a7127ba76a98dda65411496086114a7Dima Zavin mDefaultOutputDevice = AUDIO_DEVICE_OUT_SPEAKER; 3987739022f26a7127ba76a98dda65411496086114a7Dima Zavin mAttachedOutputDevices = AUDIO_DEVICE_OUT_SPEAKER; 3988ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableInputDevices = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; 3989739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3990739022f26a7127ba76a98dda65411496086114a7Dima Zavin module = new HwModule("primary"); 3991739022f26a7127ba76a98dda65411496086114a7Dima Zavin 3992739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile = new IOProfile(module); 3993739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSamplingRates.add(44100); 3994739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 3995739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO); 3996739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSupportedDevices = AUDIO_DEVICE_OUT_SPEAKER; 3997739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY; 3998739022f26a7127ba76a98dda65411496086114a7Dima Zavin module->mOutputProfiles.add(profile); 3999739022f26a7127ba76a98dda65411496086114a7Dima Zavin 4000739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile = new IOProfile(module); 4001739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSamplingRates.add(8000); 4002739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 4003739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO); 4004739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSupportedDevices = AUDIO_DEVICE_IN_BUILTIN_MIC; 4005739022f26a7127ba76a98dda65411496086114a7Dima Zavin module->mInputProfiles.add(profile); 4006739022f26a7127ba76a98dda65411496086114a7Dima Zavin 4007739022f26a7127ba76a98dda65411496086114a7Dima Zavin mHwModules.add(module); 4008739022f26a7127ba76a98dda65411496086114a7Dima Zavin} 4009f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4010f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin}; // namespace android 4011