AudioPolicyManagerBase.cpp revision 6a36ec43e62e07921da08456d2b309edabb03a0c
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 34c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross#include <inttypes.h> 35c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross#include <math.h> 36c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross 37c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross#include <cutils/properties.h> 38f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <utils/Log.h> 39accf5b4b6232f67208f4bfa8e2f1546e345d6e9fDaniel Erat#include <utils/Timers.h> 40c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross 4108b014d9e509c9163db6b33a63852e73db4d07ccEric Laurent#include <hardware/audio.h> 42c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross#include <hardware/audio_effect.h> 435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#include <hardware_legacy/audio_policy_conf.h> 44c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross#include <hardware_legacy/AudioPolicyManagerBase.h> 45f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 46e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinnamespace android_audio_legacy { 47f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 48f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 49f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyInterface implementation 50f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 51f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 52f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 53c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivistatus_t AudioPolicyManagerBase::setDeviceConnectionState(audio_devices_t device, 54f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state, 55f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 56f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 572d2ea50df16fc1a04f1ebf8772c65c56e4f5ecfaGlenn Kasten // device_address can be NULL and should be handled as an empty string in this case, 582d2ea50df16fc1a04f1ebf8772c65c56e4f5ecfaGlenn Kasten // and it is not checked by AudioPolicyInterfaceImpl.cpp 592d2ea50df16fc1a04f1ebf8772c65c56e4f5ecfaGlenn Kasten if (device_address == NULL) { 602d2ea50df16fc1a04f1ebf8772c65c56e4f5ecfaGlenn Kasten device_address = ""; 612d2ea50df16fc1a04f1ebf8772c65c56e4f5ecfaGlenn Kasten } 62c26f454f8d841657542916cdd140a9896a89ad20Paul McLean ALOGV("setDeviceConnectionState() device: 0x%X, state %d, address %s", device, state, device_address); 63f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 64f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // connect/disconnect only 1 device at a time 65ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; 66f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 67f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { 685efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid address: %s", device_address); 69f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 70f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 71f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 72f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output devices 73c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_output_device(device)) { 74fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean SortedVector <audio_io_handle_t> outputs; 75f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7633bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood if (!mHasA2dp && audio_is_a2dp_out_device(device)) { 7748387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("setDeviceConnectionState() invalid A2DP device: %x", device); 78f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 79f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 80fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (!mHasUsb && audio_is_usb_out_device(device)) { 8148387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("setDeviceConnectionState() invalid USB audio device: %x", device); 8248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi return BAD_VALUE; 8348387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 8448387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi if (!mHasRemoteSubmix && audio_is_remote_submix_device((audio_devices_t)device)) { 8548387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("setDeviceConnectionState() invalid remote submix audio device: %x", device); 86599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent return BAD_VALUE; 87599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 88f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 89c952527e6f89d5427881462823514be9d79f13e6Eric Laurent // save a copy of the opened output descriptors before any output is opened or closed 90c952527e6f89d5427881462823514be9d79f13e6Eric Laurent // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() 91c952527e6f89d5427881462823514be9d79f13e6Eric Laurent mPreviousOutputs = mOutputs; 929f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent String8 paramStr; 93f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 94f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 95f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device connection 96f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: 97f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableOutputDevices & device) { 9864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %x", device); 99f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1016a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() connecting device %x", device); 102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 10333bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood if (mHasA2dp && audio_is_a2dp_out_device(device)) { 1049f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent // handle A2DP device connection 1059f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent AudioParameter param; 1069f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), String8(device_address)); 1079f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent paramStr = param.toString(); 108fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } else if (mHasUsb && audio_is_usb_out_device(device)) { 1099f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent // handle USB device connection 1109f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent paramStr = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 1119f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent } 1129f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent 1139f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent if (checkOutputsForDevice(device, state, outputs, paramStr) != NO_ERROR) { 1143cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return INVALID_OPERATION; 1153cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 116c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs", 1173cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.size()); 118f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // register new device as available 119f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device); 120f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 12133bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood if (mHasA2dp && audio_is_a2dp_out_device(device)) { 1229f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent // handle A2DP device connection 1239f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 1249f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent mA2dpSuspended = false; 1259f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent } else if (audio_is_bluetooth_sco_device(device)) { 1269f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent // handle SCO device connection 1279f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 128fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } else if (mHasUsb && audio_is_usb_out_device(device)) { 1299f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent // handle USB device connection 130fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mUsbOutCardAndDevice = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 131f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1329f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent 133f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 134f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device disconnection 135f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableOutputDevices & device)) { 13764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %x", device); 138f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 139f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 140f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1416a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() disconnecting device %x", device); 142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // remove device from available output devices 143f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device); 1449f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent checkOutputsForDevice(device, state, outputs, paramStr); 145fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 14633bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood if (mHasA2dp && audio_is_a2dp_out_device(device)) { 1473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle A2DP device disconnection 148b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpDeviceAddress = ""; 149b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpSuspended = false; 150c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (audio_is_bluetooth_sco_device(device)) { 1513cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle SCO device disconnection 152b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mScoDeviceAddress = ""; 153fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } else if (mHasUsb && audio_is_usb_out_device(device)) { 1543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // handle USB device disconnection 155fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mUsbOutCardAndDevice = ""; 156f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 15748387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi // not currently handling multiple simultaneous submixes: ignoring remote submix 15848387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi // case and address 159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 1625efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 168b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // outputs must be closed after checkOutputForAllStrategies() is executed 1693cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!outputs.isEmpty()) { 1703cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t i = 0; i < outputs.size(); i++) { 171a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]); 1723cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // close unused outputs after device disconnection or direct outputs that have been 1733cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // opened by checkOutputsForDevice() to query dynamic parameters 1743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if ((state == AudioSystem::DEVICE_STATE_UNAVAILABLE) || 175a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) && 176a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald (desc->mDirectOpenCount == 0))) { 1773cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent closeOutput(outputs[i]); 1783cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1793cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 180f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 182c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 1835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1842c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent // do not force device change on duplicated output because if device is 0, it will 1852c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent // also force a device 0 for the two outputs it is duplicated to which may override 1862c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent // a valid device selection on those outputs. 18776e97d3950f2654adbb0a415218b6d048200c395Eric Laurent setOutputDevice(mOutputs.keyAt(i), 18876e97d3950f2654adbb0a415218b6d048200c395Eric Laurent getNewDevice(mOutputs.keyAt(i), true /*fromCache*/), 1892c72e9faa5ad5e324b85b78e383dd85c8bdc04a9Eric Laurent !mOutputs.valueAt(i)->isDuplicated(), 19076e97d3950f2654adbb0a415218b6d048200c395Eric Laurent 0); 1915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 193806fab660adf8a5c3d36e9411d214a4942cd67e9Eric Laurent return NO_ERROR; 194fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } // end if is output device 195fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 196f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input devices 197c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_input_device(device)) { 198fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean SortedVector <audio_io_handle_t> inputs; 199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 200fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean String8 paramStr; 201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device connection 204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: { 205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableInputDevices & device) { 20664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %d", device); 207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 209fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 210fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (mHasUsb && audio_is_usb_in_device(device)) { 211fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // handle USB device connection 212fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean paramStr = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 21333bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood } else if (mHasA2dp && audio_is_a2dp_in_device(device)) { 21433bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood // handle A2DP device connection 21533bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood AudioParameter param; 21633bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood param.add(String8(AUDIO_PARAMETER_A2DP_SOURCE_ADDRESS), String8(device_address)); 21733bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood paramStr = param.toString(); 218fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 219fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 220fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (checkInputsForDevice(device, state, inputs, paramStr) != NO_ERROR) { 221fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean return INVALID_OPERATION; 222fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 223ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableInputDevices = mAvailableInputDevices | (device & ~AUDIO_DEVICE_BIT_IN); 224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device disconnection 228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableInputDevices & device)) { 23064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %d", device); 231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 233fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean checkInputsForDevice(device, state, inputs, paramStr); 2345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAvailableInputDevices = (audio_devices_t) (mAvailableInputDevices & ~device); 235fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } break; 236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 2385efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 242fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean closeAllInputs(); 243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 245fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } // end if is input device 246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() invalid device: %x", device); 248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 251c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel TriviAudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(audio_devices_t device, 252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2542d2ea50df16fc1a04f1ebf8772c65c56e4f5ecfaGlenn Kasten // similar to setDeviceConnectionState 2552d2ea50df16fc1a04f1ebf8772c65c56e4f5ecfaGlenn Kasten if (device_address == NULL) { 2562d2ea50df16fc1a04f1ebf8772c65c56e4f5ecfaGlenn Kasten device_address = ""; 2572d2ea50df16fc1a04f1ebf8772c65c56e4f5ecfaGlenn Kasten } 258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE; 259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 address = String8(device_address); 260c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_output_device(device)) { 261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableOutputDevices) { 26233bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood if (audio_is_a2dp_out_device(device) && 2635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (!mHasA2dp || (address != "" && mA2dpDeviceAddress != address))) { 264f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 266c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (audio_is_bluetooth_sco_device(device) && 267f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin address != "" && mScoDeviceAddress != address) { 268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 269f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 270fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (audio_is_usb_out_device(device) && 271fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean (!mHasUsb || (address != "" && mUsbOutCardAndDevice != address))) { 27248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi ALOGE("getDeviceConnectionState() invalid device: %x", device); 27348387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi return state; 27448387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 27548387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi if (audio_is_remote_submix_device((audio_devices_t)device) && !mHasRemoteSubmix) { 276599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent return state; 277599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 280c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (audio_is_input_device(device)) { 281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableInputDevices) { 282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 283f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 284f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setPhoneState(int state) 290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2916a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() state %d", state); 292ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent audio_devices_t newDevice = AUDIO_DEVICE_NONE; 293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state < 0 || state >= AudioSystem::NUM_MODES) { 29464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() invalid state %d", state); 295f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 297f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == mPhoneState ) { 29964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() setting same state %d", state); 300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if leaving call state, handle special case of active streams 304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 3066a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, true); 309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store previous phone state for management of sonification strategy below 313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int oldState = mPhoneState; 314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mPhoneState = state; 315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool force = false; 316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // are we entering or starting a call 318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isStateInCall(oldState) && isStateInCall(state)) { 3196a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Entering call in setPhoneState()"); 320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when starting a call 321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 32387e28f7b352fb77f46e16ebcdd85cbf01396a203Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 32487e28f7b352fb77f46e16ebcdd85cbf01396a203Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 32587e28f7b352fb77f46e16ebcdd85cbf01396a203Eric Laurent sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j]; 32687e28f7b352fb77f46e16ebcdd85cbf01396a203Eric Laurent } 327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(oldState) && !isStateInCall(state)) { 3286a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Exiting call in setPhoneState()"); 329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when exiting a call 330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 33287e28f7b352fb77f46e16ebcdd85cbf01396a203Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 33387e28f7b352fb77f46e16ebcdd85cbf01396a203Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 33487e28f7b352fb77f46e16ebcdd85cbf01396a203Eric Laurent sVolumeProfiles[AUDIO_STREAM_DTMF][j]; 33587e28f7b352fb77f46e16ebcdd85cbf01396a203Eric Laurent } 336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(state) && (state != oldState)) { 3376a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when switching between telephony and VoIP 339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check for device and output changes triggered by new phone state 3445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/); 345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 347c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 349b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when ending call 352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 353ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) { 354f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin newDevice = hwOutputDesc->device(); 355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int delayMs = 0; 358772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani if (isStateInCall(state)) { 35980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent nsecs_t sysTime = systemTime(); 360772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani for (size_t i = 0; i < mOutputs.size(); i++) { 361772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani AudioOutputDescriptor *desc = mOutputs.valueAt(i); 36280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent // mute media and sonification strategies and delay device switch by the largest 36380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent // latency of any output where either strategy is active. 36480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent // This avoid sending the ring tone or music tail into the earpiece or headset. 36580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if ((desc->isStrategyActive(STRATEGY_MEDIA, 36680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 36780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime) || 36880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent desc->isStrategyActive(STRATEGY_SONIFICATION, 36980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 37080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime)) && 37180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent (delayMs < (int)desc->mLatency*2)) { 37280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent delayMs = desc->mLatency*2; 373772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani } 37480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); 37580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, 37680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); 37780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i)); 37880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS, 37980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/)); 380772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani } 381772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani } 382772686310a3bc44d93591349e174a60360a3d30dSathishKumar Mani 383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // change routing is necessary 384b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setOutputDevice(mPrimaryOutput, newDevice, force, delayMs); 385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if entering in call state, handle special case of active streams 387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(state)) { 3896a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, true, true); 392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == AudioSystem::MODE_RINGTONE && 397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = true; 399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = false; 401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) 405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 4066a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool forceVolumeReeval = false; 409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(usage) { 410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_COMMUNICATION: 411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO && 412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 41364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_MEDIA: 420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP && 421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 4231afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE && 42431363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi config != AudioSystem::FORCE_NO_BT_A2DP) { 42564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_RECORD: 431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY && 432f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 43364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 434f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 435f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 436f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_DOCK: 439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK && 440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_BT_DESK_DOCK && 441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_DIGITAL_DOCK) { 44464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 449738207def5f691d605ae33d041116829a74513a9Eric Laurent case AudioSystem::FOR_SYSTEM: 450738207def5f691d605ae33d041116829a74513a9Eric Laurent if (config != AudioSystem::FORCE_NONE && 451738207def5f691d605ae33d041116829a74513a9Eric Laurent config != AudioSystem::FORCE_SYSTEM_ENFORCED) { 452738207def5f691d605ae33d041116829a74513a9Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config); 453738207def5f691d605ae33d041116829a74513a9Eric Laurent } 454738207def5f691d605ae33d041116829a74513a9Eric Laurent forceVolumeReeval = true; 455738207def5f691d605ae33d041116829a74513a9Eric Laurent mForceUse[usage] = config; 456738207def5f691d605ae33d041116829a74513a9Eric Laurent break; 457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 45864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid usage %d", usage); 459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 461f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // check for device and output changes triggered by new force usage 463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 464f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 465c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 4665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 4675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 4685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, true /*fromCache*/); 469ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE)); 470ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) { 4715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent applyStreamVolumes(output, newDevice, 0, true); 4725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 4785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 479ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { 4806a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() changing device from %x to %x for input %d", 481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 490f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage) 492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mForceUse[usage]; 494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 495f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setSystemProperty(const char* property, const char* value) 497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 4986a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setSystemProperty() property %s, value %s", property, value); 499f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 501b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent// Find a direct output profile compatible with the parameters passed, even if the input flags do 502b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent// not explicitly request a direct output 5033cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric LaurentAudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getProfileForDirectOutput( 5043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_devices_t device, 50570c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 5065082dbeb19e37883230510129c94336063a4f91cGlenn Kasten audio_format_t format, 5072c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten audio_channel_mask_t channelMask, 5080977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags) 50970c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 51070c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 51170c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 51270c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 51370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 51470c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { 515a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; 516a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { 517a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (profile->isCompatibleProfile(device, samplingRate, format, 518a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald channelMask, 519a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) { 520a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (mAvailableOutputDevices & profile->mSupportedDevices) { 521a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return mHwModules[i]->mOutputProfiles[j]; 522a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 523a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 524b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } else { 525a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (profile->isCompatibleProfile(device, samplingRate, format, 5263cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent channelMask, 5273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AUDIO_OUTPUT_FLAG_DIRECT)) { 528a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (mAvailableOutputDevices & profile->mSupportedDevices) { 529a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return mHwModules[i]->mOutputProfiles[j]; 530a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 531a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 532a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 53370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 53470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 53570c236c9290732782d5267935af1475b8d5ae602Eric Laurent return 0; 53670c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 53770c236c9290732782d5267935af1475b8d5ae602Eric Laurent 538f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream, 539f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 5405082dbeb19e37883230510129c94336063a4f91cGlenn Kasten audio_format_t format, 5412c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten audio_channel_mask_t channelMask, 542b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald AudioSystem::output_flags flags, 543b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald const audio_offload_info_t *offloadInfo) 544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t output = 0; 546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t latency = 0; 547f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); 5485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 549a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x", 550a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald device, stream, samplingRate, format, channelMask, flags); 551f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 552f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 553f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mCurOutput != 0) { 55470c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", 555f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 557f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput] == 0) { 5586a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() opening test output"); 5593cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = mTestDevice; 561f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = mTestSamplingRate; 562f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFormat = mTestFormat; 56370c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mChannelMask = mTestChannels; 564f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = mTestLatencyMs; 5650977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent outputDesc->mFlags = (audio_output_flags_t)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0); 566f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 56770c236c9290732782d5267935af1475b8d5ae602Eric Laurent mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice, 568f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 569f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 57070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 571f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 572b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald outputDesc->mFlags, 573b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald offloadInfo); 574f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput]) { 575f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 576f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"),mCurOutput); 577f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 578f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(mTestOutputs[mCurOutput], outputDesc); 579f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 580f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 581f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mTestOutputs[mCurOutput]; 582f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 583f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 584f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 585f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a direct output if required by specified parameters 586a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald //force direct flag if offload flag is set: offloading implies a direct output stream 587a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // and all common behaviors are driven by checking only the direct flag 588a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // this should normally be set appropriately in the policy configuration file 589a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 590a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald flags = (AudioSystem::output_flags)(flags | AUDIO_OUTPUT_FLAG_DIRECT); 591a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 592a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 593000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 594000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 595000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // detects there is an active non offloadable effect. 596000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 597000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 598000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // in the background. 599000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent IOProfile *profile = NULL; 600000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) || 601000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent !isNonOffloadableEffectEnabled()) { 602000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent profile = getProfileForDirectOutput(device, 603000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent samplingRate, 604000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent format, 605000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent channelMask, 606000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent (audio_output_flags_t)flags); 607000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent } 608000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent 6093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile != NULL) { 6105a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent AudioOutputDescriptor *outputDesc = NULL; 611f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6125a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 6135a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 6145a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (!desc->isDuplicated() && (profile == desc->mProfile)) { 6155a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc = desc; 6165a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent // reuse direct output if currently open and configured with same parameters 6175a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if ((samplingRate == outputDesc->mSamplingRate) && 6185a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent (format == outputDesc->mFormat) && 6195a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent (channelMask == outputDesc->mChannelMask)) { 6205a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc->mDirectOpenCount++; 621a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i)); 6225a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent return mOutputs.keyAt(i); 6235a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 6245a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 6255a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 6265a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent // close direct output if currently open and configured with different parameters 6275a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (outputDesc != NULL) { 6285a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent closeOutput(outputDesc->mId); 6295a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 6305a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc = new AudioOutputDescriptor(profile); 631f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = device; 632f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = samplingRate; 6332d749b0bda4ae60ef1a940eeba86121b2e94d07dGlenn Kasten outputDesc->mFormat = format; 6342c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten outputDesc->mChannelMask = channelMask; 635f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = 0; 636a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags); 637f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 638f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mStopTime[stream] = 0; 6395a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent outputDesc->mDirectOpenCount = 1; 6403cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent output = mpClientInterface->openOutput(profile->mModule->mHandle, 64170c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 642f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 643f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 64470c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 645f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 646a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald outputDesc->mFlags, 647a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo); 648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6499f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi // only accept an output with the requested parameters 650f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == 0 || 651f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || 6522d749b0bda4ae60ef1a940eeba86121b2e94d07dGlenn Kasten (format != AUDIO_FORMAT_DEFAULT && format != outputDesc->mFormat) || 65370c236c9290732782d5267935af1475b8d5ae602Eric Laurent (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { 6543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," 6553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent "format %d %d, channelMask %04x %04x", output, samplingRate, 6563cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, 6573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputDesc->mChannelMask); 658f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output != 0) { 659f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 660f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete outputDesc; 662f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 66445c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t srcOutput = getOutputForEffect(); 665f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(output, outputDesc); 66645c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 66745c763947b657b347211dc9388754e05d30d0467Eric Laurent if (dstOutput == output) { 66845c763947b657b347211dc9388754e05d30d0467Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput); 66945c763947b657b347211dc9388754e05d30d0467Eric Laurent } 6705a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent mPreviousOutputs = mOutputs; 6715a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent ALOGV("getOutput() returns new direct output %d", output); 672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 673f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 674f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6759f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi // ignoring channel mask due to downmix capability in mixer 6769f1f9b509c930830f6f32e9ef6c2c8a03d6fa96eJean-Michel Trivi 677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a non direct output 678f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 679a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // for non direct outputs, only PCM is supported 6802d749b0bda4ae60ef1a940eeba86121b2e94d07dGlenn Kasten if (audio_is_linear_pcm(format)) { 681a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // get which output is suitable for the specified stream. The actual 682a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // routing change will happen when startOutput() will be called 683a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs); 684f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 685a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald output = selectOutput(outputs, flags); 686a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 687a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d," 68870c236c9290732782d5267935af1475b8d5ae602Eric Laurent "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); 689f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("getOutput() returns output %d", output); 6915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 693f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 694f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::selectOutput(const SortedVector<audio_io_handle_t>& outputs, 6965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioSystem::output_flags flags) 6975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 6985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // select one output among several that provide a path to a particular device or set of 6995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // devices (the list was previously build by getOutputsForDevice()). 7005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // The priority is as follows: 7015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 1: the output with the highest number of requested policy flags 7025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 2: the primary output 7035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // 3: the first output in the list 7045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 7055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputs.size() == 0) { 7065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 7075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputs.size() == 1) { 7095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputs[0]; 7105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 7125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent int maxCommonFlags = 0; 7135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t outputFlags = 0; 7145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t outputPrimary = 0; 7155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 7165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 7175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]); 7185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!outputDesc->isDuplicated()) { 7195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent int commonFlags = (int)AudioSystem::popCount(outputDesc->mProfile->mFlags & flags); 7205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (commonFlags > maxCommonFlags) { 7215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputFlags = outputs[i]; 7225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent maxCommonFlags = commonFlags; 7235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); 7245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7250977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 7265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputPrimary = outputs[i]; 7275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 7315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputFlags != 0) { 7325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputFlags; 7335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputPrimary != 0) { 7355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputPrimary; 7365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 7385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return outputs[0]; 7395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 7405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 741f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, 742f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 7436a36ec43e62e07921da08456d2b309edabb03a0cGlenn Kasten audio_session_t session) 744f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7456a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 746f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 747f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 7486742b021061741c309d6e45c074b45a560f11086Glenn Kasten ALOGW("startOutput() unknown output %d", output); 749f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 750f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 751f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 752f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 753f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // increment usage count for this stream on the requested output: 755f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE that the usage count is the same for duplicated output and hardware output which is 7565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // necessary for a correct control of hardware output routing by startOutput() and stopOutput() 757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, 1); 758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->mRefCount[stream] == 1) { 7605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 761b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent routing_strategy strategy = getStrategy(stream); 762b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent bool shouldWait = (strategy == STRATEGY_SONIFICATION) || 763b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent (strategy == STRATEGY_SONIFICATION_RESPECTFUL); 764b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t waitMs = 0; 7655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool force = false; 7665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 7675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 768b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (desc != outputDesc) { 769b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // force a device change if any other output is managed by the same hw 770b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // module and has a current device selection that differs from selected device. 771b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // In this case, the audio HAL must receive the new device selection so that it can 772b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // change the device currently selected by the other active output. 773b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (outputDesc->sharesHwModuleWith(desc) && 7745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent desc->device() != newDevice) { 775b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent force = true; 776b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 777b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // wait for audio on other active outputs to be presented when starting 778b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent // a notification so that audio focus effect can propagate. 77942fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent uint32_t latency = desc->latency(); 78042fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { 78142fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent waitMs = latency; 782b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 7835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 7845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 785b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); 786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 7875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // handle special case for sonification while in call 7885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isInCall()) { 7895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleIncallSonification(stream, true, false); 7905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 791c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 7925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // apply volume rules for current stream and device if necessary 7935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent checkAndSetVolume(stream, 794c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi mStreams[stream].getVolumeIndex(newDevice), 7955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent output, 7965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent newDevice); 79712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 7985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // update the outputs if starting an output with a stream that can affect notification 7995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // routing 8005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleNotificationRoutingForStream(stream); 801b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent if (waitMs > muteWaitMs) { 802b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent usleep((waitMs - muteWaitMs) * 2 * 1000); 803b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent } 8045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 805f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 806f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 807f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 8085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 809f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, 810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 8116a36ec43e62e07921da08456d2b309edabb03a0cGlenn Kasten audio_session_t session) 812f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8136a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 814f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 815f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 8166742b021061741c309d6e45c074b45a560f11086Glenn Kasten ALOGW("stopOutput() unknown output %d", output); 817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 819f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 820f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 821f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 822f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle special case for sonification while in call 823f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 824f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, false); 825f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 826f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 827f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream] > 0) { 828f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // decrement usage count of this stream on the output 829f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, -1); 830f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store time at which the stream was stopped - see isStreamActive() 8315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->mRefCount[stream] == 0) { 8325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStopTime[stream] = systemTime(); 8335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 8345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // delay the device switch by twice the latency because stopOutput() is executed when 8355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // the track stop() command is received and at that time the audio track buffer can 8365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // still contain data that needs to be drained. The latency only covers the audio HAL 8375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // and kernel buffers. Also the latency does not always include additional delay in the 8385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // audio path (audio DSP, CODEC ...) 8395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); 8405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 8415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // force restoring the device selection on other active outputs if it differs from the 8425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // one being selected for this output 8435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 8445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(i); 8455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 8465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (curOutput != output && 84780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent desc->isActive() && 8485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->sharesHwModuleWith(desc) && 849a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald (newDevice != desc->device())) { 8505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setOutputDevice(curOutput, 8515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent getNewDevice(curOutput, false /*fromCache*/), 8525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent true, 8535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mLatency*2); 8545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 8555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 8565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // update the outputs if stopping one with a stream that can affect notification routing 8575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent handleNotificationRoutingForStream(stream); 858f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 859f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 860f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 86164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() refcount is already 0 for output %d", output); 862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 863f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 864f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 865f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 866f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output) 867f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8686a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseOutput() %d", output); 869f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 870f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 87164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseOutput() releasing unknown output %d", output); 872f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 873f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 874f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 875f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 876f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int testIndex = testOutputIndex(output); 877f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (testIndex != 0) { 878f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 87980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (outputDesc->isActive()) { 880f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 881f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(index); 882f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(output); 883f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[testIndex] = 0; 884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 885f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 886f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 887f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 888f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 8895a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(index); 8905a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (desc->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) { 8915a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (desc->mDirectOpenCount <= 0) { 8925a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent ALOGW("releaseOutput() invalid open count %d for output %d", 8935a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent desc->mDirectOpenCount, output); 8945a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent return; 8955a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 8965a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent if (--desc->mDirectOpenCount == 0) { 8975a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent closeOutput(output); 89845c763947b657b347211dc9388754e05d30d0467Eric Laurent // If effects where present on the output, audioflinger moved them to the primary 89945c763947b657b347211dc9388754e05d30d0467Eric Laurent // output by default: move them back to the appropriate output. 90045c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 90145c763947b657b347211dc9388754e05d30d0467Eric Laurent if (dstOutput != mPrimaryOutput) { 90245c763947b657b347211dc9388754e05d30d0467Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput); 90345c763947b657b347211dc9388754e05d30d0467Eric Laurent } 9045a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent } 905f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 906f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 90845c763947b657b347211dc9388754e05d30d0467Eric Laurent 909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource, 910f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 9115082dbeb19e37883230510129c94336063a4f91cGlenn Kasten audio_format_t format, 9122c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten audio_channel_mask_t channelMask, 913f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::audio_in_acoustics acoustics) 914f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 915f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t input = 0; 916f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device = getDeviceForInputSource(inputSource); 917f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 91870c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x", 91970c236c9290732782d5267935af1475b8d5ae602Eric Laurent inputSource, samplingRate, format, channelMask, acoustics); 920f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 921ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 9225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW("getInput() could not find device for inputSource %d", inputSource); 923f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 924f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 925f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 926f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // adapt channel selection to input source 927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(inputSource) { 928f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 9292c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK; 930f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 931f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 9322c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK; 933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 9352c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK; 936f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 937f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 938f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 939f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 940f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 9415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = getInputProfile(device, 9425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent samplingRate, 9435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent format, 94470c236c9290732782d5267935af1475b8d5ae602Eric Laurent channelMask); 9455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (profile == NULL) { 946fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGW("getInput() could not find profile for device 0x%X, samplingRate %d, format %d, " 947fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean "channelMask 0x%X", 94870c236c9290732782d5267935af1475b8d5ae602Eric Laurent device, samplingRate, format, channelMask); 94970c236c9290732782d5267935af1475b8d5ae602Eric Laurent return 0; 95070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 95170c236c9290732782d5267935af1475b8d5ae602Eric Laurent 95270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (profile->mModule->mHandle == 0) { 9533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); 9545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 9555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 9565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 9575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile); 958f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 959f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mInputSource = inputSource; 960f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = device; 961f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mSamplingRate = samplingRate; 9622d749b0bda4ae60ef1a940eeba86121b2e94d07dGlenn Kasten inputDesc->mFormat = format; 9632c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten inputDesc->mChannelMask = channelMask; 964f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 965fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 96670c236c9290732782d5267935af1475b8d5ae602Eric Laurent input = mpClientInterface->openInput(profile->mModule->mHandle, 96770c236c9290732782d5267935af1475b8d5ae602Eric Laurent &inputDesc->mDevice, 968f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mSamplingRate, 969f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mFormat, 97070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &inputDesc->mChannelMask); 971f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 972f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // only accept input with the exact requested set of parameters 973f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input == 0 || 974f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != inputDesc->mSamplingRate) || 975f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != inputDesc->mFormat) || 97670c236c9290732782d5267935af1475b8d5ae602Eric Laurent (channelMask != inputDesc->mChannelMask)) { 977fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGI("getInput() failed opening input: samplingRate %d, format %d, channelMask 0x%X", 97870c236c9290732782d5267935af1475b8d5ae602Eric Laurent samplingRate, format, channelMask); 979f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input != 0) { 980f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 981f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 982f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete inputDesc; 983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 985fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean addInput(input, inputDesc); 986fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 987f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return input; 988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 989f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 990f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startInput(audio_io_handle_t input) 991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 9926a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startInput() input %d", input); 993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 994f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 9956742b021061741c309d6e45c074b45a560f11086Glenn Kasten ALOGW("startInput() unknown input %d", input); 996f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 999f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1000f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1001f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestInput == 0) 1002f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1003f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1004fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent // refuse 2 active AudioRecord clients at the same time except if the active input 1005fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent // uses AUDIO_SOURCE_HOTWORD in which case it is closed. 1006fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent audio_io_handle_t activeInput = getActiveInput(); 1007fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent if (!isVirtualInputDevice(inputDesc->mDevice) && activeInput != 0) { 1008fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput); 1009fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) { 1010fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent ALOGW("startInput() preempting already started low-priority input %d", activeInput); 1011fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent stopInput(activeInput); 1012fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent releaseInput(activeInput); 1013fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent } else { 10146742b021061741c309d6e45c074b45a560f11086Glenn Kasten ALOGW("startInput() input %d failed: other input already started", input); 1015fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent return INVALID_OPERATION; 1016fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent } 1017f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1018f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1019f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 102066707435156d8d99d795271a7bd54943065b4c2dEric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 102166707435156d8d99d795271a7bd54943065b4c2dEric Laurent if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { 102266707435156d8d99d795271a7bd54943065b4c2dEric Laurent inputDesc->mDevice = newDevice; 102366707435156d8d99d795271a7bd54943065b4c2dEric Laurent } 1024b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown 1025b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown // automatically enable the remote submix output when input is started 1026b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1027b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 1028b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown AudioSystem::DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 1029b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown } 1030b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown 1031f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 1032f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice); 1033f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1034fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent int aliasSource = (inputDesc->mInputSource == AUDIO_SOURCE_HOTWORD) ? 1035fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent AUDIO_SOURCE_VOICE_RECOGNITION : inputDesc->mInputSource; 1036fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent 1037fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent param.addInt(String8(AudioParameter::keyInputSource), aliasSource); 10386a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 1039f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1040f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 1041f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1042f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 1; 1043f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1044f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1045f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1046f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopInput(audio_io_handle_t input) 1047f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 10486a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopInput() input %d", input); 1049f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 1050f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 10516742b021061741c309d6e45c074b45a560f11086Glenn Kasten ALOGW("stopInput() unknown input %d", input); 1052f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 1053f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1054f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 1055f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1056f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (inputDesc->mRefCount == 0) { 105764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() input %d already stopped", input); 1058f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1059f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1060b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown // automatically disable the remote submix output when input is stopped 1061b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1062b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 1063b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown AudioSystem::DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 1064b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown } 1065b96b2839f464f93e30d256124034ec985f8a9702Jeff Brown 1066f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 1067f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), 0); 1068f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 1069f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 1070f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1071f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1072f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1073f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1074f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseInput(audio_io_handle_t input) 1075f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 10766a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() %d", input); 1077f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 1078f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 107964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseInput() releasing unknown input %d", input); 1080f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 1081f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1082f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 1083f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(index); 1084f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.removeItem(input); 1085fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 10866a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() exit"); 1087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1088f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1089fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLeanvoid AudioPolicyManagerBase::closeAllInputs() { 1090fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for(size_t input_index = 0; input_index < mInputs.size(); input_index++) { 1091fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mpClientInterface->closeInput(mInputs.keyAt(input_index)); 1092fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 1093fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mInputs.clear(); 1094fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean} 1095fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 1096f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream, 1097f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMin, 1098f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMax) 1099f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 11006a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 1101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (indexMin < 0 || indexMin >= indexMax) { 110264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 1103f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 1104f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1105f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMin = indexMin; 1106f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMax = indexMax; 1107f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1108f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1109c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, 1110c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 1111c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 1112f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1113f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1114f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 1115f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 1116f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1117c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 1118c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 1119c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1120f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1121f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force max volume if stream cannot be muted 1122f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 1123f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1124b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", 1125c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent stream, device, index); 1126c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 1127c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 1128c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // clear all device specific values 1129c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1130c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.clear(); 1131c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1132c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 1133f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1134f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // compute and apply stream volume on all outputs according to connected device 1135f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin status_t status = NO_ERROR; 1136f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1137c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent audio_devices_t curDevice = 1138c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi getDeviceForVolume(mOutputs.valueAt(i)->device()); 1139e92d623811f3fd3e7cc5e5dd8bc93c0c0a8fdf50Eric Laurent if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) { 1140c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); 1141c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent if (volStatus != NO_ERROR) { 1142c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status = volStatus; 1143c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent } 1144f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return status; 1147f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1148f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1149c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, 1150c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int *index, 1151c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 1152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1153c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (index == NULL) { 1154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 1155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1156c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 1157c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 1158c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1159c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 1160c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // the strategy the stream belongs to. 1161c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1162c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); 1163c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 1164c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = getDeviceForVolume(device); 1165c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 1166c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 1167c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 1168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 117145c763947b657b347211dc9388754e05d30d0467Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::selectOutputForEffects( 117245c763947b657b347211dc9388754e05d30d0467Eric Laurent const SortedVector<audio_io_handle_t>& outputs) 117345c763947b657b347211dc9388754e05d30d0467Eric Laurent{ 117445c763947b657b347211dc9388754e05d30d0467Eric Laurent // select one output among several suitable for global effects. 117545c763947b657b347211dc9388754e05d30d0467Eric Laurent // The priority is as follows: 117645c763947b657b347211dc9388754e05d30d0467Eric Laurent // 1: An offloaded output. If the effect ends up not being offloadable, 117745c763947b657b347211dc9388754e05d30d0467Eric Laurent // AudioFlinger will invalidate the track and the offloaded output 117845c763947b657b347211dc9388754e05d30d0467Eric Laurent // will be closed causing the effect to be moved to a PCM output. 117945c763947b657b347211dc9388754e05d30d0467Eric Laurent // 2: A deep buffer output 118045c763947b657b347211dc9388754e05d30d0467Eric Laurent // 3: the first output in the list 118145c763947b657b347211dc9388754e05d30d0467Eric Laurent 118245c763947b657b347211dc9388754e05d30d0467Eric Laurent if (outputs.size() == 0) { 118345c763947b657b347211dc9388754e05d30d0467Eric Laurent return 0; 118445c763947b657b347211dc9388754e05d30d0467Eric Laurent } 118545c763947b657b347211dc9388754e05d30d0467Eric Laurent 118645c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t outputOffloaded = 0; 118745c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t outputDeepBuffer = 0; 118845c763947b657b347211dc9388754e05d30d0467Eric Laurent 118945c763947b657b347211dc9388754e05d30d0467Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 119045c763947b657b347211dc9388754e05d30d0467Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]); 1191c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags); 119245c763947b657b347211dc9388754e05d30d0467Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 119345c763947b657b347211dc9388754e05d30d0467Eric Laurent outputOffloaded = outputs[i]; 119445c763947b657b347211dc9388754e05d30d0467Eric Laurent } 119545c763947b657b347211dc9388754e05d30d0467Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) { 119645c763947b657b347211dc9388754e05d30d0467Eric Laurent outputDeepBuffer = outputs[i]; 119745c763947b657b347211dc9388754e05d30d0467Eric Laurent } 119845c763947b657b347211dc9388754e05d30d0467Eric Laurent } 119945c763947b657b347211dc9388754e05d30d0467Eric Laurent 120045c763947b657b347211dc9388754e05d30d0467Eric Laurent ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d", 120145c763947b657b347211dc9388754e05d30d0467Eric Laurent outputOffloaded, outputDeepBuffer); 120245c763947b657b347211dc9388754e05d30d0467Eric Laurent if (outputOffloaded != 0) { 120345c763947b657b347211dc9388754e05d30d0467Eric Laurent return outputOffloaded; 120445c763947b657b347211dc9388754e05d30d0467Eric Laurent } 120545c763947b657b347211dc9388754e05d30d0467Eric Laurent if (outputDeepBuffer != 0) { 120645c763947b657b347211dc9388754e05d30d0467Eric Laurent return outputDeepBuffer; 120745c763947b657b347211dc9388754e05d30d0467Eric Laurent } 120845c763947b657b347211dc9388754e05d30d0467Eric Laurent 120945c763947b657b347211dc9388754e05d30d0467Eric Laurent return outputs[0]; 121045c763947b657b347211dc9388754e05d30d0467Eric Laurent} 121145c763947b657b347211dc9388754e05d30d0467Eric Laurent 1212c94dccc97cc3ed5171b45f46a0f7f8762d37156fGlenn Kastenaudio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(const effect_descriptor_t *desc) 1213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // apply simple rule where global effects are attached to the same output as MUSIC streams 12154660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen 12164660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen routing_strategy strategy = getStrategy(AudioSystem::MUSIC); 12174660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 1218c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs); 121945c763947b657b347211dc9388754e05d30d0467Eric Laurent 122045c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t output = selectOutputForEffects(dstOutputs); 122145c763947b657b347211dc9388754e05d30d0467Eric Laurent ALOGV("getOutputForEffect() got output %d for fx %s flags %x", 122245c763947b657b347211dc9388754e05d30d0467Eric Laurent output, (desc == NULL) ? "unspecified" : desc->name, (desc == NULL) ? 0 : desc->flags); 122345c763947b657b347211dc9388754e05d30d0467Eric Laurent 122445c763947b657b347211dc9388754e05d30d0467Eric Laurent return output; 1225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1227c94dccc97cc3ed5171b45f46a0f7f8762d37156fGlenn Kastenstatus_t AudioPolicyManagerBase::registerEffect(const effect_descriptor_t *desc, 12281c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent audio_io_handle_t io, 1229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t strategy, 12306a36ec43e62e07921da08456d2b309edabb03a0cGlenn Kasten audio_session_t session, 1231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int id) 1232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 12331c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 1234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 12351c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent index = mInputs.indexOfKey(io); 12361c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent if (index < 0) { 123764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() unknown io %d", io); 12381c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent return INVALID_OPERATION; 12391c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent } 1240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 124364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 1244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin desc->name, desc->memoryUsage); 1245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory += desc->memoryUsage; 12486a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 12491c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent desc->name, io, strategy, session, id); 12506a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 1251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = new EffectDescriptor(); 1253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t)); 12541c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent pDesc->mIo = io; 1255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mStrategy = (routing_strategy)strategy; 1256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mSession = session; 1257582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = false; 1258582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.add(id, pDesc); 1260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1262f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1263f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1264f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::unregisterEffect(int id) 1265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1266f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mEffects.indexOfKey(id); 1267f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 126864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 1269f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 1270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1271f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = mEffects.valueAt(index); 1273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1274582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent setEffectEnabled(pDesc, false); 1275582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) { 127764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() memory %d too big for total %d", 1278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage = mTotalEffectsMemory; 1280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory -= pDesc->mDesc.memoryUsage; 12826a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 1283582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1284f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.removeItem(id); 1286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete pDesc; 1287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1291582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(int id, bool enabled) 1292582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 1293582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1294582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (index < 0) { 129564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 1296582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1297582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1298582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1299582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 1300582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 1301582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1302582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(EffectDescriptor *pDesc, bool enabled) 1303582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 1304582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled == pDesc->mEnabled) { 13056a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(%s) effect already %s", 1306582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 1307582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1308582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1309582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1310582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled) { 1311582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 131264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 1313582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10); 1314582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 1315582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1316582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad; 13176a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 1318582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } else { 1319582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) { 132064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 1321582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 1322582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 1323582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1324582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad; 13256a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 1326582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 1327582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = enabled; 1328582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return NO_ERROR; 1329582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 1330582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 1331000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurentbool AudioPolicyManagerBase::isNonOffloadableEffectEnabled() 1332000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent{ 1333000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 1334000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent const EffectDescriptor * const pDesc = mEffects.valueAt(i); 1335000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent if (pDesc->mEnabled && (pDesc->mStrategy == STRATEGY_MEDIA) && 1336000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent ((pDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) { 1337000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d", 1338000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent pDesc->mDesc.name, pDesc->mSession); 1339000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent return true; 1340000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent } 1341000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent } 1342000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent return false; 1343000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent} 1344000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent 1345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const 1346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin nsecs_t sysTime = systemTime(); 1348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 134980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 135080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (outputDesc->isStreamActive((AudioSystem::stream_type)stream, inPastMs, sysTime)) { 1351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return true; 1352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1353f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1354f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1357dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivibool AudioPolicyManagerBase::isStreamActiveRemotely(int stream, uint32_t inPastMs) const 1358dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi{ 1359dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi nsecs_t sysTime = systemTime(); 1360dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi for (size_t i = 0; i < mOutputs.size(); i++) { 1361dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 136280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 136380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent outputDesc->isStreamActive((AudioSystem::stream_type)stream, inPastMs, sysTime)) { 1364dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi return true; 1365dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi } 1366dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi } 1367dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi return false; 1368dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi} 1369dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi 1370abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivibool AudioPolicyManagerBase::isSourceActive(audio_source_t source) const 1371abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi{ 1372abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi for (size_t i = 0; i < mInputs.size(); i++) { 1373abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi const AudioInputDescriptor * inputDescriptor = mInputs.valueAt(i); 1374fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent if ((inputDescriptor->mInputSource == (int)source || 1375fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent (source == (audio_source_t)AUDIO_SOURCE_VOICE_RECOGNITION && 1376fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) 1377fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent && (inputDescriptor->mRefCount > 0)) { 1378abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi return true; 1379abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi } 1380abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi } 1381abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi return false; 1382abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi} 1383abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi 1384abc55c698301e05a80d7f9394c75abca0b307602Jean-Michel Trivi 1385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::dump(int fd) 1386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 1390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 1392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1393b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 139470c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput); 1395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string()); 1397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string()); 1399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1400fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean snprintf(buffer, SIZE, " USB audio ALSA %s\n", mUsbOutCardAndDevice.string()); 1401599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent result.append(buffer); 1402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices); 1403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices); 1405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 1407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]); 1409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]); 1411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]); 1413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]); 1415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1416738207def5f691d605ae33d041116829a74513a9Eric Laurent snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AudioSystem::FOR_SYSTEM]); 1417738207def5f691d605ae33d041116829a74513a9Eric Laurent result.append(buffer); 1418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 1419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 14205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 142170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 14225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, buffer, strlen(buffer)); 142370c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 1424c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1); 14255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, buffer, strlen(buffer)); 142670c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules[i]->dump(fd); 14275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 14285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 1429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nOutputs dump:\n"); 1430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1432f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 1433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1434f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueAt(i)->dump(fd); 1435f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1436f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nInputs dump:\n"); 1438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 1441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.valueAt(i)->dump(fd); 1443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1444f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nStreams dump:\n"); 1446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1447c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, 1448c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 1449f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1450f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 1451c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross snprintf(buffer, SIZE, " %02zu ", i); 1452f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1453c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[i].dump(fd); 1454f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1455f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 1457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 1458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "Registered effects:\n"); 1461f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1462f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mEffects.size(); i++) { 1463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 1464f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1465f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.valueAt(i)->dump(fd); 1466f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1470f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1472a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald// This function checks for the parameters which can be offloaded. 1473a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald// This can be enhanced depending on the capability of the DSP and policy 1474a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald// of the system. 1475b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgeraldbool AudioPolicyManagerBase::isOffloadSupported(const audio_offload_info_t& offloadInfo) 1476b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald{ 1477a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d," 1478c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross " BitRate=%u, duration=%" PRId64 " us, has_video=%d", 1479a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.sample_rate, offloadInfo.channel_mask, 1480a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.format, 1481a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us, 1482a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.has_video); 1483a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 1484a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // Check if offload has been disabled 1485a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald char propValue[PROPERTY_VALUE_MAX]; 1486a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (property_get("audio.offload.disable", propValue, "0")) { 1487a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (atoi(propValue) != 0) { 1488a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("offload disabled by audio.offload.disable=%s", propValue ); 1489a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return false; 1490a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 1491a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 1492a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 1493a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // Check if stream type is music, then only allow offload as of now. 1494a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC) 1495a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald { 149641b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent ALOGV("isOffloadSupported: stream_type != MUSIC, returning false"); 149741b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent return false; 149841b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent } 149941b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent 150041b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent //TODO: enable audio offloading with video when ready 150141b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent if (offloadInfo.has_video) 150241b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent { 150341b150b659d4ba33a9be9f99fd9f0ee1f2787541Eric Laurent ALOGV("isOffloadSupported: has_video == true, returning false"); 1504a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return false; 1505a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 1506a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 1507a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald //If duration is less than minimum value defined in property, return false 1508a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (property_get("audio.offload.min.duration.secs", propValue, NULL)) { 1509a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) { 1510a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue); 1511a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return false; 1512a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 1513a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) { 1514a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS); 1515a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return false; 1516a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 1517a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 1518000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 1519000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 1520000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // detects there is an active non offloadable effect. 1521000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 1522000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 1523000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent // in the background. 1524000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent if (isNonOffloadableEffectEnabled()) { 1525000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent return false; 1526000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent } 1527000bb51ca507645f3aa4ccfcbbb8859e8d539629Eric Laurent 1528a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // See if there is a profile to support this. 1529a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // AUDIO_DEVICE_NONE 1530a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald IOProfile *profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */, 1531a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.sample_rate, 1532a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.format, 1533a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald offloadInfo.channel_mask, 1534a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD); 1535a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ALOGV("isOffloadSupported() profile %sfound", profile != NULL ? "" : "NOT "); 1536a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald return (profile != NULL); 1537b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald} 1538b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald 1539f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1540f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyManagerBase 1541f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface) 1544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin : 1545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Thread(false), 1547f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 154870c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput((audio_io_handle_t)0), 1549ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableOutputDevices(AUDIO_DEVICE_NONE), 1550ca0657a1ca087a6d474a75fcfedd6aac3901d587Glenn Kasten mPhoneState(AudioSystem::MODE_NORMAL), 1551f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 1552f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 155318fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi mA2dpSuspended(false), mHasA2dp(false), mHasUsb(false), mHasRemoteSubmix(false), 155418fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi mSpeakerDrcEnabled(false) 1555f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface = clientInterface; 1557f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1558f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) { 1559f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[i] = AudioSystem::FORCE_NONE; 1560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1561f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1562f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpDeviceAddress = String8(""); 1563f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mScoDeviceAddress = String8(""); 1564fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mUsbOutCardAndDevice = String8(""); 1565f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 15665ec145df7708564d385fd3fb764085321cf4c253Dima Zavin if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { 15675ec145df7708564d385fd3fb764085321cf4c253Dima Zavin if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { 1568739022f26a7127ba76a98dda65411496086114a7Dima Zavin ALOGE("could not load audio policy configuration file, setting defaults"); 1569739022f26a7127ba76a98dda65411496086114a7Dima Zavin defaultAudioPolicyConfig(); 15705ec145df7708564d385fd3fb764085321cf4c253Dima Zavin } 15715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 15725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 157318fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi // must be done after reading the policy 157418fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi initializeVolumeCurves(); 157518fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi 1576b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // open all output streams needed to access attached devices 157770c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 157870c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 157970c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 158070c236c9290732782d5267935af1475b8d5ae602Eric Laurent ALOGW("could not open HW module %s", mHwModules[i]->mName); 158170c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 158270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 158370c236c9290732782d5267935af1475b8d5ae602Eric Laurent // open all output streams needed to access attached devices 1584a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // except for direct output streams that are only opened when they are actually 1585a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // required by an app. 158670c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 158770c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 158870c236c9290732782d5267935af1475b8d5ae602Eric Laurent const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j]; 158970c236c9290732782d5267935af1475b8d5ae602Eric Laurent 1590a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if ((outProfile->mSupportedDevices & mAttachedOutputDevices) && 1591a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) { 159270c236c9290732782d5267935af1475b8d5ae602Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile); 159370c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice & 159470c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mSupportedDevices); 159570c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput( 159670c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mModule->mHandle, 159770c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 159870c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mSamplingRate, 159970c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mFormat, 160070c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 160170c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mLatency, 160270c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mFlags); 160370c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (output == 0) { 160470c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete outputDesc; 160570c236c9290732782d5267935af1475b8d5ae602Eric Laurent } else { 160670c236c9290732782d5267935af1475b8d5ae602Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | 160770c236c9290732782d5267935af1475b8d5ae602Eric Laurent (outProfile->mSupportedDevices & mAttachedOutputDevices)); 160870c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mPrimaryOutput == 0 && 16090977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 161070c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput = output; 161170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 161270c236c9290732782d5267935af1475b8d5ae602Eric Laurent addOutput(output, outputDesc); 161370c236c9290732782d5267935af1475b8d5ae602Eric Laurent setOutputDevice(output, 161470c236c9290732782d5267935af1475b8d5ae602Eric Laurent (audio_devices_t)(mDefaultOutputDevice & 161570c236c9290732782d5267935af1475b8d5ae602Eric Laurent outProfile->mSupportedDevices), 161670c236c9290732782d5267935af1475b8d5ae602Eric Laurent true); 1617b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1618b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1619b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1620f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1621f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 16225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE_IF((mAttachedOutputDevices & ~mAvailableOutputDevices), 1623b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent "Not output found for attached devices %08x", 16245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (mAttachedOutputDevices & ~mAvailableOutputDevices)); 1625b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1626b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 1627b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1628c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 16293cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 1630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1631b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput != 0) { 1632f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1633f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1634b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1635f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1636c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi mTestDevice = AUDIO_DEVICE_OUT_SPEAKER; 1637f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = 44100; 1638f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = AudioSystem::PCM_16_BIT; 1639f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = AudioSystem::CHANNEL_OUT_STEREO; 1640f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestLatencyMs = 0; 1641f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = 0; 1642f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1643f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1644f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[i] = 0; 1645f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1646f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1647f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1649f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 1650f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin run(buffer, ANDROID_PRIORITY_AUDIO); 1651f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1652f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1653f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1654f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1655f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::~AudioPolicyManagerBase() 1656f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1657f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1658f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin exit(); 1659f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1660f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(mOutputs.keyAt(i)); 1662f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(i); 1663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1665f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(mInputs.keyAt(i)); 1666f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(i); 1667f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 166870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 166970c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mHwModules[i]; 16705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 1671f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1673f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::initCheck() 1674f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1675b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; 1676f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1678f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1679f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::threadLoop() 1680f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 16816a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("entering threadLoop()"); 1682f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin while (!exitPending()) 1683f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1684f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 command; 1685f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int valueInt; 1686f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 value; 1687f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1688f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Mutex::Autolock _l(mLock); 1689f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 1690f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 1692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(command); 1693f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1694f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 1695f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin valueInt != 0) { 16966a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("Test command %s received", command.string()); 1697f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 target; 1698f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("target"), target) != NO_ERROR) { 1699f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin target = "Manager"; 1700f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1701f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 1702f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_output")); 1703f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = valueInt; 1704f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1705f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 1706f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_direct")); 1707f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "false") { 1708f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1709f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "true") { 1710f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = true; 1711f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1712f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1713f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 1714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_input")); 1715f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestInput = valueInt; 1716f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1717f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 1719f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_format")); 1720f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int format = AudioSystem::INVALID_FORMAT; 1721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "PCM 16 bits") { 1722f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_16_BIT; 1723f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "PCM 8 bits") { 1724f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_8_BIT; 1725f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Compressed MP3") { 1726f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::MP3; 1727f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1728f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (format != AudioSystem::INVALID_FORMAT) { 1729f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1730f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = format; 1731f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1732f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1733f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("format"), format); 1734f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1735f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1736f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1737f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1738f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 1739f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_channels")); 1740f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int channels = 0; 1741f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1742f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "Channels Stereo") { 1743f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_STEREO; 1744f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Channels Mono") { 1745f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_MONO; 1746f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1747f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (channels != 0) { 1748f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1749f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = channels; 1750f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1751f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1752f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("channels"), channels); 1753f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1754f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1755f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1756f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 1758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_sampleRate")); 1759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (valueInt >= 0 && valueInt <= 96000) { 1760f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int samplingRate = valueInt; 1761f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1762f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = samplingRate; 1763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1764f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("sampling_rate"), samplingRate); 1766f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1767f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1768f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1769f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1770f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 1772f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_reopen")); 1773f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 177470c236c9290732782d5267935af1475b8d5ae602Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 1775b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(mPrimaryOutput); 177670c236c9290732782d5267935af1475b8d5ae602Eric Laurent 177770c236c9290732782d5267935af1475b8d5ae602Eric Laurent audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; 177870c236c9290732782d5267935af1475b8d5ae602Eric Laurent 1779b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(mPrimaryOutput); 1780b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(mPrimaryOutput); 1781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1782b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 1783c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; 178470c236c9290732782d5267935af1475b8d5ae602Eric Laurent mPrimaryOutput = mpClientInterface->openOutput(moduleHandle, 178570c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mDevice, 1786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 1787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 178870c236c9290732782d5267935af1475b8d5ae602Eric Laurent &outputDesc->mChannelMask, 1789f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 1790f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 1791b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput == 0) { 17925efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d", 179370c236c9290732782d5267935af1475b8d5ae602Eric Laurent outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); 1794f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1795f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1796f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1797b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1798b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent addOutput(mPrimaryOutput, outputDesc); 1799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1800f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1801f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1802f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1803f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 1804f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1805f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1806f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1807f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1808f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1809f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::exit() 1810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1811f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1812f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AutoMutex _l(mLock); 1813f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExit(); 1814f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.signal(); 1815f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1816f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExitAndWait(); 1817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1819f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinint AudioPolicyManagerBase::testOutputIndex(audio_io_handle_t output) 1820f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1821f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1822f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == mTestOutputs[i]) return i; 1823f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1824f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 1825f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1826f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1827f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1828f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- 1829f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1830f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc) 1831f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1832f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mId = id; 1833f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.add(id, outputDesc); 1834f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1835f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1836fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLeanvoid AudioPolicyManagerBase::addInput(audio_io_handle_t id, AudioInputDescriptor *inputDesc) 1837fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean{ 1838fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean inputDesc->mId = id; 1839fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mInputs.add(id, inputDesc); 1840fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean} 1841f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 18423cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurentstatus_t AudioPolicyManagerBase::checkOutputsForDevice(audio_devices_t device, 18433cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioSystem::device_connection_state state, 18449f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent SortedVector<audio_io_handle_t>& outputs, 18459f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent const String8 paramStr) 1846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 18473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent AudioOutputDescriptor *desc; 1848b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1849b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (state == AudioSystem::DEVICE_STATE_AVAILABLE) { 18503cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // first list already open outputs that can be routed to this device 1851b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 18523cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(i); 18533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices & device)) { 18543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i)); 18553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(mOutputs.keyAt(i)); 1856b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1857b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 18583cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // then look for output profiles that can be routed to this device 18593cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent SortedVector<IOProfile *> profiles; 186070c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 1861b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent { 186270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 186370c236c9290732782d5267935af1475b8d5ae602Eric Laurent continue; 186470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 186570c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 186670c236c9290732782d5267935af1475b8d5ae602Eric Laurent { 186770c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices & device) { 1868c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i); 18693cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profiles.add(mHwModules[i]->mOutputProfiles[j]); 187070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 187170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 1872b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 187370c236c9290732782d5267935af1475b8d5ae602Eric Laurent 18743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profiles.isEmpty() && outputs.isEmpty()) { 18753cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 18763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return BAD_VALUE; 187770c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 187870c236c9290732782d5267935af1475b8d5ae602Eric Laurent 18793cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // open outputs for matching profiles if needed. Direct outputs are also opened to 18803cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 18813cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 18823cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = profiles[profile_index]; 1883b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 18843cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // nothing to do if one output is already opened for this profile 18853cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent size_t j; 1886fd8cecbee6843b444d56a1db40af76027e2b19f1Eric Laurent for (j = 0; j < mOutputs.size(); j++) { 18873cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(j); 18883cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && desc->mProfile == profile) { 18893cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent break; 18903cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18913cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1892fd8cecbee6843b444d56a1db40af76027e2b19f1Eric Laurent if (j != mOutputs.size()) { 18933cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent continue; 18943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 18953cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 18969f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent ALOGV("opening output for device %08x with params %s", device, paramStr.string()); 18973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = new AudioOutputDescriptor(profile); 18983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc->mDevice = device; 1899727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; 1900727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent offloadInfo.sample_rate = desc->mSamplingRate; 1901727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent offloadInfo.format = desc->mFormat; 1902727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent offloadInfo.channel_mask = desc->mChannelMask; 1903727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent 19043cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle, 19053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mDevice, 19063cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mSamplingRate, 19073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mFormat, 19083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mChannelMask, 19093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent &desc->mLatency, 1910727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent desc->mFlags, 1911727fef1b1a8cb6d6609ec99a749fcd9573a3417dEric Laurent &offloadInfo); 19123cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (output != 0) { 19139f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent if (!paramStr.isEmpty()) { 1914fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // Here is where the out_set_parameters() for card & device gets called 19159f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent mpClientInterface->setParameters(output, paramStr); 19169f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent } 19179f4165f36d90dddc32246d0eddbf289383c3b2bbEric Laurent 1918fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // Here is where we step through and resolve any "dynamic" fields 1919c26f454f8d841657542916cdd140a9896a89ad20Paul McLean String8 reply; 1920c26f454f8d841657542916cdd140a9896a89ad20Paul McLean char *value; 1921c26f454f8d841657542916cdd140a9896a89ad20Paul McLean if (profile->mSamplingRates[0] == 0) { 1922c26f454f8d841657542916cdd140a9896a89ad20Paul McLean reply = mpClientInterface->getParameters(output, 1923c26f454f8d841657542916cdd140a9896a89ad20Paul McLean String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 1924c26f454f8d841657542916cdd140a9896a89ad20Paul McLean ALOGV("checkOutputsForDevice() direct output sup sampling rates %s", 1925c26f454f8d841657542916cdd140a9896a89ad20Paul McLean reply.string()); 1926c26f454f8d841657542916cdd140a9896a89ad20Paul McLean value = strpbrk((char *)reply.string(), "="); 1927c26f454f8d841657542916cdd140a9896a89ad20Paul McLean if (value != NULL) { 1928c26f454f8d841657542916cdd140a9896a89ad20Paul McLean loadSamplingRates(value + 1, profile); 19293cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1930c26f454f8d841657542916cdd140a9896a89ad20Paul McLean } 1931c26f454f8d841657542916cdd140a9896a89ad20Paul McLean if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 1932c26f454f8d841657542916cdd140a9896a89ad20Paul McLean reply = mpClientInterface->getParameters(output, 1933c26f454f8d841657542916cdd140a9896a89ad20Paul McLean String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 1934c26f454f8d841657542916cdd140a9896a89ad20Paul McLean ALOGV("checkOutputsForDevice() direct output sup formats %s", 1935c26f454f8d841657542916cdd140a9896a89ad20Paul McLean reply.string()); 1936c26f454f8d841657542916cdd140a9896a89ad20Paul McLean value = strpbrk((char *)reply.string(), "="); 1937c26f454f8d841657542916cdd140a9896a89ad20Paul McLean if (value != NULL) { 1938c26f454f8d841657542916cdd140a9896a89ad20Paul McLean loadFormats(value + 1, profile); 19393cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1940c26f454f8d841657542916cdd140a9896a89ad20Paul McLean } 1941c26f454f8d841657542916cdd140a9896a89ad20Paul McLean if (profile->mChannelMasks[0] == 0) { 1942c26f454f8d841657542916cdd140a9896a89ad20Paul McLean reply = mpClientInterface->getParameters(output, 1943c26f454f8d841657542916cdd140a9896a89ad20Paul McLean String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 1944c26f454f8d841657542916cdd140a9896a89ad20Paul McLean ALOGV("checkOutputsForDevice() direct output sup channel masks %s", 1945c26f454f8d841657542916cdd140a9896a89ad20Paul McLean reply.string()); 1946c26f454f8d841657542916cdd140a9896a89ad20Paul McLean value = strpbrk((char *)reply.string(), "="); 1947c26f454f8d841657542916cdd140a9896a89ad20Paul McLean if (value != NULL) { 1948c26f454f8d841657542916cdd140a9896a89ad20Paul McLean loadOutChannels(value + 1, profile); 19493cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 1950c26f454f8d841657542916cdd140a9896a89ad20Paul McLean } 1951c26f454f8d841657542916cdd140a9896a89ad20Paul McLean if (((profile->mSamplingRates[0] == 0) && 1952c26f454f8d841657542916cdd140a9896a89ad20Paul McLean (profile->mSamplingRates.size() < 2)) || 1953c26f454f8d841657542916cdd140a9896a89ad20Paul McLean ((profile->mFormats[0] == 0) && 1954c26f454f8d841657542916cdd140a9896a89ad20Paul McLean (profile->mFormats.size() < 2)) || 1955c26f454f8d841657542916cdd140a9896a89ad20Paul McLean ((profile->mChannelMasks[0] == 0) && 1956c26f454f8d841657542916cdd140a9896a89ad20Paul McLean (profile->mChannelMasks.size() < 2))) { 1957c26f454f8d841657542916cdd140a9896a89ad20Paul McLean ALOGW("checkOutputsForDevice() direct output missing param"); 1958c26f454f8d841657542916cdd140a9896a89ad20Paul McLean mpClientInterface->closeOutput(output); 1959c26f454f8d841657542916cdd140a9896a89ad20Paul McLean output = 0; 1960c26f454f8d841657542916cdd140a9896a89ad20Paul McLean } else if (profile->mSamplingRates[0] == 0) { 1961c26f454f8d841657542916cdd140a9896a89ad20Paul McLean mpClientInterface->closeOutput(output); 1962c26f454f8d841657542916cdd140a9896a89ad20Paul McLean desc->mSamplingRate = profile->mSamplingRates[1]; 1963c26f454f8d841657542916cdd140a9896a89ad20Paul McLean offloadInfo.sample_rate = desc->mSamplingRate; 1964c26f454f8d841657542916cdd140a9896a89ad20Paul McLean output = mpClientInterface->openOutput( 1965c26f454f8d841657542916cdd140a9896a89ad20Paul McLean profile->mModule->mHandle, 1966c26f454f8d841657542916cdd140a9896a89ad20Paul McLean &desc->mDevice, 1967c26f454f8d841657542916cdd140a9896a89ad20Paul McLean &desc->mSamplingRate, 1968c26f454f8d841657542916cdd140a9896a89ad20Paul McLean &desc->mFormat, 1969c26f454f8d841657542916cdd140a9896a89ad20Paul McLean &desc->mChannelMask, 1970c26f454f8d841657542916cdd140a9896a89ad20Paul McLean &desc->mLatency, 1971c26f454f8d841657542916cdd140a9896a89ad20Paul McLean desc->mFlags, 1972c26f454f8d841657542916cdd140a9896a89ad20Paul McLean &offloadInfo); 1973c26f454f8d841657542916cdd140a9896a89ad20Paul McLean } 1974c26f454f8d841657542916cdd140a9896a89ad20Paul McLean 1975c26f454f8d841657542916cdd140a9896a89ad20Paul McLean if (output != 0) { 19763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent addOutput(output, desc); 1977c26f454f8d841657542916cdd140a9896a89ad20Paul McLean if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { 1978c26f454f8d841657542916cdd140a9896a89ad20Paul McLean audio_io_handle_t duplicatedOutput = 0; 1979c26f454f8d841657542916cdd140a9896a89ad20Paul McLean 1980c26f454f8d841657542916cdd140a9896a89ad20Paul McLean // set initial stream volume for device 1981c26f454f8d841657542916cdd140a9896a89ad20Paul McLean applyStreamVolumes(output, device, 0, true); 1982c26f454f8d841657542916cdd140a9896a89ad20Paul McLean 1983c26f454f8d841657542916cdd140a9896a89ad20Paul McLean //TODO: configure audio effect output stage here 1984c26f454f8d841657542916cdd140a9896a89ad20Paul McLean 1985c26f454f8d841657542916cdd140a9896a89ad20Paul McLean // open a duplicating output thread for the new output and the primary output 1986c26f454f8d841657542916cdd140a9896a89ad20Paul McLean duplicatedOutput = mpClientInterface->openDuplicateOutput(output, 1987c26f454f8d841657542916cdd140a9896a89ad20Paul McLean mPrimaryOutput); 1988c26f454f8d841657542916cdd140a9896a89ad20Paul McLean if (duplicatedOutput != 0) { 1989c26f454f8d841657542916cdd140a9896a89ad20Paul McLean // add duplicated output descriptor 1990c26f454f8d841657542916cdd140a9896a89ad20Paul McLean AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL); 1991c26f454f8d841657542916cdd140a9896a89ad20Paul McLean dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); 1992c26f454f8d841657542916cdd140a9896a89ad20Paul McLean dupOutputDesc->mOutput2 = mOutputs.valueFor(output); 1993c26f454f8d841657542916cdd140a9896a89ad20Paul McLean dupOutputDesc->mSamplingRate = desc->mSamplingRate; 1994c26f454f8d841657542916cdd140a9896a89ad20Paul McLean dupOutputDesc->mFormat = desc->mFormat; 1995c26f454f8d841657542916cdd140a9896a89ad20Paul McLean dupOutputDesc->mChannelMask = desc->mChannelMask; 1996c26f454f8d841657542916cdd140a9896a89ad20Paul McLean dupOutputDesc->mLatency = desc->mLatency; 1997c26f454f8d841657542916cdd140a9896a89ad20Paul McLean addOutput(duplicatedOutput, dupOutputDesc); 1998c26f454f8d841657542916cdd140a9896a89ad20Paul McLean applyStreamVolumes(duplicatedOutput, device, 0, true); 1999c26f454f8d841657542916cdd140a9896a89ad20Paul McLean } else { 2000c26f454f8d841657542916cdd140a9896a89ad20Paul McLean ALOGW("checkOutputsForDevice() could not open dup output for %d and %d", 2001c26f454f8d841657542916cdd140a9896a89ad20Paul McLean mPrimaryOutput, output); 2002c26f454f8d841657542916cdd140a9896a89ad20Paul McLean mpClientInterface->closeOutput(output); 2003c26f454f8d841657542916cdd140a9896a89ad20Paul McLean mOutputs.removeItem(output); 2004c26f454f8d841657542916cdd140a9896a89ad20Paul McLean output = 0; 2005c26f454f8d841657542916cdd140a9896a89ad20Paul McLean } 20063cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 20073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 20083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 20093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (output == 0) { 20103cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice() could not open output for device %x", device); 20113cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent delete desc; 20123cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profiles.removeAt(profile_index); 20133cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile_index--; 2014b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 20153cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(output); 20163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): adding output %d", output); 2017f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 20183cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 20193cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 20203cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profiles.isEmpty()) { 20213cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 20223cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return BAD_VALUE; 2023f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2024fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } else { // Disconnect 2025b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // check if one opened output is not needed any more after disconnecting one device 2026b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 20273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent desc = mOutputs.valueAt(i); 20283cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (!desc->isDuplicated() && 20293cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent !(desc->mProfile->mSupportedDevices & mAvailableOutputDevices)) { 20303cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i)); 20313cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent outputs.add(mOutputs.keyAt(i)); 20323cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 20333cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 2034fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // Clear any profiles associated with the disconnected device. 20353cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 20363cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent { 20373cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (mHwModules[i]->mHandle == 0) { 20383cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent continue; 20393cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 20403cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 20413cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent { 20423cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; 2043c26f454f8d841657542916cdd140a9896a89ad20Paul McLean if (profile->mSupportedDevices & device) { 2044c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross ALOGV("checkOutputsForDevice(): clearing direct output profile %zu on module %zu", 20453cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent j, i); 20463cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mSamplingRates[0] == 0) { 20473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.clear(); 20483cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.add(0); 20493cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 20502d749b0bda4ae60ef1a940eeba86121b2e94d07dGlenn Kasten if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 20513cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mFormats.clear(); 20522d749b0bda4ae60ef1a940eeba86121b2e94d07dGlenn Kasten profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 20533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 20543cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile->mChannelMasks[0] == 0) { 20553cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mChannelMasks.clear(); 20562c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten profile->mChannelMasks.add(0); 20573cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 20583cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 2059b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2060f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2061f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 20623cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return NO_ERROR; 2063f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2064f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2065fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLeanstatus_t AudioPolicyManagerBase::checkInputsForDevice(audio_devices_t device, 2066fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean AudioSystem::device_connection_state state, 2067fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean SortedVector<audio_io_handle_t>& inputs, 2068fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean const String8 paramStr) 2069fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean{ 2070fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean AudioInputDescriptor *desc; 2071fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (state == AudioSystem::DEVICE_STATE_AVAILABLE) { 2072fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // first list already open inputs that can be routed to this device 2073fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 2074fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean desc = mInputs.valueAt(input_index); 2075fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (desc->mProfile->mSupportedDevices & (device & ~AUDIO_DEVICE_BIT_IN)) { 2076fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index)); 2077fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean inputs.add(mInputs.keyAt(input_index)); 2078fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2079fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2080fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2081fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // then look for input profiles that can be routed to this device 2082fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean SortedVector<IOProfile *> profiles; 2083fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) 2084fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean { 2085fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (mHwModules[module_index]->mHandle == 0) { 2086fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean continue; 2087fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2088fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for (size_t profile_index = 0; 2089fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile_index < mHwModules[module_index]->mInputProfiles.size(); 2090fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile_index++) 2091fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean { 2092fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (mHwModules[module_index]->mInputProfiles[profile_index]->mSupportedDevices 2093fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean & (device & ~AUDIO_DEVICE_BIT_IN)) { 2094f2d9ad053ae3a1b3650bb51c8940be9c9aab3dc0Dan Albert ALOGV("checkInputsForDevice(): adding profile %zu from module %zu", 2095fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile_index, module_index); 2096fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profiles.add(mHwModules[module_index]->mInputProfiles[profile_index]); 2097fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2098fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2099fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2100fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2101fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (profiles.isEmpty() && inputs.isEmpty()) { 2102fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 2103fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean return BAD_VALUE; 2104fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2105fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2106fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // open inputs for matching profiles if needed. Direct inputs are also opened to 2107fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // query for dynamic parameters and will be closed later by setDeviceConnectionState() 2108fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 2109fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2110fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean IOProfile *profile = profiles[profile_index]; 2111fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // nothing to do if one input is already opened for this profile 2112fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean size_t input_index; 2113fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for (input_index = 0; input_index < mInputs.size(); input_index++) { 2114fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean desc = mInputs.valueAt(input_index); 2115fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (desc->mProfile == profile) { 2116fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean break; 2117fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2118fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2119fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (input_index != mInputs.size()) { 2120fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean continue; 2121fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2122fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2123fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV("opening input for device 0x%X with params %s", device, paramStr.string()); 2124fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean desc = new AudioInputDescriptor(profile); 2125fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean desc->mDevice = device; 2126fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2127fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle, 2128fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean &desc->mDevice, 2129fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean &desc->mSamplingRate, 2130fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean &desc->mFormat, 2131fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean &desc->mChannelMask); 2132fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2133fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (input != 0) { 2134fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (!paramStr.isEmpty()) { 2135fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mpClientInterface->setParameters(input, paramStr); 2136fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2137fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2138fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // Here is where we step through and resolve any "dynamic" fields 2139fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean String8 reply; 2140fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean char *value; 2141fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (profile->mSamplingRates[0] == 0) { 2142fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean reply = mpClientInterface->getParameters(input, 2143fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 2144fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV("checkInputsForDevice() direct input sup sampling rates %s", 2145fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean reply.string()); 2146fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean value = strpbrk((char *)reply.string(), "="); 2147fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (value != NULL) { 2148fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean loadSamplingRates(value + 1, profile); 2149fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2150fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2151fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2152fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean reply = mpClientInterface->getParameters(input, 2153fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 2154fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string()); 2155fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean value = strpbrk((char *)reply.string(), "="); 2156fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (value != NULL) { 2157fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean loadFormats(value + 1, profile); 2158fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2159fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2160fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (profile->mChannelMasks[0] == 0) { 2161fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean reply = mpClientInterface->getParameters(input, 2162fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 2163fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV("checkInputsForDevice() direct input sup channel masks %s", 2164fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean reply.string()); 2165fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean value = strpbrk((char *)reply.string(), "="); 2166fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (value != NULL) { 2167fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean loadInChannels(value + 1, profile); 2168fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2169fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2170fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) || 2171fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) || 2172fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) { 2173fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGW("checkInputsForDevice() direct input missing param"); 2174fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mpClientInterface->closeInput(input); 2175fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean input = 0; 2176fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2177fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2178fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (input != 0) { 2179fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean addInput(input, desc); 2180fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2181fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } // endif input != 0 2182fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2183fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (input == 0) { 2184fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGW("checkInputsForDevice() could not open input for device 0x%X", device); 2185fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean delete desc; 2186fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profiles.removeAt(profile_index); 2187fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile_index--; 2188fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } else { 2189fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean inputs.add(input); 2190fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV("checkInputsForDevice(): adding input %d", input); 2191fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2192fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } // end scan profiles 2193fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2194fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (profiles.isEmpty()) { 2195fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 2196fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean return BAD_VALUE; 2197fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2198fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } else { 2199fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // Disconnect 2200fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // check if one opened input is not needed any more after disconnecting one device 2201fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 2202fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean desc = mInputs.valueAt(input_index); 2203fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (!(desc->mProfile->mSupportedDevices & mAvailableInputDevices)) { 2204fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV("checkInputsForDevice(): disconnecting adding input %d", 2205fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mInputs.keyAt(input_index)); 2206fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean inputs.add(mInputs.keyAt(input_index)); 2207fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2208fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2209fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // Clear any profiles associated with the disconnected device. 2210fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) 2211fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean { 2212fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (mHwModules[module_index]->mHandle == 0) { 2213fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean continue; 2214fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2215fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for (size_t profile_index = 0; 2216fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile_index < mHwModules[module_index]->mInputProfiles.size(); 2217fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile_index++) 2218fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean { 2219fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean IOProfile *profile = mHwModules[module_index]->mInputProfiles[profile_index]; 2220fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (profile->mSupportedDevices & device) { 2221f2d9ad053ae3a1b3650bb51c8940be9c9aab3dc0Dan Albert ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu", 2222fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile_index, module_index); 2223fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (profile->mSamplingRates[0] == 0) { 2224fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile->mSamplingRates.clear(); 2225fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile->mSamplingRates.add(0); 2226fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2227fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2228fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile->mFormats.clear(); 2229fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 2230fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2231fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (profile->mChannelMasks[0] == 0) { 2232fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile->mChannelMasks.clear(); 2233fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean profile->mChannelMasks.add(0); 2234fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2235fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2236fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2237fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 2238fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } // end disconnect 2239fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2240fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean return NO_ERROR; 2241fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean} 2242fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 2243b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::closeOutput(audio_io_handle_t output) 2244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2245b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput(%d)", output); 2246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2247b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2248b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputDesc == NULL) { 2249b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGW("closeOutput() unknown output %d", output); 2250b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 2251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2253b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // look for duplicated outputs connected to the output being removed. 2254b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2255b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i); 2256b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->isDuplicated() && 2257b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (dupOutputDesc->mOutput1 == outputDesc || 2258b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent dupOutputDesc->mOutput2 == outputDesc)) { 2259b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc2; 2260b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->mOutput1 == outputDesc) { 2261b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput2; 2262b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 2263b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput1; 2264b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2265b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // As all active tracks on duplicated output will be deleted, 2266b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // and as they were also referenced on the other output, the reference 2267b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // count for their stream type must be adjusted accordingly on 2268b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // the other output. 2269b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (int j = 0; j < (int)AudioSystem::NUM_STREAM_TYPES; j++) { 2270b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent int refCount = dupOutputDesc->mRefCount[j]; 2271b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2->changeRefCount((AudioSystem::stream_type)j,-refCount); 2272b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2273b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i); 2274b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); 2275f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2276b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(duplicatedOutput); 2277b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(duplicatedOutput); 2278b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(duplicatedOutput); 2279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2281b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2282b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioParameter param; 2283b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent param.add(String8("closing"), String8("true")); 2284b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(output, param.toString()); 2285b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2286b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(output); 22875a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent delete outputDesc; 2288b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(output); 22895a950c960cd40648cc3ab8defe817f88e0a7ecf4Eric Laurent mPreviousOutputs = mOutputs; 2290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2292c952527e6f89d5427881462823514be9d79f13e6Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManagerBase::getOutputsForDevice(audio_devices_t device, 2293c952527e6f89d5427881462823514be9d79f13e6Eric Laurent DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs) 2294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2295b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t> outputs; 2296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 22973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getOutputsForDevice() device %04x", device); 2298c952527e6f89d5427881462823514be9d79f13e6Eric Laurent for (size_t i = 0; i < openOutputs.size(); i++) { 22993cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("output %d isDuplicated=%d device=%04x", 2300c952527e6f89d5427881462823514be9d79f13e6Eric Laurent i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices()); 2301c952527e6f89d5427881462823514be9d79f13e6Eric Laurent if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) { 2302c952527e6f89d5427881462823514be9d79f13e6Eric Laurent ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i)); 2303c952527e6f89d5427881462823514be9d79f13e6Eric Laurent outputs.add(openOutputs.keyAt(i)); 2304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2306b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return outputs; 2307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2309b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentbool AudioPolicyManagerBase::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, 2310b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t>& outputs2) 2311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2312b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1.size() != outputs2.size()) { 2313b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 2314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2315b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < outputs1.size(); i++) { 2316b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1[i] != outputs2[i]) { 2317b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 2318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2320b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return true; 2321b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 2322b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2323b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy) 2324b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 232501e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); 232601e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); 2327c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs); 2328c952527e6f89d5427881462823514be9d79f13e6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); 2329b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2330b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!vectorsEqual(srcOutputs,dstOutputs)) { 2331b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", 2332b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent strategy, srcOutputs[0], dstOutputs[0]); 23335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // mute strategy while moving tracks from one output to another 23345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < srcOutputs.size(); i++) { 2335fa3697d716b444bbea6be480801536c44bf69214Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]); 233680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (desc->isStrategyActive(strategy)) { 2337fa3697d716b444bbea6be480801536c44bf69214Eric Laurent setStrategyMute(strategy, true, srcOutputs[i]); 2338fa3697d716b444bbea6be480801536c44bf69214Eric Laurent setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); 2339fa3697d716b444bbea6be480801536c44bf69214Eric Laurent } 23405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Move effects associated to this strategy from previous output to new output 23434660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (strategy == STRATEGY_MEDIA) { 234445c763947b657b347211dc9388754e05d30d0467Eric Laurent audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs); 23454660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen SortedVector<audio_io_handle_t> moved; 23464660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen for (size_t i = 0; i < mEffects.size(); i++) { 23474660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen EffectDescriptor *desc = mEffects.valueAt(i); 23484660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX && 234945c763947b657b347211dc9388754e05d30d0467Eric Laurent desc->mIo != fxOutput) { 23504660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen if (moved.indexOf(desc->mIo) < 0) { 23514660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen ALOGV("checkOutputForStrategy() moving effect %d to output %d", 235245c763947b657b347211dc9388754e05d30d0467Eric Laurent mEffects.keyAt(i), fxOutput); 23534660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, desc->mIo, 235445c763947b657b347211dc9388754e05d30d0467Eric Laurent fxOutput); 23554660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen moved.add(desc->mIo); 23564660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 235745c763947b657b347211dc9388754e05d30d0467Eric Laurent desc->mIo = fxOutput; 23584660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 23594660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 23604660455366d2ee64cb65f0ecd6f7ddeb1c17bac6Marco Nelissen } 23615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // Move tracks associated to this strategy from previous output to new output 2362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 2363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)i) == strategy) { 2364316222fcd60a429e53aa6205278697bb2df8ef32Glenn Kasten mpClientInterface->invalidateStream((AudioSystem::stream_type)i); 2365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2370f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkOutputForAllStrategies() 2371f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2372c16ac09f510437e8340be691720177a490ae78f0Eric Laurent checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 2373f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_PHONE); 2374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_SONIFICATION); 237512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 2376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_MEDIA); 2377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_DTMF); 2378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2380b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::getA2dpOutput() 2381b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 23825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp) { 2383b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 2384b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2385b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2386b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2387b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 2388b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 2389b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mOutputs.keyAt(i); 2390b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2391b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2392b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2393b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 2394b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 2395b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkA2dpSuspend() 2397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 23985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (!mHasA2dp) { 2399b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 2400b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2401b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t a2dpOutput = getA2dpOutput(); 2402b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (a2dpOutput == 0) { 2403b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 2404b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2405b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // suspend A2DP output if: 2407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (NOT already suspended) && 2408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is connected && 2409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage for communication || for record is SCO))) || 2410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is ringing || in call) 2411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 2412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // restore A2DP output if: 2413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (Already suspended) && 2414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is NOT connected || 2415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage NOT for communication && NOT for record is SCO))) && 2416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is NOT ringing && NOT in call) 2417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 2418f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpSuspended) { 2419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress == "") || 2420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) && 2421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) && 2422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState != AudioSystem::MODE_IN_CALL) && 2423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState != AudioSystem::MODE_RINGTONE))) { 2424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2425b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->restoreOutput(a2dpOutput); 2426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = false; 2427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress != "") && 2430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 2431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) || 2432f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState == AudioSystem::MODE_IN_CALL) || 2433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState == AudioSystem::MODE_RINGTONE))) { 2434f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2435b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->suspendOutput(a2dpOutput); 2436f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = true; 2437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2441f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache) 2442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2443ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent audio_devices_t device = AUDIO_DEVICE_NONE; 2444f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check the following by order of priority to request a routing change if necessary: 2447c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 1: the strategy enforced audible is active on the output: 2448c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // use device for strategy enforced audible 2449c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 2: we are in call or the strategy phone is active on the output: 2450f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy phone 2451c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 3: the strategy sonification is active on the output: 2452f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy sonification 245312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 4: the strategy "respectful" sonification is active on the output: 245412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // use device for strategy "respectful" sonification 245512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 5: the strategy media is active on the output: 2456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy media 245712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 6: the strategy DTMF is active on the output: 2458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy DTMF 245980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { 2460c16ac09f510437e8340be691720177a490ae78f0Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 2461c16ac09f510437e8340be691720177a490ae78f0Eric Laurent } else if (isInCall() || 246280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent outputDesc->isStrategyActive(STRATEGY_PHONE)) { 2463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 246480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) { 2465f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 246680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { 24675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); 246880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { 2469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 247080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { 2471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 2472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 24746a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getNewDevice() selected device %x", device); 2475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return device; 2476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getStrategyForStream(AudioSystem::stream_type stream) { 2479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return (uint32_t)getStrategy(stream); 2480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2482f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDevicesForStream(AudioSystem::stream_type stream) { 2483f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t devices; 2484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // By checking the range of stream before calling getStrategy, we avoid 24855efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 2486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and then return STRATEGY_MEDIA, but we want to return the empty set. 2487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream < (AudioSystem::stream_type) 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 2488ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent devices = AUDIO_DEVICE_NONE; 2489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2490f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioPolicyManagerBase::routing_strategy strategy = getStrategy(stream); 24915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devices = getDeviceForStrategy(strategy, true /*fromCache*/); 2492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return devices; 2494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2495f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy( 2497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream) { 2498f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // stream to strategy mapping 2499f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (stream) { 2500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::VOICE_CALL: 2501f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::BLUETOOTH_SCO: 2502f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_PHONE; 2503f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::RING: 2504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::ALARM: 2505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_SONIFICATION; 250612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::NOTIFICATION: 250712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi return STRATEGY_SONIFICATION_RESPECTFUL; 2508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DTMF: 2509f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_DTMF; 2510f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 25115efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("unknown stream type"); 2512f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::SYSTEM: 2513f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 2514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // while key clicks are played produces a poor result 2515f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::TTS: 2516f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::MUSIC: 2517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_MEDIA; 2518c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case AudioSystem::ENFORCED_AUDIBLE: 2519c16ac09f510437e8340be691720177a490ae78f0Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 2520f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2521f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2522f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 252312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivivoid AudioPolicyManagerBase::handleNotificationRoutingForStream(AudioSystem::stream_type stream) { 252412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi switch(stream) { 252512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::MUSIC: 252612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 2527c952527e6f89d5427881462823514be9d79f13e6Eric Laurent updateDevicesAndOutputs(); 252812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 252912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi default: 253012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 253112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 253212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi} 253312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 25345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, 25355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool fromCache) 2536f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2537ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 2538f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2539f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (fromCache) { 25403cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x", 25415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent strategy, mDeviceForStrategy[strategy]); 2542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mDeviceForStrategy[strategy]; 2543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (strategy) { 254612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 254712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case STRATEGY_SONIFICATION_RESPECTFUL: 254812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if (isInCall()) { 25495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 2550dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi } else if (isStreamActiveRemotely(AudioSystem::MUSIC, 2551dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 2552dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // while media is playing on a remote device, use the the sonification behavior. 2553dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // Note that we test this usecase before testing if media is playing because 2554dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // the isStreamActive() method only informs about the activity of a stream, not 2555dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi // if it's for local playback. Note also that we use the same delay between both tests 2556dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Trivi device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 255712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 255812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // while media is playing (or has recently played), use the same device 25595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 256012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else { 256112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // when media is not playing anymore, fall back on the sonification behavior 25625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 256312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 256412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 256512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 256612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 2567f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_DTMF: 2568f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall()) { 2569f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when off call, DTMF strategy follows the same rules as MEDIA strategy 25705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 2571f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2572f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2573f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when in call, DTMF and PHONE strategies follow the same rules 2574f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2575f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2576f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_PHONE: 2577f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // for phone strategy, we first consider the forced use and then the available devices by order 2578f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // of priority 2579f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { 2580f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_BT_SCO: 2581f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall() || strategy != STRATEGY_DTMF) { 2582c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 2583f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2584f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2585c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 2586f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2587c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; 2588f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2589f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if SCO device is requested but no SCO device is available, fall back to default case 2590f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2591f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2592f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: // FORCE_NONE 2593f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 25941afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (mHasA2dp && !isInCall() && 25951afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 2596ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 2597c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 2598f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2599c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2600f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2601f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2602c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 26031afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (device) break; 2604c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET; 26051afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (device) break; 2606b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (mPhoneState != AudioSystem::MODE_IN_CALL) { 2607b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2608b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2609b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2610b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2611b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2612b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2613b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2614b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2615b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2616b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2617b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent } 2618c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_EARPIECE; 26195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 26205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2621ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 26225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); 2623f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2624f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2625f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2626f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_SPEAKER: 2627f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 2628f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // A2DP speaker when forcing to speaker output 26291afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent if (mHasA2dp && !isInCall() && 26301afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 2631ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 2632c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2633f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 2634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2635b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (mPhoneState != AudioSystem::MODE_IN_CALL) { 2636b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2637b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2638b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2639b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2640b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2641b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2642b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2643b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2644b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2645b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent if (device) break; 2646b52f373bd56fbbb07a625de15125d33672d5143fEric Laurent } 2647c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; 26485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 26495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2650ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 26515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); 2652f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2653f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2654f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2655f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2656f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2657f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_SONIFICATION: 2658f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2659f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 2660f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handleIncallSonification(). 2661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 26625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); 2663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2665c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // FALL THROUGH 2666c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 2667c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 2668c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 2669ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // except: 2670ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // - when in call where it doesn't default to STRATEGY_PHONE behavior 2671ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent // - in countries where not enforced in which case it follows STRATEGY_MEDIA 2672c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 2673738207def5f691d605ae33d041116829a74513a9Eric Laurent if ((strategy == STRATEGY_SONIFICATION) || 2674738207def5f691d605ae33d041116829a74513a9Eric Laurent (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED)) { 2675c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; 2676ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2677ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); 2678ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent } 2679f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2680f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // The second device used for sonification is the same as the device used by media strategy 2681f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 2682f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2683f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_MEDIA: { 2684ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent uint32_t device2 = AUDIO_DEVICE_NONE; 268531363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi if (strategy != STRATEGY_SONIFICATION) { 268631363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi // no sonification on remote submix (e.g. WFD) 268748387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; 268848387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 2689ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 269048387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && 2691ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 2692c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 2693ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2694c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2695f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2696ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2697c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2698f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2699f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2700ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2701c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 27021afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent } 2703ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2704c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET; 27051afd84f62291d20414cbf58c7af01462a8fdca60Eric Laurent } 2706ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2707599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2708599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 2709ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2710599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; 2711599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } 2712ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2713c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 271531363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { 271631363a9cb94e80330c335fede0b92b1953a09517Jean-Michel Trivi // no sonification on aux digital (e.g. HDMI) 2717c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 27195a484b753cc72d6a50c1dd3bbf68b3403c741a3aEric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 27205a484b753cc72d6a50c1dd3bbf68b3403c741a3aEric Laurent (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_ANALOG_DOCK)) { 2721c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2722f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2723ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 2724c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; 2725f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2726f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2727c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 2728ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise 2729f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device |= device2; 27305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (device) break; 27315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device = mDefaultOutputDevice; 2732ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 27335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); 2734f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2735f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 2736f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2737f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 273864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 2739f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2740f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2741f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 27423cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 2743c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi return device; 2744f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2745f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2746c952527e6f89d5427881462823514be9d79f13e6Eric Laurentvoid AudioPolicyManagerBase::updateDevicesAndOutputs() 2747f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2748f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_STRATEGIES; i++) { 27495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 27505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2751c952527e6f89d5427881462823514be9d79f13e6Eric Laurent mPreviousOutputs = mOutputs; 27525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 27535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2754b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurentuint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc, 27559029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent audio_devices_t prevDevice, 27565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t delayMs) 27575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 27589029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // mute/unmute strategies using an incompatible device combination 27599029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // if muting, wait for the audio in pcm buffer to be drained before proceeding 27609029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // if unmuting, unmute only after the specified delay 27615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->isDuplicated()) { 2762b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return 0; 27635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 27645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 27655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t muteWaitMs = 0; 27665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t device = outputDesc->device(); 276780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent bool shouldMute = outputDesc->isActive() && (AudioSystem::popCount(device) >= 2); 27689029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // temporary mute output if device selection changes to avoid volume bursts due to 27699029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent // different per device volumes 277080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent bool tempMute = outputDesc->isActive() && (device != prevDevice); 27715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 27725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 27735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 27745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool mute = shouldMute && (curDevice & device) && (curDevice != device); 27755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent bool doMute = false; 27765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 27775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (mute && !outputDesc->mStrategyMutedByDevice[i]) { 27785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent doMute = true; 27795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = true; 27805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){ 27815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent doMute = true; 27825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = false; 27835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 27849029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (doMute || tempMute) { 27855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t j = 0; j < mOutputs.size(); j++) { 27865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(j); 2787f32e38e24db196671d3ea43427125a4e212466faEric Laurent // skip output if it does not share any device with current output 2788c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if ((desc->supportedDevices() & outputDesc->supportedDevices()) 2789ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent == AUDIO_DEVICE_NONE) { 27905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent continue; 27915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 27925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(j); 27933cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", 27945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mute ? "muting" : "unmuting", i, curDevice, curOutput); 27955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); 279680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (desc->isStrategyActive((routing_strategy)i)) { 2797f32e38e24db196671d3ea43427125a4e212466faEric Laurent // do tempMute only for current output 2798f32e38e24db196671d3ea43427125a4e212466faEric Laurent if (tempMute && (desc == outputDesc)) { 279901e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStrategyMute((routing_strategy)i, true, curOutput); 280001e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStrategyMute((routing_strategy)i, false, curOutput, 280101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent desc->latency() * 2, device); 28029029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent } 2803f32e38e24db196671d3ea43427125a4e212466faEric Laurent if ((tempMute && (desc == outputDesc)) || mute) { 28049029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent if (muteWaitMs < desc->latency()) { 28059029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent muteWaitMs = desc->latency(); 28069029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent } 28075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 28085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 28095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 28105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 28115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 28125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 28135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // FIXME: should not need to double latency if volume could be applied immediately by the 28145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // audioflinger mixer. We must account for the delay between now and the next time 28155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // the audioflinger thread for this output will process a buffer (which corresponds to 28165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // one buffer size, usually 1/2 or 1/4 of the latency). 28175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent muteWaitMs *= 2; 28185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // wait for the PCM output buffers to empty before proceeding with the rest of the command 28195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (muteWaitMs > delayMs) { 2820b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs -= delayMs; 2821b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent usleep(muteWaitMs * 1000); 2822b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2823f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2824b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return 0; 2825f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2826f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2827b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurentuint32_t AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, 2828f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2829f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent bool force, 2830f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent int delayMs) 2831f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 28325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); 2833f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 28345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent AudioParameter param; 2835f32e38e24db196671d3ea43427125a4e212466faEric Laurent uint32_t muteWaitMs; 2836f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2837f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->isDuplicated()) { 2838b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); 2839b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); 2840b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2841f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2842f32e38e24db196671d3ea43427125a4e212466faEric Laurent // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current 2843f32e38e24db196671d3ea43427125a4e212466faEric Laurent // output profile 2844f32e38e24db196671d3ea43427125a4e212466faEric Laurent if ((device != AUDIO_DEVICE_NONE) && 2845f32e38e24db196671d3ea43427125a4e212466faEric Laurent ((device & outputDesc->mProfile->mSupportedDevices) == 0)) { 2846f32e38e24db196671d3ea43427125a4e212466faEric Laurent return 0; 2847f32e38e24db196671d3ea43427125a4e212466faEric Laurent } 2848f32e38e24db196671d3ea43427125a4e212466faEric Laurent 2849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // filter devices according to output selected 2850f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices); 2851f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 28525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_devices_t prevDevice = outputDesc->mDevice; 28535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 28545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() prevDevice %04x", prevDevice); 28555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2856ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device != AUDIO_DEVICE_NONE) { 28575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent outputDesc->mDevice = device; 285831de680d5649ffc9568172b3904dccd3580d71aeVincent Becker 285931de680d5649ffc9568172b3904dccd3580d71aeVincent Becker // Force routing if previously asked for this output 286031de680d5649ffc9568172b3904dccd3580d71aeVincent Becker if (outputDesc->mForceRouting) { 286131de680d5649ffc9568172b3904dccd3580d71aeVincent Becker ALOGV("Force routing to current device as previous device was null for this output"); 286231de680d5649ffc9568172b3904dccd3580d71aeVincent Becker force = true; 286331de680d5649ffc9568172b3904dccd3580d71aeVincent Becker 286431de680d5649ffc9568172b3904dccd3580d71aeVincent Becker // Request consumed. Reset mForceRouting to false 286531de680d5649ffc9568172b3904dccd3580d71aeVincent Becker outputDesc->mForceRouting = false; 286631de680d5649ffc9568172b3904dccd3580d71aeVincent Becker } 28675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 286831de680d5649ffc9568172b3904dccd3580d71aeVincent Becker else { 286931de680d5649ffc9568172b3904dccd3580d71aeVincent Becker // Device is null and does not reflect the routing. Save the necessity to force 287031de680d5649ffc9568172b3904dccd3580d71aeVincent Becker // re-routing upon next attempt to select a non-null device for this output 287131de680d5649ffc9568172b3904dccd3580d71aeVincent Becker outputDesc->mForceRouting = true; 287231de680d5649ffc9568172b3904dccd3580d71aeVincent Becker } 287331de680d5649ffc9568172b3904dccd3580d71aeVincent Becker 28749029a4fe8abafd383e6fbb1409d1e2f749b51391Eric Laurent muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); 28755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2876f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Do not change the routing if: 2877ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent // - the requested device is AUDIO_DEVICE_NONE 2878f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the requested device is the same as current device and force is not specified. 2879f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Doing this check here allows the caller to call setOutputDevice() without conditions 2880ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) { 28815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); 2882b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 2883f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 28855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("setOutputDevice() changing device"); 2886f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do the routing 2887f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)device); 28885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mpClientInterface->setParameters(output, param.toString(), delayMs); 28895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 2890f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // update stream volumes according to new device 2891f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin applyStreamVolumes(output, device, delayMs); 2892b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent 2893b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent return muteWaitMs; 28945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 2895f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 28965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getInputProfile(audio_devices_t device, 28975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t samplingRate, 28985082dbeb19e37883230510129c94336063a4f91cGlenn Kasten audio_format_t format, 28992c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten audio_channel_mask_t channelMask) 29005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 29015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // Choose an input profile based on the requested capture parameters: select the first available 29025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // profile supporting all requested parameters. 290370c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 29045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent { 290570c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mHwModules[i]->mHandle == 0) { 29065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent continue; 29075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 290870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 29095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent { 291070c236c9290732782d5267935af1475b8d5ae602Eric Laurent IOProfile *profile = mHwModules[i]->mInputProfiles[j]; 2911fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean // profile->log(); 291270c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 29132d749b0bda4ae60ef1a940eeba86121b2e94d07dGlenn Kasten channelMask, AUDIO_OUTPUT_FLAG_NONE)) { 291470c236c9290732782d5267935af1475b8d5ae602Eric Laurent return profile; 29155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 29165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2917f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 291870c236c9290732782d5267935af1475b8d5ae602Eric Laurent return NULL; 2919f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2920f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2921f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) 2922f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2923ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 2924f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 29259641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent switch (inputSource) { 29269641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 29279641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { 29289641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 29299641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent break; 29309641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent } 29319641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent // FALL THROUGH 29329641bd36dbf0c4b1eeb84499b35c1cdb7fa5a530Eric Laurent 2933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_DEFAULT: 2934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_MIC: 293533bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood if (mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) { 293633bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP; 293733bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood break; 293833bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood } 293933bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood // FALL THROUGH 294033bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood 2941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_RECOGNITION: 2942fc9b2457ce4721538dca0903de63c7766e97498aEric Laurent case AUDIO_SOURCE_HOTWORD: 2943f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_COMMUNICATION: 2944f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO && 2945c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 2946c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 2947c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_WIRED_HEADSET) { 2948c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_WIRED_HEADSET; 2949fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_USB_DEVICE) { 2950fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean device = AUDIO_DEVICE_IN_USB_DEVICE; 2951c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { 2952c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BUILTIN_MIC; 2953f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2954f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2955f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_CAMCORDER: 2956c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (mAvailableInputDevices & AUDIO_DEVICE_IN_BACK_MIC) { 2957c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BACK_MIC; 2958c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { 2959c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_BUILTIN_MIC; 2960f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2961f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2962f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 2963f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 2964c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { 2965c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi device = AUDIO_DEVICE_IN_VOICE_CALL; 29665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 2967f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 296848387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi case AUDIO_SOURCE_REMOTE_SUBMIX: 296948387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi if (mAvailableInputDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { 297048387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; 297148387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } 297248387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi break; 2973f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 297464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 2975f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 2976f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 29776a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 2978c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi return device; 2979f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2980f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 29816d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivibool AudioPolicyManagerBase::isVirtualInputDevice(audio_devices_t device) 29826d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi{ 29836d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi if ((device & AUDIO_DEVICE_BIT_IN) != 0) { 29846d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi device &= ~AUDIO_DEVICE_BIT_IN; 29856d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) 29866d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi return true; 29876d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi } 29886d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi return false; 29896d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi} 29906d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi 29916d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Triviaudio_io_handle_t AudioPolicyManagerBase::getActiveInput(bool ignoreVirtualInputs) 2992f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 29946d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi const AudioInputDescriptor * input_descriptor = mInputs.valueAt(i); 29956d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi if ((input_descriptor->mRefCount > 0) 29966d3a115c091adc1618b3d1e50a86951c3b35fa30Jean-Michel Trivi && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) { 2997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mInputs.keyAt(i); 2998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2999f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3000f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 3001f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3002f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3003e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 3004c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForVolume(audio_devices_t device) 3005e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 3006ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3007e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // this happens when forcing a route update and no track is active on an output. 3008e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // In this case the returned category is not important. 3009c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 3010c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else if (AudioSystem::popCount(device) > 1) { 3011e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // Multiple device selection is either: 3012e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - speaker + one other device: give priority to speaker in this case. 3013e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 3014e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 3015e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // selection if not the speaker. 3016c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 3017c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 3018c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else { 3019c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 3020c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 3021e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 3022e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 302364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW_IF(AudioSystem::popCount(device) != 1, 3024c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 3025e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device); 3026e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 3027c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return device; 3028c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 3029c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3030f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric LaurentAudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(audio_devices_t device) 3031c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 3032f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent switch(getDeviceForVolume(device)) { 3033e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 3034e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_EARPIECE; 3035e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 3036e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 3037e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 3038e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 3039e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 3040e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 3041e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_HEADSET; 3042e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 3043e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 3044e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 3045c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent case AUDIO_DEVICE_OUT_AUX_DIGITAL: 3046599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent case AUDIO_DEVICE_OUT_USB_ACCESSORY: 3047599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent case AUDIO_DEVICE_OUT_USB_DEVICE: 304848387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi case AUDIO_DEVICE_OUT_REMOTE_SUBMIX: 3049e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent default: 3050e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_SPEAKER; 3051e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 3052e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent} 3053e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 3054f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentfloat AudioPolicyManagerBase::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, 3055e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int indexInUi) 3056e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 3057e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device_category deviceCategory = getDeviceCategory(device); 3058e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 3059e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 3060f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // the volume index in the UI is relative to the min and max volume indices for this stream type 3061e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 3062e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[VOLMIN].mIndex; 3063f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 3064f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (streamDesc.mIndexMax - streamDesc.mIndexMin); 3065f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3066f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // find what part of the curve this index volume belongs to, or if it's out of bounds 3067f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int segment = 0; 3068e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 3069f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0.0f; 3070e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 3071f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 0; 3072e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 3073f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 1; 3074e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 3075f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 2; 3076f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { // out of bounds 3077f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0f; 3078f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3079f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3080f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // linear interpolation in the attenuation table in dB 3081e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent float decibels = curve[segment].mDBAttenuation + 3082e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 3083e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ( (curve[segment+1].mDBAttenuation - 3084e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation) / 3085e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(curve[segment+1].mIndex - 3086e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex)) ); 3087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3088f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 3089f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 30903cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 3091e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex, volIdx, 3092e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mIndex, 3093e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation, 3094cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent decibels, 3095e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mDBAttenuation, 3096f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin amplification); 3097f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3098f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return amplification; 3099f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3101cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 3102e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 3103e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 3104e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 3105e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 3106e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 3107e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 3108e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 3109cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent}; 3110cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent 3111e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 3112e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 3113e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 3114e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 3115e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 3116e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 3117e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 3118e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 3119e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 3120e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 312118fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Triviconst AudioPolicyManagerBase::VolumeCurvePoint 312218fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi AudioPolicyManagerBase::sSpeakerSonificationVolumeCurveDrc[AudioPolicyManagerBase::VOLCNT] = { 312318fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f} 312418fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi}; 312518fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi 3126ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks 312787e28f7b352fb77f46e16ebcdd85cbf01396a203Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets. 312887e28f7b352fb77f46e16ebcdd85cbf01396a203Eric Laurent// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java). 3129123897874418f9f0e48bb89386d8c470e6975f28Jean-Michel Trivi// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset. 313087e28f7b352fb77f46e16ebcdd85cbf01396a203Eric Laurent 3131ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 3132ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent AudioPolicyManagerBase::sDefaultSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 3133123897874418f9f0e48bb89386d8c470e6975f28Jean-Michel Trivi {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f} 3134ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent}; 3135ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent 3136ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 313718fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi AudioPolicyManagerBase::sDefaultSystemVolumeCurveDrc[AudioPolicyManagerBase::VOLCNT] = { 313818fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f} 313918fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi}; 314018fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi 314118fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Triviconst AudioPolicyManagerBase::VolumeCurvePoint 3142ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent AudioPolicyManagerBase::sHeadsetSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 31437465678e0d5711ebcd78ae47b3a76821534a23eaEric Laurent {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f} 3144ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent}; 3145e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 3146e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 31470d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent AudioPolicyManagerBase::sDefaultVoiceVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 31480d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f} 31490d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent}; 31500d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent 31510d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 31520d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent AudioPolicyManagerBase::sSpeakerVoiceVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 31530d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f} 31540d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent}; 31550d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent 31560d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 3157e714af927c1e87a488178315b78b0c12c0ec9db9Eric Laurent *AudioPolicyManagerBase::sVolumeProfiles[AudioSystem::NUM_STREAM_TYPES] 3158e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent [AudioPolicyManagerBase::DEVICE_CATEGORY_CNT] = { 3159ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_VOICE_CALL 31600d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 31610d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 31620d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 3163e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 3164ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_SYSTEM 3165ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 3166ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3167ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 3168ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 3169ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_RING 3170e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 3171e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3172e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 3173e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 3174ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_MUSIC 3175ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 3176ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3177ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 3178ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 3179ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_ALARM 318012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 318112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 318212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 318312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi }, 3184ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_NOTIFICATION 3185e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 3186ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3187e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 3188c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 3189ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_BLUETOOTH_SCO 31900d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 31910d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 31920d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 3193c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 3194ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_ENFORCED_AUDIBLE 3195ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 3196ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3197ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 3198ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 3199ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_DTMF 3200ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 3201ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3202ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 3203ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 3204ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent { // AUDIO_STREAM_TTS 3205ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 3206ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3207ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 3208ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent }, 3209e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 3210e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 3211e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentvoid AudioPolicyManagerBase::initializeVolumeCurves() 3212e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 3213e714af927c1e87a488178315b78b0c12c0ec9db9Eric Laurent for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 3214e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 3215cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent mStreams[i].mVolumeCurve[j] = 3216ddfe26905ea3210c86a88eeb331eef4c9f99b931Eric Laurent sVolumeProfiles[i][j]; 3217cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 3218cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 321918fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi 322018fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi // Check availability of DRC on speaker path: if available, override some of the speaker curves 322118fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi if (mSpeakerDrcEnabled) { 322218fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 322318fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi sDefaultSystemVolumeCurveDrc; 322418fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 322518fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi sSpeakerSonificationVolumeCurveDrc; 322618fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 322718fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi sSpeakerSonificationVolumeCurveDrc; 322818fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 322918fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi sSpeakerSonificationVolumeCurveDrc; 323018fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi } 3231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3233c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentfloat AudioPolicyManagerBase::computeVolume(int stream, 3234c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 3235c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 3236f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device) 3237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = 1.0; 3239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 3240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 3241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3242ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = outputDesc->device(); 3244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if volume is not 0 (not muted), force media volume to max on digital output 3247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::MUSIC && 3248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin index != mStreams[stream].mIndexMin && 3249f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent (device == AUDIO_DEVICE_OUT_AUX_DIGITAL || 325003d92f4a6ec954cfa81765f00c1784e2c2ff2f49Paul McLean device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) { 3251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0; 3252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = volIndexToAmpl(device, streamDesc, index); 3255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if a headset is connected, apply the following rules to ring tones and notifications 3257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // to avoid sound level bursts in user's ears: 3258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - always attenuate ring tones and notifications volume by 6dB 3259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - if music is playing, always limit the volume to current music volume, 3260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // with a minimum threshold at -36dB so that notification is always perceived. 326112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 3262c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | 3263c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 3264c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi AUDIO_DEVICE_OUT_WIRED_HEADSET | 3265c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) && 326612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION) 326712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) 3268738207def5f691d605ae33d041116829a74513a9Eric Laurent || (stream == AudioSystem::SYSTEM) 3269738207def5f691d605ae33d041116829a74513a9Eric Laurent || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) && 3270738207def5f691d605ae33d041116829a74513a9Eric Laurent (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_NONE))) && 3271f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin streamDesc.mCanBeMuted) { 3272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 3273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when the phone is ringing we must consider that music could have been paused just before 3274f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // by the music application and behave as if music was active if the last music track was 3275f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // just stopped 3276ac3cf10ef6de12e69540a1244ac7255f93fa7502Eric Laurent if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || 3277ac3cf10ef6de12e69540a1244ac7255f93fa7502Eric Laurent mLimitRingtoneVolume) { 327817a73c3394547692457299dc512b5c2312ea0344Eric Laurent audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/); 3279c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float musicVol = computeVolume(AudioSystem::MUSIC, 328017a73c3394547692457299dc512b5c2312ea0344Eric Laurent mStreams[AudioSystem::MUSIC].getVolumeIndex(musicDevice), 3281c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 328217a73c3394547692457299dc512b5c2312ea0344Eric Laurent musicDevice); 3283c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 3284c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 3285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume > minVol) { 3286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = minVol; 32876a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 3288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return volume; 3293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3295c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::checkAndSetVolume(int stream, 3296c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 3297c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 3298f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 3299c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 3300c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 3301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change actual stream volume if the stream is muted 3304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 33053cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkAndSetVolume() stream %d muted count %d", 33065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent stream, mOutputs.valueFor(output)->mMuteCount[stream]); 3307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change in call volume if bluetooth is connected and vice versa 3311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 3312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) { 33136a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 3314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, mForceUse[AudioSystem::FOR_COMMUNICATION]); 3315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 3316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = computeVolume(stream, index, output, device); 3319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // We actually change the volume if: 3320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the float value returned by computeVolume() changed 3321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the force flag is set 3322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 3323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force) { 3324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueFor(output)->mCurVolume[stream] = volume; 33253cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 33260d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 33270d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent // enabled 33280d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent if (stream == AudioSystem::BLUETOOTH_SCO) { 33290d6490a58bf607f1efc00638709f9c4c8f7dd270Eric Laurent mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs); 3330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); 3332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3333f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL || 3335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::BLUETOOTH_SCO) { 3336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float voiceVolume; 3337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force voice volume to max for bluetooth SCO as volume is managed by the headset 3338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL) { 3339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 3340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 3341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = 1.0; 3342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3344b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { 3345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 3346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLastVoiceVolume = voiceVolume; 3347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3353c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, 3354f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 3355c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 3356c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 3357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 33583cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("applyStreamVolumes() for output %d and device %x", output, device); 3359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 3361c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 3362f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mStreams[stream].getVolumeIndex(device), 3363c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 3364c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 3365c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs, 3366c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent force); 3367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 337001e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurentvoid AudioPolicyManagerBase::setStrategyMute(routing_strategy strategy, 337101e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent bool on, 337201e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_io_handle_t output, 337301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent int delayMs, 337401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t device) 3375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 33763cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 3377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 3378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)stream) == strategy) { 337901e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent setStreamMute(stream, on, output, delayMs, device); 3380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3381f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3382f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 338401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurentvoid AudioPolicyManagerBase::setStreamMute(int stream, 338501e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent bool on, 338601e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_io_handle_t output, 338701e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent int delayMs, 338801e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent audio_devices_t device) 3389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 3391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 3392ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if (device == AUDIO_DEVICE_NONE) { 339301e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent device = outputDesc->device(); 339401e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent } 3395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 33963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x", 339701e6272f0a3a7d1d53e826012377ff9269b03b06Eric Laurent stream, on, output, outputDesc->mMuteCount[stream], device); 3398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (on) { 3400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 3401738207def5f691d605ae33d041116829a74513a9Eric Laurent if (streamDesc.mCanBeMuted && 3402738207def5f691d605ae33d041116829a74513a9Eric Laurent ((stream != AudioSystem::ENFORCED_AUDIBLE) || 3403738207def5f691d605ae33d041116829a74513a9Eric Laurent (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_NONE))) { 3404c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 3405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 3408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mMuteCount[stream]++; 3409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 3410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 34113cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("setStreamMute() unmuting non muted stream!"); 3412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 3413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (--outputDesc->mMuteCount[stream] == 0) { 3415c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 3416c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi streamDesc.getVolumeIndex(device), 3417c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 3418c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 3419c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs); 3420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, bool stateChange) 3425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if the stream pertains to sonification strategy and we are in call we must 3427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // mute the stream if it is low visibility. If it is high visibility, we must play a tone 3428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // in the device used for phone strategy and play the tone if the selected device does not 3429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // interfere with the device used for phone strategy 3430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 3431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // many times as there are active tracks on the output 343212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 343312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if ((stream_strategy == STRATEGY_SONIFICATION) || 343412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { 3435b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 34366a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 3437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, starting, outputDesc->mDevice, stateChange); 3438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream]) { 3439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int muteCount = 1; 3440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stateChange) { 3441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin muteCount = outputDesc->mRefCount[stream]; 3442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) { 34446a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 3445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 3446b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 3447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 34496a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility"); 34505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (outputDesc->device() & 34515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) { 34526a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 3453f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 3454b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 3455f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (starting) { 3458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL); 3459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 3460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->stopTone(); 3461f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3462f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3464f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3465f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3466f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isInCall() 3468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return isStateInCall(mPhoneState); 3470f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStateInCall(int state) { 3473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((state == AudioSystem::MODE_IN_CALL) || 3474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (state == AudioSystem::MODE_IN_COMMUNICATION)); 3475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsCpuLoad() 3478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_CPU_LOAD; 3480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsMemory() 3483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_MEMORY; 3485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioOutputDescriptor class implementation 3488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3489b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric LaurentAudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor( 34905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const IOProfile *profile) 34912d749b0bda4ae60ef1a940eeba86121b2e94d07dGlenn Kasten : mId(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), 34922c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten mChannelMask(0), mLatency(0), 3493ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), 349431de680d5649ffc9568172b3904dccd3580d71aeVincent Becker mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0), 349531de680d5649ffc9568172b3904dccd3580d71aeVincent Becker mForceRouting(false) 3496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // clear usage count for all stream types 3498f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 3499f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[i] = 0; 3500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurVolume[i] = -1.0; 3501f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mMuteCount[i] = 0; 3502f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStopTime[i] = 0; 3503f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 350485ad78f27ca032e90af0f2100659d12c16322c76Marco Nelissen for (int i = 0; i < NUM_STRATEGIES; i++) { 350585ad78f27ca032e90af0f2100659d12c16322c76Marco Nelissen mStrategyMutedByDevice[i] = false; 350685ad78f27ca032e90af0f2100659d12c16322c76Marco Nelissen } 35073cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (profile != NULL) { 35083cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mSamplingRate = profile->mSamplingRates[0]; 35093cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mFormat = profile->mFormats[0]; 35103cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mChannelMask = profile->mChannelMasks[0]; 35113cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent mFlags = profile->mFlags; 35123cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 3513f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3515dc3bf1a37425697277f6ed04fc8cfe4a52fd678aJean-Michel Triviaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::device() const 3516f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 3518f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 3519f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 3520f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return mDevice; 3521f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3522f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3523f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 35245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::latency() 35255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 35265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isDuplicated()) { 35275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 35285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 35295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return mLatency; 35305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 35335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::sharesHwModuleWith( 35345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const AudioOutputDescriptor *outputDesc) 35355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 35365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (isDuplicated()) { 35375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 35385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (outputDesc->isDuplicated()){ 35395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2); 35405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 354170c236c9290732782d5267935af1475b8d5ae602Eric Laurent return (mProfile->mModule == outputDesc->mProfile->mModule); 35425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 35435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 35445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 3545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta) 3546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3547f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // forward usage count change to attached outputs 3548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 3549f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput1->changeRefCount(stream, delta); 3550f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput2->changeRefCount(stream, delta); 3551f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3552f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((delta + (int)mRefCount[stream]) < 0) { 355364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]); 3554f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] = 0; 3555f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 3556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3557f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] += delta; 35586a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 3559f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3561f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::supportedDevices() 3562b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 3563b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (isDuplicated()) { 3564f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 3565b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 3566b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mProfile->mSupportedDevices ; 3567b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 3568b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 3569b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 357042fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::isActive(uint32_t inPastMs) const 357142fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent{ 357280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return isStrategyActive(NUM_STRATEGIES, inPastMs); 357380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent} 357480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent 357580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy, 357680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent uint32_t inPastMs, 357780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent nsecs_t sysTime) const 357880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent{ 357980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if ((sysTime == 0) && (inPastMs != 0)) { 358080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime = systemTime(); 358180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 358242fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 358380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (((getStrategy((AudioSystem::stream_type)i) == strategy) || 358480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent (NUM_STRATEGIES == strategy)) && 358580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent isStreamActive((AudioSystem::stream_type)i, inPastMs, sysTime)) { 358642fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent return true; 358742fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent } 358842fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent } 358942fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent return false; 359042fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent} 359142fa8215a763822c0d03fc936e4cac1eb864c9ccEric Laurent 359280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurentbool AudioPolicyManagerBase::AudioOutputDescriptor::isStreamActive(AudioSystem::stream_type stream, 359380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent uint32_t inPastMs, 359480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent nsecs_t sysTime) const 359580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent{ 359680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (mRefCount[stream] != 0) { 359780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return true; 359880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 359980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (inPastMs == 0) { 360080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return false; 360180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 360280f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (sysTime == 0) { 360380f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent sysTime = systemTime(); 360480f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 360580f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 360680f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return true; 360780f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent } 360880f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent return false; 360980f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent} 361080f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent 361180f5b0400f86d49e70aa1a793b34f34492f005bcEric Laurent 3612f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd) 3613f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 3615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 3616f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 3617f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3618f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 3619f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3620a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 3621f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 362270c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 3623f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3624f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 3625f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3626f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 3627f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3628f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", device()); 3629f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 3631f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3632f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 3633f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 3634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3635f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 3636f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3637f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3638f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3639f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3640f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3641f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioInputDescriptor class implementation 3642f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 36435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor(const IOProfile *profile) 3644fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean : mId(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(0), 3645ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mDevice(AUDIO_DEVICE_NONE), mRefCount(0), 36465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mInputSource(0), mProfile(profile) 3647f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3648fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean if (profile != NULL) { 3649fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mSamplingRate = profile->mSamplingRates[0]; 3650fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mFormat = profile->mFormats[0]; 3651fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean mChannelMask = profile->mChannelMasks[0]; 3652fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 3653f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3654f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3655f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd) 3656f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3657f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 3658f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 3659f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 3660f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 3662f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 3664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 366570c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 3666f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3667f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 3668f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3669f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 3670f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3671f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3673f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3674f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3675f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3676f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- StreamDescriptor class implementation 3677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3678c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric LaurentAudioPolicyManagerBase::StreamDescriptor::StreamDescriptor() 3679c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 3680c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 3681c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 3682c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 3683c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3684c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentint AudioPolicyManagerBase::StreamDescriptor::getVolumeIndex(audio_devices_t device) 3685c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 3686c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AudioPolicyManagerBase::getDeviceForVolume(device); 3687c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 3688c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 3689c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 3690c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 3691c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return mIndexCur.valueFor(device); 3692c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 3693c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3694c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::StreamDescriptor::dump(int fd) 3695f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3696c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent const size_t SIZE = 256; 3697c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent char buffer[SIZE]; 3698c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent String8 result; 3699c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3700c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 3701c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 3702c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 3703c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 3704c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 3705c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.keyAt(i), 3706c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.valueAt(i)); 3707c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 3708c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 3709c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append("\n"); 3710c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 3711c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent write(fd, result.string(), result.size()); 3712f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3713f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- EffectDescriptor class implementation 3715f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3716f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::EffectDescriptor::dump(int fd) 3717f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 3719f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 3720f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 3721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 37221c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 3723f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3724f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 3725f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3726f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Session: %d\n", mSession); 3727f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3728f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 3729f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 3730582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 3731582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent result.append(buffer); 3732f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 3733f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 3734f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 3735f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 3736f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 37375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// --- IOProfile class implementation 37385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 373970c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::HwModule::HwModule(const char *name) 374070c236c9290732782d5267935af1475b8d5ae602Eric Laurent : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0) 374170c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 374270c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 374370c236c9290732782d5267935af1475b8d5ae602Eric Laurent 374470c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::HwModule::~HwModule() 374570c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 374670c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 374770c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mOutputProfiles[i]; 374870c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 374970c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 375070c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete mInputProfiles[i]; 375170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 375270c236c9290732782d5267935af1475b8d5ae602Eric Laurent free((void *)mName); 375370c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 375470c236c9290732782d5267935af1475b8d5ae602Eric Laurent 375570c236c9290732782d5267935af1475b8d5ae602Eric Laurentvoid AudioPolicyManagerBase::HwModule::dump(int fd) 375670c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 375770c236c9290732782d5267935af1475b8d5ae602Eric Laurent const size_t SIZE = 256; 375870c236c9290732782d5267935af1475b8d5ae602Eric Laurent char buffer[SIZE]; 375970c236c9290732782d5267935af1475b8d5ae602Eric Laurent String8 result; 376070c236c9290732782d5267935af1475b8d5ae602Eric Laurent 376170c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - name: %s\n", mName); 376270c236c9290732782d5267935af1475b8d5ae602Eric Laurent result.append(buffer); 376370c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 376470c236c9290732782d5267935af1475b8d5ae602Eric Laurent result.append(buffer); 376570c236c9290732782d5267935af1475b8d5ae602Eric Laurent write(fd, result.string(), result.size()); 376670c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mOutputProfiles.size()) { 37674387d30660db3c9a10b16b3a4a1c986c330e788bPatrick Tjin write(fd, " - outputs:\n", strlen(" - outputs:\n")); 376870c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 3769c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross snprintf(buffer, SIZE, " output %zu:\n", i); 3770599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent write(fd, buffer, strlen(buffer)); 377170c236c9290732782d5267935af1475b8d5ae602Eric Laurent mOutputProfiles[i]->dump(fd); 377270c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 377370c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 377470c236c9290732782d5267935af1475b8d5ae602Eric Laurent if (mInputProfiles.size()) { 37754387d30660db3c9a10b16b3a4a1c986c330e788bPatrick Tjin write(fd, " - inputs:\n", strlen(" - inputs:\n")); 377670c236c9290732782d5267935af1475b8d5ae602Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 3777c7b6e3c857c5f5af5f244d0b877c41a9c55f92abColin Cross snprintf(buffer, SIZE, " input %zu:\n", i); 3778599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent write(fd, buffer, strlen(buffer)); 377970c236c9290732782d5267935af1475b8d5ae602Eric Laurent mInputProfiles[i]->dump(fd); 378070c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 378170c236c9290732782d5267935af1475b8d5ae602Eric Laurent } 378270c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 378370c236c9290732782d5267935af1475b8d5ae602Eric Laurent 378470c236c9290732782d5267935af1475b8d5ae602Eric LaurentAudioPolicyManagerBase::IOProfile::IOProfile(HwModule *module) 37850977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent : mFlags((audio_output_flags_t)0), mModule(module) 37865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 37875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 37885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 37895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric LaurentAudioPolicyManagerBase::IOProfile::~IOProfile() 37905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 379170c236c9290732782d5267935af1475b8d5ae602Eric Laurent} 379270c236c9290732782d5267935af1475b8d5ae602Eric Laurent 3793b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent// checks if the IO profile is compatible with specified parameters. 3794b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent// Sampling rate, format and channel mask must be specified in order to 3795b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent// get a valid a match 379670c236c9290732782d5267935af1475b8d5ae602Eric Laurentbool AudioPolicyManagerBase::IOProfile::isCompatibleProfile(audio_devices_t device, 379770c236c9290732782d5267935af1475b8d5ae602Eric Laurent uint32_t samplingRate, 37985082dbeb19e37883230510129c94336063a4f91cGlenn Kasten audio_format_t format, 37992c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten audio_channel_mask_t channelMask, 38000977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent audio_output_flags_t flags) const 380170c236c9290732782d5267935af1475b8d5ae602Eric Laurent{ 38022d749b0bda4ae60ef1a940eeba86121b2e94d07dGlenn Kasten if (samplingRate == 0 || !audio_is_valid_format(format) || channelMask == 0) { 3803b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent return false; 3804b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3805b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent 3806b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent if ((mSupportedDevices & device) != device) { 3807b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent return false; 3808b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3809b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent if ((mFlags & flags) != flags) { 3810b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent return false; 3811b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3812b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent size_t i; 3813b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent for (i = 0; i < mSamplingRates.size(); i++) 3814b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent { 3815b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent if (mSamplingRates[i] == samplingRate) { 3816b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent break; 3817b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3818b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3819b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent if (i == mSamplingRates.size()) { 3820b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent return false; 3821b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3822b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent for (i = 0; i < mFormats.size(); i++) 3823b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent { 3824b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent if (mFormats[i] == format) { 3825b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent break; 3826b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3827b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3828b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent if (i == mFormats.size()) { 3829b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent return false; 3830b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3831b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent for (i = 0; i < mChannelMasks.size(); i++) 3832b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent { 3833b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent if (mChannelMasks[i] == channelMask) { 3834b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent break; 3835b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3836b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3837b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent if (i == mChannelMasks.size()) { 3838b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent return false; 3839b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent } 3840b40b96a78537d63d801af7e706764c68acf8f182Eric Laurent return true; 38415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 38425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 38435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::IOProfile::dump(int fd) 38445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 38455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const size_t SIZE = 256; 38465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char buffer[SIZE]; 38475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent String8 result; 38485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 384970c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - sampling rates: "); 38505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 38515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 38525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent snprintf(buffer, SIZE, "%d", mSamplingRates[i]); 38535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 38545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mSamplingRates.size() - 1) ? "\n" : ", "); 38555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 38565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 385770c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - channel masks: "); 38585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 38595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 3860a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]); 38615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 38625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mChannelMasks.size() - 1) ? "\n" : ", "); 38635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 38645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 386570c236c9290732782d5267935af1475b8d5ae602Eric Laurent snprintf(buffer, SIZE, " - formats: "); 38665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 38675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 3868a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald snprintf(buffer, SIZE, "0x%08x", mFormats[i]); 38695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 38705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(i == (mFormats.size() - 1) ? "\n" : ", "); 38715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 38725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 3873a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald snprintf(buffer, SIZE, " - devices: 0x%04x\n", mSupportedDevices); 38745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 3875a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald snprintf(buffer, SIZE, " - flags: 0x%04x\n", mFlags); 38765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent result.append(buffer); 38775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 38785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent write(fd, result.string(), result.size()); 38795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 38805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 3881fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLeanvoid AudioPolicyManagerBase::IOProfile::log() 3882fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean{ 3883fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean const size_t SIZE = 256; 3884fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean char buffer[SIZE]; 3885fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean String8 result; 3886fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 3887fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV(" - sampling rates: "); 3888fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for (size_t i = 0; i < mSamplingRates.size(); i++) { 3889fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV(" %d", mSamplingRates[i]); 3890fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 3891fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 3892fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV(" - channel masks: "); 3893fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for (size_t i = 0; i < mChannelMasks.size(); i++) { 3894fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV(" 0x%04x", mChannelMasks[i]); 3895fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 3896fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 3897fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV(" - formats: "); 3898fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean for (size_t i = 0; i < mFormats.size(); i++) { 3899fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV(" 0x%08x", mFormats[i]); 3900fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean } 3901fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 3902fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV(" - devices: 0x%04x\n", mSupportedDevices); 3903fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV(" - flags: 0x%04x\n", mFlags); 3904fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean} 3905fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean 39065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent// --- audio_policy.conf file parsing 39075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentstruct StringToEnum { 39095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *name; 39105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t value; 39115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 39125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#define STRING_TO_ENUM(string) { #string, string } 39145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 39155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sDeviceNameToEnumTable[] = { 39175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE), 39185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER), 39195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET), 39205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE), 39215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO), 39225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP), 39235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL), 39245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET), 3925599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET), 3926599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE), 3927599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY), 3928599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB), 392948387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX), 39305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), 39315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), 39325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET), 39335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL), 39345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL), 39355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC), 393648387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX), 3937ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET), 3938ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET), 3939ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY), 394026101ada7b6a34cc517b92dec1e96b17fb4a996dPeter Yoon STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE), 394133bf1b0fe363bd4892349d160f54d860567fab12Mike Lockwood STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP), 39425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 39435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sFlagNameToEnumTable[] = { 39450977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT), 39460977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), 3947b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), 3948b2971bf2ae4e9da3155559aa134e3aa6c2b216a4Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), 3949b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD), 3950b4d07b97d23cfaffe22c7859ad7c45e168a7df0eRichard Fitzgerald STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING), 39515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 39525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sFormatNameToEnumTable[] = { 39545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT), 39555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT), 39569df8ecc68bdaa90aaac86b9218d728f84586660eGlenn Kasten STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT), 39579df8ecc68bdaa90aaac86b9218d728f84586660eGlenn Kasten STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT), 39589df8ecc68bdaa90aaac86b9218d728f84586660eGlenn Kasten STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT), 39599df8ecc68bdaa90aaac86b9218d728f84586660eGlenn Kasten STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED), 39605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_MP3), 39615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AAC), 39625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_VORBIS), 3963d97aa170de2e0d37aa4cf5305a72939ea7639d88Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V1), 3964d97aa170de2e0d37aa4cf5305a72939ea7639d88Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V2), 3965d97aa170de2e0d37aa4cf5305a72939ea7639d88Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_OPUS), 3966d97aa170de2e0d37aa4cf5305a72939ea7639d88Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AC3), 3967d97aa170de2e0d37aa4cf5305a72939ea7639d88Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_E_AC3), 39685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 39695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sOutChannelsNameToEnumTable[] = { 39715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO), 39725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 39735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 39745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 39755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 39765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentconst struct StringToEnum sInChannelsNameToEnumTable[] = { 39785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), 39795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), 398060758e27a4be8fc9ac1180f8a4055234e1702cc9Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK), 39815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent}; 39825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 39845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentuint32_t AudioPolicyManagerBase::stringToEnum(const struct StringToEnum *table, 39855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent size_t size, 39865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *name) 39875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 39885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent for (size_t i = 0; i < size; i++) { 39895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(table[i].name, name) == 0) { 39905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("stringToEnum() found %s", table[i].name); 39915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return table[i].value; 39925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 39945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return 0; 39955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 39965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 399718fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivibool AudioPolicyManagerBase::stringToBool(const char *value) 399818fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi{ 399918fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0)); 400018fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi} 400118fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi 40020977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurentaudio_output_flags_t AudioPolicyManagerBase::parseFlagNames(char *name) 40035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 40045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t flag = 0; 40055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 40065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // it is OK to cast name to non const here as we are not going to use it after 40075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent // strtok() modifies it 40085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *flagName = strtok(name, "|"); 40095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (flagName != NULL) { 40105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strlen(flagName) != 0) { 40115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flag |= stringToEnum(sFlagNameToEnumTable, 40125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sFlagNameToEnumTable), 40135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flagName); 40145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 40155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent flagName = strtok(NULL, "|"); 40165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 4017a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald //force direct flag if offload flag is set: offloading implies a direct output stream 4018a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // and all common behaviors are driven by checking only the direct flag 4019a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald // this should normally be set appropriately in the policy configuration file 4020a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 4021a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald flag |= AUDIO_OUTPUT_FLAG_DIRECT; 4022a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald } 4023a527ffd3c2ce72048a8fae51cd399024af4439b9Richard Fitzgerald 40240977cf534ffb71c2abac622716510ae8ea25f3e9Eric Laurent return (audio_output_flags_t)flag; 40255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 40265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 40275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentaudio_devices_t AudioPolicyManagerBase::parseDeviceNames(char *name) 40285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 40295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t device = 0; 40305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 40315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *devName = strtok(name, "|"); 40325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (devName != NULL) { 40335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strlen(devName) != 0) { 40345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent device |= stringToEnum(sDeviceNameToEnumTable, 40355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 40365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devName); 40375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 40385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent devName = strtok(NULL, "|"); 40395ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 4040c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi return device; 40415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 40425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 40435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadSamplingRates(char *name, IOProfile *profile) 40445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 40455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *str = strtok(name, "|"); 40465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 40473cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling 40483cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // rates should be read from the output stream after it is opened for the first time 40493cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 40503cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent profile->mSamplingRates.add(0); 40513cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 40523cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 40533cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 40545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 40555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent uint32_t rate = atoi(str); 40565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (rate != 0) { 40575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadSamplingRates() adding rate %d", rate); 40585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSamplingRates.add(rate); 40595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 40605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 40615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 40625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 40635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 40645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 40655ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadFormats(char *name, IOProfile *profile) 40665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 40675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *str = strtok(name, "|"); 40685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 40693cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mFormats indicates the supported formats 40703cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // should be read from the output stream after it is opened for the first time 40713cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 40722d749b0bda4ae60ef1a940eeba86121b2e94d07dGlenn Kasten profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 40733cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 40743cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 40753cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 40765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 40775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable, 40785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 40795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str); 40802d749b0bda4ae60ef1a940eeba86121b2e94d07dGlenn Kasten if (format != AUDIO_FORMAT_DEFAULT) { 40815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mFormats.add(format); 40825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 40835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 40845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 40855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 40865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 40875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 40885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadInChannels(char *name, IOProfile *profile) 40895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 40905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *str = strtok(name, "|"); 40915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 40925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInChannels() %s", name); 40933cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 40943cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 40952c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten profile->mChannelMasks.add(0); 40963cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 40973cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 40983cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 40995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 41005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent audio_channel_mask_t channelMask = 41015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 41025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 41035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str); 41045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (channelMask != 0) { 41055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadInChannels() adding channelMask %04x", channelMask); 41065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mChannelMasks.add(channelMask); 41075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 41085ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 41095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 41105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 41115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 41125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 41135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadOutChannels(char *name, IOProfile *profile) 41145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 41155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent const char *str = strtok(name, "|"); 41163cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 41173cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ALOGV("loadOutChannels() %s", name); 41183cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent 41193cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // by convention, "0' in the first entry in mChannelMasks indicates the supported channel 41203cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent // masks should be read from the output stream after it is opened for the first time 41213cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 41222c3d2379ee6eadb32b63bf6de538cfd6487e8e20Glenn Kasten profile->mChannelMasks.add(0); 41233cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent return; 41243cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent } 41255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 41265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (str != NULL) { 41273cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent audio_channel_mask_t channelMask = 41283cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 41293cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 41303cdfddf1b27bcb5408ca3a04fcdf206447ba07baEric Laurent str); 41315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (channelMask != 0) { 41325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mChannelMasks.add(channelMask); 41335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 41345ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent str = strtok(NULL, "|"); 41355ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 41365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 41375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 41385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 413970c236c9290732782d5267935af1475b8d5ae602Eric Laurentstatus_t AudioPolicyManagerBase::loadInput(cnode *root, HwModule *module) 41405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 41415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = root->first_child; 41425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 41435ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = new IOProfile(module); 41445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 41455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 41465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 41475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadSamplingRates((char *)node->value, profile); 41485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 41495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadFormats((char *)node->value, profile); 41505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 41515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadInChannels((char *)node->value, profile); 41525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 41535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices = parseDeviceNames((char *)node->value); 41545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 41555ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 41565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 4157ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(profile->mSupportedDevices == AUDIO_DEVICE_NONE, 41585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported devices"); 41595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 41605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported channel masks"); 41615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 41625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported sampling rates"); 41635ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 41645ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadInput() invalid supported formats"); 4165ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((profile->mSupportedDevices != AUDIO_DEVICE_NONE) && 41665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mChannelMasks.size() != 0) && 41675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mSamplingRates.size() != 0) && 41685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mFormats.size() != 0)) { 41695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 4170fd61179b6483f1c6360968d0f9f7695ea6f380a7Paul McLean ALOGV("loadInput() adding input mSupportedDevices 0x%X", profile->mSupportedDevices); 41715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 417270c236c9290732782d5267935af1475b8d5ae602Eric Laurent module->mInputProfiles.add(profile); 41735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 41745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 41755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent delete profile; 41765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return BAD_VALUE; 41775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 41785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 41795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 418070c236c9290732782d5267935af1475b8d5ae602Eric Laurentstatus_t AudioPolicyManagerBase::loadOutput(cnode *root, HwModule *module) 41815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 41825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = root->first_child; 41835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 41845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent IOProfile *profile = new IOProfile(module); 41855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 41865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 41875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 41885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadSamplingRates((char *)node->value, profile); 41895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 41905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadFormats((char *)node->value, profile); 41915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 41925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadOutChannels((char *)node->value, profile); 41935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 41945ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices = parseDeviceNames((char *)node->value); 41955ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(node->name, FLAGS_TAG) == 0) { 41965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mFlags = parseFlagNames((char *)node->value); 41975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 41985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 41995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 4200ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(profile->mSupportedDevices == AUDIO_DEVICE_NONE, 42015ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported devices"); 42025ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 42035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported channel masks"); 42045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 42055ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported sampling rates"); 42065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 42075ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent "loadOutput() invalid supported formats"); 4208ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent if ((profile->mSupportedDevices != AUDIO_DEVICE_NONE) && 42095ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mChannelMasks.size() != 0) && 42105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mSamplingRates.size() != 0) && 42115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (profile->mFormats.size() != 0)) { 42125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 42135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadOutput() adding output mSupportedDevices %04x, mFlags %04x", 42145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent profile->mSupportedDevices, profile->mFlags); 42155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 421670c236c9290732782d5267935af1475b8d5ae602Eric Laurent module->mOutputProfiles.add(profile); 42175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 42185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else { 42195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent delete profile; 42205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return BAD_VALUE; 42215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 42225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 42235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 42245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadHwModule(cnode *root) 42255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 42265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, OUTPUTS_TAG); 42275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status_t status = NAME_NOT_FOUND; 422870c236c9290732782d5267935af1475b8d5ae602Eric Laurent 422970c236c9290732782d5267935af1475b8d5ae602Eric Laurent HwModule *module = new HwModule(root->name); 423070c236c9290732782d5267935af1475b8d5ae602Eric Laurent 42315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node != NULL) { 42325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_A2DP) == 0) { 42335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mHasA2dp = true; 4234599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent } else if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_USB) == 0) { 4235599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent mHasUsb = true; 423648387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi } else if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX) == 0) { 423748387b28c87327c6c4d512eabe091c29236d2e70Jean-Michel Trivi mHasRemoteSubmix = true; 42385ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 4239599a1fc11596ac669499c1caf87c6ceddd0bfee4Eric Laurent 42405ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 42415ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 42425ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModule() loading output %s", node->name); 424370c236c9290732782d5267935af1475b8d5ae602Eric Laurent status_t tmpStatus = loadOutput(node, module); 42445ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 42455ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status = tmpStatus; 42465ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 42475ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 42485ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 42495ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 42505ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = config_find(root, INPUTS_TAG); 42515ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node != NULL) { 42525ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 42535ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 42545ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModule() loading input %s", node->name); 425570c236c9290732782d5267935af1475b8d5ae602Eric Laurent status_t tmpStatus = loadInput(node, module); 42565ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 42575ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent status = tmpStatus; 42585ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 42595ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 42605ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 42615ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 42625ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (status == NO_ERROR) { 426370c236c9290732782d5267935af1475b8d5ae602Eric Laurent mHwModules.add(module); 426470c236c9290732782d5267935af1475b8d5ae602Eric Laurent } else { 426570c236c9290732782d5267935af1475b8d5ae602Eric Laurent delete module; 42665ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 42675ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 42685ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 42695ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadHwModules(cnode *root) 42705ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 42715ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); 42725ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node == NULL) { 42735ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 42745ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 42755ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 42765ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 42775ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 42785ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadHwModules() loading module %s", node->name); 42795ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadHwModule(node); 42805ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 42815ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 42825ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 42835ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 42845ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentvoid AudioPolicyManagerBase::loadGlobalConfig(cnode *root) 42855ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 42865ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *node = config_find(root, GLOBAL_CONFIG_TAG); 42875ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (node == NULL) { 42885ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return; 42895ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 42905ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->first_child; 42915ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent while (node) { 42925ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { 42935ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mAttachedOutputDevices = parseDeviceNames((char *)node->value); 4294ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(mAttachedOutputDevices == AUDIO_DEVICE_NONE, 4295c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi "loadGlobalConfig() no attached output devices"); 42965ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mAttachedOutputDevices %04x", mAttachedOutputDevices); 42975ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { 42985ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent mDefaultOutputDevice = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable, 42995ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 43005ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent (char *)node->value); 4301ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent ALOGW_IF(mDefaultOutputDevice == AUDIO_DEVICE_NONE, 4302c8101f5b14e745b348592c5609e55f121a11a6bfJean-Michel Trivi "loadGlobalConfig() default device not specified"); 43035ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mDefaultOutputDevice %04x", mDefaultOutputDevice); 43045ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { 4305ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableInputDevices = parseDeviceNames((char *)node->value) & ~AUDIO_DEVICE_BIT_IN; 43065ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent ALOGV("loadGlobalConfig() mAvailableInputDevices %04x", mAvailableInputDevices); 430718fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) { 430818fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi mSpeakerDrcEnabled = stringToBool((char *)node->value); 430918fc094c0ed41851be3d746423c6695dd28d48e1Jean-Michel Trivi ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled); 43105ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 43115ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent node = node->next; 43125ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 43135ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 43145ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 43155ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurentstatus_t AudioPolicyManagerBase::loadAudioPolicyConfig(const char *path) 43165ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent{ 43175ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent cnode *root; 43185ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent char *data; 43195ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 43205ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent data = (char *)load_file(path, NULL); 43215ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent if (data == NULL) { 43225ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return -ENODEV; 43235ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent } 43245ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent root = config_node("", ""); 43255ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent config_load(root, data); 43265ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 43275ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadGlobalConfig(root); 43285ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent loadHwModules(root); 43295ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 43305ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent config_free(root); 43315ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent free(root); 43325ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent free(data); 43335ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent 43345ec145df7708564d385fd3fb764085321cf4c253Dima Zavin ALOGI("loadAudioPolicyConfig() loaded %s\n", path); 43355ec145df7708564d385fd3fb764085321cf4c253Dima Zavin 43365ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent return NO_ERROR; 43375ccdf14a85ed66ac54036fb393acc06ea7acfed6Eric Laurent} 4338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4339739022f26a7127ba76a98dda65411496086114a7Dima Zavinvoid AudioPolicyManagerBase::defaultAudioPolicyConfig(void) 4340739022f26a7127ba76a98dda65411496086114a7Dima Zavin{ 4341739022f26a7127ba76a98dda65411496086114a7Dima Zavin HwModule *module; 4342739022f26a7127ba76a98dda65411496086114a7Dima Zavin IOProfile *profile; 4343739022f26a7127ba76a98dda65411496086114a7Dima Zavin 4344739022f26a7127ba76a98dda65411496086114a7Dima Zavin mDefaultOutputDevice = AUDIO_DEVICE_OUT_SPEAKER; 4345739022f26a7127ba76a98dda65411496086114a7Dima Zavin mAttachedOutputDevices = AUDIO_DEVICE_OUT_SPEAKER; 4346ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent mAvailableInputDevices = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; 4347739022f26a7127ba76a98dda65411496086114a7Dima Zavin 4348739022f26a7127ba76a98dda65411496086114a7Dima Zavin module = new HwModule("primary"); 4349739022f26a7127ba76a98dda65411496086114a7Dima Zavin 4350739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile = new IOProfile(module); 4351739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSamplingRates.add(44100); 4352739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 4353739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO); 4354739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSupportedDevices = AUDIO_DEVICE_OUT_SPEAKER; 4355739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY; 4356739022f26a7127ba76a98dda65411496086114a7Dima Zavin module->mOutputProfiles.add(profile); 4357739022f26a7127ba76a98dda65411496086114a7Dima Zavin 4358739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile = new IOProfile(module); 4359739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSamplingRates.add(8000); 4360739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 4361739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO); 4362739022f26a7127ba76a98dda65411496086114a7Dima Zavin profile->mSupportedDevices = AUDIO_DEVICE_IN_BUILTIN_MIC; 4363739022f26a7127ba76a98dda65411496086114a7Dima Zavin module->mInputProfiles.add(profile); 4364739022f26a7127ba76a98dda65411496086114a7Dima Zavin 4365739022f26a7127ba76a98dda65411496086114a7Dima Zavin mHwModules.add(module); 4366739022f26a7127ba76a98dda65411496086114a7Dima Zavin} 4367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 4368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin}; // namespace android 4369