AudioPolicyManagerBase.cpp revision 12bd6e4a5c26bd8035bf804d0cc821bd9b8cce9b
1f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin/* 2f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * Copyright (C) 2009 The Android Open Source Project 3f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * 4f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * Licensed under the Apache License, Version 2.0 (the "License"); 5f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * you may not use this file except in compliance with the License. 6f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * You may obtain a copy of the License at 7f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * 8f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * http://www.apache.org/licenses/LICENSE-2.0 9f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * 10f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * Unless required by applicable law or agreed to in writing, software 11f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * distributed under the License is distributed on an "AS IS" BASIS, 12f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * See the License for the specific language governing permissions and 14f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin * limitations under the License. 15f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin */ 16f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 17f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#define LOG_TAG "AudioPolicyManagerBase" 18f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin//#define LOG_NDEBUG 0 19f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <utils/Log.h> 20f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <hardware_legacy/AudioPolicyManagerBase.h> 211c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent#include <hardware/audio_effect.h> 2208b014d9e509c9163db6b33a63852e73db4d07ccEric Laurent#include <hardware/audio.h> 23f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#include <math.h> 24f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 25e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinnamespace android_audio_legacy { 26f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 27f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 28f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyInterface implementation 29f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 30f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 31b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent//////////////////// 32b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent// TODO: the following static configuration will be read from a configuration file 33b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 34b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 35b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent// sHasA2dp is true on platforms with support for bluetooth A2DP 36b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentbool sHasA2dp = true; 37b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 38b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent// devices that are always available on the platform 39b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_devices_t sAttachedOutputDevices = 40b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (audio_devices_t)(AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER); 41b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 42b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent// device selected by default at boot time must be in sAttachedOutputDevices 43b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_devices_t sDefaultOutputDevice = AUDIO_DEVICE_OUT_SPEAKER; 44b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 45b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentuint32_t sSamplingRates[] = {44100, 0}; 46b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_channel_mask_t sChannels[] = {AUDIO_CHANNEL_OUT_STEREO, (audio_channel_mask_t)0}; 47b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_format_t sFormats[] = {AUDIO_FORMAT_PCM_16_BIT, (audio_format_t)0}; 48b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 49b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent// the primary output (identified by AUDIO_POLICY_OUTPUT_FLAG_PRIMARY in its profile) must exist and 50b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent// is unique on a platform. It is the output receiving the routing and volume commands for telephony 51b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent// use cases. It is normally exposed by the primary audio hw module and opened at boot time by 52b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent// the audio policy manager. 53b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentconst output_profile_t sPrimaryOutput = { 54b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent sSamplingRates, 55b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent sChannels, 56b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent sFormats, 57b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (audio_devices_t)(AUDIO_DEVICE_OUT_EARPIECE | 58b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AUDIO_DEVICE_OUT_SPEAKER | 59b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADSET | 60b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADPHONE | 61b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AUDIO_DEVICE_OUT_ALL_SCO | 62b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AUDIO_DEVICE_OUT_AUX_DIGITAL | 63b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET), 64b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AUDIO_POLICY_OUTPUT_FLAG_PRIMARY 65b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent}; 66b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 67b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentconst output_profile_t sA2dpOutput = { 68b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent sSamplingRates, 69b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent sChannels, 70b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent sFormats, 71b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AUDIO_DEVICE_OUT_ALL_A2DP, 72b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (audio_policy_output_flags_t)0 73b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent}; 74b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 75b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentconst output_profile_t *sAvailableOutputs[] = { 76b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &sPrimaryOutput, 77b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &sA2dpOutput, 78b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent NULL 79b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent}; 80b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 81b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent///////////// end of temporary static configuration data 82b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 83f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 84f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_devices device, 85f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state, 86f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 87f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 88b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t output = 0; 89f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 906a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); 91f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 92f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // connect/disconnect only 1 device at a time 93f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::popCount(device) != 1) return BAD_VALUE; 94f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 95f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { 965efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid address: %s", device_address); 97f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 98f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 99f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output devices 101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isOutputDevice(device)) { 102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 103b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!sHasA2dp && AudioSystem::isA2dpDevice(device)) { 1045efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid device: %x", device); 105f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 106f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 107f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 108f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 109f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 110f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device connection 111f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: 112f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableOutputDevices & device) { 11364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %x", device); 114f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 115f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1166a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() connecting device %x", device); 117f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 118f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // register new device as available 119f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device); 120f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 121f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent output = checkOutputForDevice((audio_devices_t)device, state); 122b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (output == 0) { 123f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device); 124b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return INVALID_OPERATION; 125b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 126f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle A2DP device connection 127b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (sHasA2dp && AudioSystem::isA2dpDevice(device)) { 128b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioParameter param; 12908b014d9e509c9163db6b33a63852e73db4d07ccEric Laurent param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), String8(device_address)); 130b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(output, param.toString()); 131b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 132b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpSuspended = false; 133b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else if (AudioSystem::isBluetoothScoDevice(device)) { 134b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("setDeviceConnectionState() BT SCO device, address %s", device_address); 135b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // keep track of SCO device address 136b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); 137f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 138f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 139f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle output device disconnection 140f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 141f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableOutputDevices & device)) { 14264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %x", device); 143f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 144f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 145f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 146f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1476a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() disconnecting device %x", device); 148f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // remove device from available output devices 149f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device); 150f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 151f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent output = checkOutputForDevice((audio_devices_t)device, state); 152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle A2DP device disconnection 153b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (sHasA2dp && AudioSystem::isA2dpDevice(device)) { 154b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpDeviceAddress = ""; 155b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mA2dpSuspended = false; 156b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else if (AudioSystem::isBluetoothScoDevice(device)) { 157b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mScoDeviceAddress = ""; 158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 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 // request routing change if necessary 167f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t newDevice = getNewDevice(mPrimaryOutput, false); 168b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 171b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // outputs must be closed after checkOutputForAllStrategies() is executed 172b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && output != 0) { 173b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent closeOutput(output); 174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 176b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setOutputDevice(mPrimaryOutput, newDevice); 177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 178f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 179f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_WIRED_HEADSET; 180f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO || 181f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET || 182f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 183f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; 184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input devices 189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isInputDevice(device)) { 190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (state) 192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device connection 194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_AVAILABLE: { 195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mAvailableInputDevices & device) { 19664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device already connected: %d", device); 197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 198f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableInputDevices |= device; 200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle input device disconnection 204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DEVICE_STATE_UNAVAILABLE: { 205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!(mAvailableInputDevices & device)) { 20664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() device not connected: %d", device); 207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableInputDevices &= ~device; 210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 211f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 2135efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("setDeviceConnectionState() invalid state: %x", state); 214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 215f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 219f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 220f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (newDevice != inputDesc->mDevice) { 2226a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setDeviceConnectionState() changing device from %x to %x for input %d", 223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 23464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setDeviceConnectionState() invalid device: %x", device); 235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(AudioSystem::audio_devices device, 239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const char *device_address) 240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE; 242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 address = String8(device_address); 243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isOutputDevice(device)) { 244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableOutputDevices) { 245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isA2dpDevice(device) && 246b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (!sHasA2dp || (address != "" && mA2dpDeviceAddress != address))) { 247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isBluetoothScoDevice(device) && 250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin address != "" && mScoDeviceAddress != address) { 251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (AudioSystem::isInputDevice(device)) { 256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device & mAvailableInputDevices) { 257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin state = AudioSystem::DEVICE_STATE_AVAILABLE; 258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return state; 262f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 263f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 264f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setPhoneState(int state) 265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2666a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() state %d", state); 267f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t newDevice = (audio_devices_t)0; 268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state < 0 || state >= AudioSystem::NUM_MODES) { 26964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() invalid state %d", state); 270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 271f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == mPhoneState ) { 27464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setPhoneState() setting same state %d", state); 275f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 277f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if leaving call state, handle special case of active streams 279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 2816a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 283f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, true); 284f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store previous phone state for management of sonification strategy below 288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int oldState = mPhoneState; 289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mPhoneState = state; 290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool force = false; 291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // are we entering or starting a call 293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isStateInCall(oldState) && isStateInCall(state)) { 2946a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Entering call in setPhoneState()"); 295f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when starting a call 296f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 297f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(oldState) && !isStateInCall(state)) { 2996a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Exiting call in setPhoneState()"); 300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when exiting a call 301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (isStateInCall(state) && (state != oldState)) { 3046a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when switching between telephony and VoIP 306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force = true; 308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check for device and output changes triggered by new phone state 311b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent newDevice = getNewDevice(mPrimaryOutput, false); 312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 316b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // force routing command to audio hardware when ending call 319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // even if no device change is needed 320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(oldState) && newDevice == 0) { 321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin newDevice = hwOutputDesc->device(); 322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when changing from ring tone to in call mode, mute the ringing tone 325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // immediately and delay the route change to avoid sending the ring tone 326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // tail into the earpiece or headset. 327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int delayMs = 0; 328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) { 329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // delay the device change command by twice the output latency to have some margin 330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and be sure that audio buffers not yet affected by the mute are out when 331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // we actually apply the route change 332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delayMs = hwOutputDesc->mLatency*2; 333b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(AudioSystem::RING, true, mPrimaryOutput); 334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // change routing is necessary 337b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setOutputDevice(mPrimaryOutput, newDevice, force, delayMs); 338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if entering in call state, handle special case of active streams 340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // pertaining to sonification strategy see handleIncallSonification() 341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isStateInCall(state)) { 3426a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setPhoneState() in call state management: new state is %d", state); 343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // unmute the ringing tone after a sufficient delay if it was muted before 344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // setting output device above 345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (oldState == AudioSystem::MODE_RINGTONE) { 346b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(AudioSystem::RING, false, mPrimaryOutput, MUTE_TIME_MS); 347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, true, true); 350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 353f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 354f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (state == AudioSystem::MODE_RINGTONE && 355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = true; 357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume = false; 359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 361f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 362f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) 363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 3646a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin bool forceVolumeReeval = false; 367f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(usage) { 368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_COMMUNICATION: 369f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO && 370f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 37164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 372f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 373f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_MEDIA: 378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP && 379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 381f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE) { 38264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_RECORD: 388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY && 389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_NONE) { 39064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FOR_DOCK: 396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK && 397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_BT_DESK_DOCK && 398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_WIRED_ACCESSORY && 399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_ANALOG_DOCK && 400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin config != AudioSystem::FORCE_DIGITAL_DOCK) { 40164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 402f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin forceVolumeReeval = true; 404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[usage] = config; 405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 40764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setForceUse() invalid usage %d", usage); 408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check for device and output changes triggered by new phone state 412f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t newDevice = getNewDevice(mPrimaryOutput, false); 413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkA2dpSuspend(); 414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForAllStrategies(); 415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 416b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setOutputDevice(mPrimaryOutput, newDevice); 417f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (forceVolumeReeval) { 418b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent applyStreamVolumes(mPrimaryOutput, newDevice, 0, true); 419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 420f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 421f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t activeInput = getActiveInput(); 422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (activeInput != 0) { 423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin newDevice = getDeviceForInputSource(inputDesc->mInputSource); 425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (newDevice != inputDesc->mDevice) { 4266a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setForceUse() changing device from %x to %x for input %d", 427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice, newDevice, activeInput); 428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = newDevice; 429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(activeInput, param.toString()); 432f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 434f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 435f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 436f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 437f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage) 438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mForceUse[usage]; 440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setSystemProperty(const char* property, const char* value) 443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 4446a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setSystemProperty() property %s, value %s", property, value); 445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (strcmp(property, "ro.camera.sound.forced") == 0) { 446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (atoi(value)) { 4476a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("ENFORCED_AUDIBLE cannot be muted"); 448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false; 449f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 4506a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("ENFORCED_AUDIBLE can be muted"); 451f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true; 452f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 453f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 454f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 455f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream, 457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t channels, 460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::output_flags flags) 461f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 462f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t output = 0; 463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t latency = 0; 464f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); 465f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy); 4666a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() stream %d, samplingRate %d, format %d, channels %x, flags %x", stream, samplingRate, format, channels, flags); 467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mCurOutput != 0) { 4706a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channels %x, mDirectOutput %d", 471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput] == 0) { 4746a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() opening test output"); 475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(); 476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = mTestDevice; 477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = mTestSamplingRate; 478f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFormat = mTestFormat; 479f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mChannels = mTestChannels; 480f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = mTestLatencyMs; 481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags = (AudioSystem::output_flags)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0); 482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 483f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[mCurOutput] = mpClientInterface->openOutput(&outputDesc->mDevice, 484f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 485f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mChannels, 487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestOutputs[mCurOutput]) { 490f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"),mCurOutput); 492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(mTestOutputs[mCurOutput], outputDesc); 494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 495f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mTestOutputs[mCurOutput]; 497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 498f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 499f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a direct output if required by specified parameters 501f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (needsDirectOuput(stream, samplingRate, format, channels, flags, device)) { 502f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 5036a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() opening direct output device %x", device); 504b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = device; 506f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate = samplingRate; 507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFormat = format; 508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mChannels = channels; 509f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mLatency = 0; 510f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT); 511f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mRefCount[stream] = 0; 512f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mStopTime[stream] = 0; 513f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent output = mpClientInterface->openOutput((uint32_t *)&outputDesc->mDevice, 514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 515f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 516f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mChannels, 517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 518f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 519f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 520f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // only accept an output with the requeted parameters 521f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == 0 || 522f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || 523f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != 0 && format != outputDesc->mFormat) || 524f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (channels != 0 && channels != outputDesc->mChannels)) { 5256a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutput() failed opening direct output: samplingRate %d, format %d, channels %d", 526f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin samplingRate, format, channels); 527f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output != 0) { 528f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 529f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 530f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete outputDesc; 531f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 532f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 533f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin addOutput(output, outputDesc); 534f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 535f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 536f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 537f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO && 538f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels != AudioSystem::CHANNEL_OUT_STEREO) { 539f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 540f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 541f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // open a non direct output 542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // get which output is suitable for the specified stream. The actual routing change will happen 544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when startOutput() will be called 545b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device); 546b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // TODO: current implementation assumes that at most one output corresponds to a device. 547b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // this will change when supporting low power, low latency or tunneled output streams 54812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // FIXME broken with A2DP + no wired headset 54912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi //ALOG_ASSERT(outputs.size() < 2, "getOutput(): getOutputsForDevice() " 55012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // "returned %d outputs for device %04x", outputs.size(), device); 551f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 552b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent output = outputs[0]; 553f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 55464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d, format %d, channels %x, flags %x", 555f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, samplingRate, format, channels, flags); 556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 557f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return output; 558f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 559f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, 561f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 562f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 563f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 5646a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 565f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 566f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 56764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startOutput() unknow output %d", output); 568f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 569f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 570f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 571f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 572f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 573f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // incremenent usage count for this stream on the requested output: 574f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE that the usage count is the same for duplicated output and hardware output which is 575f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // necassary for a correct control of hardware output routing by startOutput() and stopOutput() 576f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, 1); 577f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 578f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t prevDevice = outputDesc->device(); 579f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(output, getNewDevice(output)); 580f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t newDevice = outputDesc->device(); 581f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 582f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle special case for sonification while in call 583f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 584f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, true, false); 585f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 586f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 587f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // apply volume rules for current stream and device if necessary 588c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 589c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].getVolumeIndex((audio_devices_t)newDevice), 590c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 591c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent newDevice); 592f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 593c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // FIXME: need a delay to make sure that audio path switches to speaker before sound 594c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // starts. Should be platform specific? 595c16ac09f510437e8340be691720177a490ae78f0Eric Laurent if (stream == AudioSystem::ENFORCED_AUDIBLE && 596c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent prevDevice != newDevice) { 597c16ac09f510437e8340be691720177a490ae78f0Eric Laurent usleep(outputDesc->mLatency*4*1000); 598c16ac09f510437e8340be691720177a490ae78f0Eric Laurent } 599c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 60012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // update the outputs if starting an output with a stream that can affect notification routing 60112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi handleNotificationRoutingForStream(stream); 60212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 603f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 604f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 605f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, 607f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream, 608f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session) 609f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 6106a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 611f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 612f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 61364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() unknow output %d", output); 614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 616f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 617f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 618f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 619f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handle special case for sonification while in call 620f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 621f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin handleIncallSonification(stream, false, false); 622f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 623f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 624f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream] > 0) { 625f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // decrement usage count of this stream on the output 626f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->changeRefCount(stream, -1); 627f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // store time at which the stream was stopped - see isStreamActive() 628f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mStopTime[stream] = systemTime(); 629f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(output, getNewDevice(output), false, outputDesc->mLatency*2); 631f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 632b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (output != mPrimaryOutput) { 633b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setOutputDevice(mPrimaryOutput, getNewDevice(mPrimaryOutput), true); 634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 63512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 63612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // update the outputs if stopping one with a stream that can affect notification routing 63712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi handleNotificationRoutingForStream(stream); 63812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 639f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 640f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 64164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopOutput() refcount is already 0 for output %d", output); 642f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 643f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 644f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 645f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 646f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output) 647f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 6486a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseOutput() %d", output); 649f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mOutputs.indexOfKey(output); 650f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 65164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseOutput() releasing unknown output %d", output); 652f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 653f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 654f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 655f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 656f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int testIndex = testOutputIndex(output); 657f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (testIndex != 0) { 658f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 659f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->refCount() == 0) { 660f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(index); 662f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(output); 663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[testIndex] = 0; 664f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 665f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 666f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 667f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 668f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 669f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) { 670f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(output); 671f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(index); 672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.removeItem(output); 673f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 67412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 675f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 676f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource, 678f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 679f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 680f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t channels, 681f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::audio_in_acoustics acoustics) 682f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 683f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin audio_io_handle_t input = 0; 684f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device = getDeviceForInputSource(inputSource); 685f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 6866a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x", inputSource, samplingRate, format, channels, acoustics); 687f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 688f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 689f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 690f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // adapt channel selection to input source 693f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(inputSource) { 694f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 695f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_IN_VOICE_UPLINK; 696f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 697f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 698f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_IN_VOICE_DNLINK; 699f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 700f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 701f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK); 702f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 703f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 704f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 705f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 706f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 707f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = new AudioInputDescriptor(); 708f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 709f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mInputSource = inputSource; 710f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mDevice = device; 711f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mSamplingRate = samplingRate; 712f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mFormat = format; 713f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mChannels = channels; 714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mAcoustics = acoustics; 715f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 716f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent input = mpClientInterface->openInput((uint32_t *)&inputDesc->mDevice, 717f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mSamplingRate, 718f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mFormat, 719f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &inputDesc->mChannels, 72070eb9dec508c3269a0792e362ab34ffb3b29976cGlenn Kasten (audio_in_acoustics_t) inputDesc->mAcoustics); 721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 722f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // only accept input with the exact requested set of parameters 723f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input == 0 || 724f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (samplingRate != inputDesc->mSamplingRate) || 725f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (format != inputDesc->mFormat) || 726f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (channels != inputDesc->mChannels)) { 7276a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getInput() failed opening input: samplingRate %d, format %d, channels %d", 728f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin samplingRate, format, channels); 729f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (input != 0) { 730f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 731f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 732f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete inputDesc; 733f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 734f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 735f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.add(input, inputDesc); 736f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return input; 737f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 738f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 739f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::startInput(audio_io_handle_t input) 740f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7416a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("startInput() input %d", input); 742f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 743f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 74464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startInput() unknow input %d", input); 745f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 746f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 747f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 748f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 749f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 750f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTestInput == 0) 751f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 752f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 753f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // refuse 2 active AudioRecord clients at the same time 754f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getActiveInput() != 0) { 75564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("startInput() input %d failed: other input already started", input); 756f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 760f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 761f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice); 762f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource); 7646a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 766f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 767f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 768f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 1; 769f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 770f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 772f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::stopInput(audio_io_handle_t input) 773f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7746a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("stopInput() input %d", input); 775f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 776f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 77764cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() unknow input %d", input); 778f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 779f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 782f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (inputDesc->mRefCount == 0) { 78364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("stopInput() input %d already stopped", input); 784f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 785f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), 0); 788f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(input, param.toString()); 789f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin inputDesc->mRefCount = 0; 790f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 791f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 792f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 793f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 794f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::releaseInput(audio_io_handle_t input) 795f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 7966a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() %d", input); 797f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mInputs.indexOfKey(input); 798f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 79964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("releaseInput() releasing unknown input %d", input); 800f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 801f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 802f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(input); 803f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(index); 804f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.removeItem(input); 8056a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("releaseInput() exit"); 806f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 807f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 808f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream, 809f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMin, 810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int indexMax) 811f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8126a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 813f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (indexMin < 0 || indexMin >= indexMax) { 81464cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 815f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 816f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMin = indexMin; 818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStreams[stream].mIndexMax = indexMax; 819f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 820f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 821c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, 822c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 823c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 824f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 825f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 826f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 827f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 828f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 829c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 830c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 831c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 832f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 833f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force max volume if stream cannot be muted 834f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 835f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 836b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", 837c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent stream, device, index); 838c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 839c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 840c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // clear all device specific values 841c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 842c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.clear(); 843c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 844c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // compute and apply stream volume on all outputs according to connected device 847f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin status_t status = NO_ERROR; 848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 849c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent audio_devices_t curDevice = 850c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent getDeviceForVolume((audio_devices_t)mOutputs.valueAt(i)->device()); 851c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent if (device == curDevice) { 852c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); 853c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent if (volStatus != NO_ERROR) { 854c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent status = volStatus; 855c5eb8b4a5d4395ce335bc7c3e6df2678fa47e2ddEric Laurent } 856f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 857f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 858f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return status; 859f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 860f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 861c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, 862c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int *index, 863c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_devices_t device) 864f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 865c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (index == NULL) { 866f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return BAD_VALUE; 867f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 868c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (!audio_is_output_device(device)) { 869c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return BAD_VALUE; 870c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 871c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 872c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // the strategy the stream belongs to. 873c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 874c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = (audio_devices_t)getDeviceForStrategy(getStrategy(stream), true); 875c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 876c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = getDeviceForVolume(device); 877c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 878c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 879c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 880f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 881f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 882f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 883f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(effect_descriptor_t *desc) 884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8856a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getOutputForEffect()"); 886f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // apply simple rule where global effects are attached to the same output as MUSIC streams 887f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return getOutput(AudioSystem::MUSIC); 888f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 889f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 890f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::registerEffect(effect_descriptor_t *desc, 8911c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent audio_io_handle_t io, 892f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t strategy, 893f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int session, 894f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int id) 895f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 8961c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 897f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 8981c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent index = mInputs.indexOfKey(io); 8991c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent if (index < 0) { 90064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() unknown io %d", io); 9011c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent return INVALID_OPERATION; 9021c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent } 903f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 904f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 905f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 90664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin desc->name, desc->memoryUsage); 908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 910f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory += desc->memoryUsage; 9116a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 9121c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent desc->name, io, strategy, session, id); 9136a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 914f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 915f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = new EffectDescriptor(); 916f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t)); 9171c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent pDesc->mIo = io; 918f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mStrategy = (routing_strategy)strategy; 919f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mSession = session; 920582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = false; 921582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 922f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.add(id, pDesc); 923f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 924f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 925f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 926f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::unregisterEffect(int id) 928f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 929f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ssize_t index = mEffects.indexOfKey(id); 930f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (index < 0) { 93164cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 932f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 933f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 934f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 935f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *pDesc = mEffects.valueAt(index); 936f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 937582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent setEffectEnabled(pDesc, false); 938582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 939f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) { 94064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() memory %d too big for total %d", 941f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin pDesc->mDesc.memoryUsage = mTotalEffectsMemory; 943f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 944f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsMemory -= pDesc->mDesc.memoryUsage; 9456a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 946582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 947f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 948f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.removeItem(id); 949f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete pDesc; 950f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 951f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 952f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 953f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 954582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(int id, bool enabled) 955582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 956582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent ssize_t index = mEffects.indexOfKey(id); 957582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (index < 0) { 95864cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("unregisterEffect() unknown effect ID %d", id); 959582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 960582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 961582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 962582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 963582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 964582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 965582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurentstatus_t AudioPolicyManagerBase::setEffectEnabled(EffectDescriptor *pDesc, bool enabled) 966582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent{ 967582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled == pDesc->mEnabled) { 9686a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(%s) effect already %s", 969582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 970582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 971582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 972582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 973582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (enabled) { 974582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 97564cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 976582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10); 977582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return INVALID_OPERATION; 978582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 979582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad; 9806a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 981582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } else { 982582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) { 98364cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 984582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 985582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 986582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 987582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad; 9886a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 989582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent } 990582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent pDesc->mEnabled = enabled; 991582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent return NO_ERROR; 992582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent} 993582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent 994f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const 995f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 996f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin nsecs_t sysTime = systemTime(); 997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueAt(i)->mRefCount[stream] != 0 || 999f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ns2ms(sysTime - mOutputs.valueAt(i)->mStopTime[stream]) < inPastMs) { 1000f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return true; 1001f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1002f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1003f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1004f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1005f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1006f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1007f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::dump(int fd) 1008f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1009f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1010f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1011f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 1012f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1013f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 1014f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1015b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1016b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent snprintf(buffer, SIZE, " Hardware Output: %d\n", mPrimaryOutput); 1017f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1018f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string()); 1019f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1020f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string()); 1021f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1022f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices); 1023f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1024f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices); 1025f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1026f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 1027f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1028f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]); 1029f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1030f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]); 1031f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1032f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]); 1033f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1034f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]); 1035f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 1036f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 1037f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1038f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nOutputs dump:\n"); 1039f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1040f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1041f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 1042f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1043f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueAt(i)->dump(fd); 1044f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1045f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1046f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nInputs dump:\n"); 1047f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1048f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1049f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 1050f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1051f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.valueAt(i)->dump(fd); 1052f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1053f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1054f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nStreams dump:\n"); 1055f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1056c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, 1057c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 1058f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1059f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 1060c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, " %02d ", i); 1061f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1062c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mStreams[i].dump(fd); 1063f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1064f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1065f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 1066f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 1067f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1068f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1069f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "Registered effects:\n"); 1070f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1071f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mEffects.size(); i++) { 1072f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 1073f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, buffer, strlen(buffer)); 1074f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mEffects.valueAt(i)->dump(fd); 1075f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1076f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1077f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1078f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 1079f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1080f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1081f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1082f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// AudioPolicyManagerBase 1083f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// ---------------------------------------------------------------------------- 1084f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1085f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface) 1086f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin : 1087f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1088f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Thread(false), 1089f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1090f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices((audio_devices_t)0), 1091ca0657a1ca087a6d474a75fcfedd6aac3901d587Glenn Kasten mPhoneState(AudioSystem::MODE_NORMAL), 1092f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 1093f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 1094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended(false) 1095f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1096f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface = clientInterface; 1097f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1098f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) { 1099f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mForceUse[i] = AudioSystem::FORCE_NONE; 1100f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1101f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1102f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin initializeVolumeCurves(); 1103f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1104f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpDeviceAddress = String8(""); 1105f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mScoDeviceAddress = String8(""); 1106f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1107b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // TODO read this from configuration file 1108b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent sHasA2dp = true; 1109b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent const output_profile_t **outProfile = sAvailableOutputs; 1110b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // open all output streams needed to access attached devices 1111b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent while (*outProfile) 1112b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent { 1113b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if ((*outProfile)->mSupportedDevices & sAttachedOutputDevices) { 1114b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(*outProfile); 1115b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1116f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent outputDesc->mDevice = (audio_devices_t)(sDefaultOutputDevice & (*outProfile)->mSupportedDevices); 1117b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc->mSamplingRate = (*outProfile)->mSamplingRates[0]; 1118b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc->mFormat = (*outProfile)->mFormats[0]; 1119b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc->mChannels = (*outProfile)->mChannelMasks[0]; 1120b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc->mFlags = (AudioSystem::output_flags)(*outProfile)->mFlags; 1121f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput((uint32_t *)&outputDesc->mDevice, 1122b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &outputDesc->mSamplingRate, 1123b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &outputDesc->mFormat, 1124b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &outputDesc->mChannels, 1125b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &outputDesc->mLatency, 1126b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc->mFlags); 1127b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (output == 0) { 1128b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete outputDesc; 1129b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 1130f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | ((*outProfile)->mSupportedDevices & sAttachedOutputDevices)); 1131b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if ((*outProfile)->mFlags & AUDIO_POLICY_OUTPUT_FLAG_PRIMARY) { 1132b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mPrimaryOutput = output; 1133b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1134b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent addOutput(output, outputDesc); 1135b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setOutputDevice(output, 1136f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent (audio_devices_t)(sDefaultOutputDevice & (*outProfile)->mSupportedDevices), 1137b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent true); 1138b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1139b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1140b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outProfile++; 1141f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1142f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1143b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGE_IF((sAttachedOutputDevices & ~mAvailableOutputDevices), 1144b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent "Not output found for attached devices %08x", 1145b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (sAttachedOutputDevices & ~mAvailableOutputDevices)); 1146b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1147b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 1148b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1149b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC; 1150b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1151f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin updateDeviceForStrategy(); 1152f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1153b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput != 0) { 1154f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1155f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1156b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1157f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1158f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER; 1159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = 44100; 1160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = AudioSystem::PCM_16_BIT; 1161f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = AudioSystem::CHANNEL_OUT_STEREO; 1162f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestLatencyMs = 0; 1163f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = 0; 1164f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestOutputs[i] = 0; 1167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 1170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 1171f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 1172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin run(buffer, ANDROID_PRIORITY_AUDIO); 1173f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1177f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::~AudioPolicyManagerBase() 1178f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1179f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1180f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin exit(); 1181f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1182f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mOutputs.size(); i++) { 1183f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeOutput(mOutputs.keyAt(i)); 1184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mOutputs.valueAt(i); 1185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.clear(); 1187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->closeInput(mInputs.keyAt(i)); 1189f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete mInputs.valueAt(i); 1190f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1191f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mInputs.clear(); 1192f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1193f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1194f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::initCheck() 1195f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1196b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; 1197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1198f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#ifdef AUDIO_POLICY_TEST 1200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::threadLoop() 1201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 12026a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("entering threadLoop()"); 1203f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin while (!exitPending()) 1204f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1205f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 command; 1206f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int valueInt; 1207f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 value; 1208f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin Mutex::Autolock _l(mLock); 1210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 1211f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 1213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(command); 1214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1215f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 1216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin valueInt != 0) { 12176a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("Test command %s received", command.string()); 1218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 target; 1219f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("target"), target) != NO_ERROR) { 1220f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin target = "Manager"; 1221f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1222f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 1223f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_output")); 1224f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurOutput = valueInt; 1225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 1227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_direct")); 1228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "false") { 1229f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = false; 1230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "true") { 1231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDirectOutput = true; 1232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 1235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_input")); 1236f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestInput = valueInt; 1237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 1240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_format")); 1241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int format = AudioSystem::INVALID_FORMAT; 1242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "PCM 16 bits") { 1243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_16_BIT; 1244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "PCM 8 bits") { 1245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::PCM_8_BIT; 1246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Compressed MP3") { 1247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin format = AudioSystem::MP3; 1248f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (format != AudioSystem::INVALID_FORMAT) { 1250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestFormat = format; 1252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("format"), format); 1255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 1260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_channels")); 1261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int channels = 0; 1262f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1263f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (value == "Channels Stereo") { 1264f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_STEREO; 1265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (value == "Channels Mono") { 1266f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin channels = AudioSystem::CHANNEL_OUT_MONO; 1267f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (channels != 0) { 1269f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestChannels = channels; 1271f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("channels"), channels); 1274f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1275f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1277f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 1279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_sampleRate")); 1280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (valueInt >= 0 && valueInt <= 96000) { 1281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int samplingRate = valueInt; 1282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (target == "Manager") { 1283f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mTestSamplingRate = samplingRate; 1284f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mTestOutputs[mCurOutput] != 0) { 1285f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputParam = AudioParameter(); 1286f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputParam.addInt(String8("sampling_rate"), samplingRate); 1287f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1289f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1292f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 1293f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.remove(String8("test_cmd_policy_reopen")); 1294f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1295b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(mPrimaryOutput); 1296b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(mPrimaryOutput); 1297b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(mPrimaryOutput); 1298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1299b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 1300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER; 1301b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mPrimaryOutput = mpClientInterface->openOutput(&outputDesc->mDevice, 1302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mSamplingRate, 1303f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mFormat, 1304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mChannels, 1305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin &outputDesc->mLatency, 1306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mFlags); 1307b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (mPrimaryOutput == 0) { 13085efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d", 1309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels); 1310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter outputCmd = AudioParameter(); 1312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputCmd.addInt(String8("set_id"), 0); 1313b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1314b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent addOutput(mPrimaryOutput, outputDesc); 1315f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1317f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 1320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1322f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return false; 1323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::exit() 1326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin { 1328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AutoMutex _l(mLock); 1329f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExit(); 1330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mWaitWorkCV.signal(); 1331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin requestExitAndWait(); 1333f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1334f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1335f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinint AudioPolicyManagerBase::testOutputIndex(audio_io_handle_t output) 1336f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1337f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (output == mTestOutputs[i]) return i; 1339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 1341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin#endif //AUDIO_POLICY_TEST 1343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- 1345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc) 1347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mId = id; 1349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.add(id, outputDesc); 1350f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1351f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1352f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1353b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::checkOutputForDevice( 1354f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 1355b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioSystem::device_connection_state state) 1356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1357b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t output = 0; 1358b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc; 1359b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1360b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // TODO handle multiple outputs supporting overlapping sets of devices. 1361b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1362b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (state == AudioSystem::DEVICE_STATE_AVAILABLE) { 1363b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // first check if one output already open can be routed to this device 1364b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1365b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 1366b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputDesc->mProfile && outputDesc->mProfile->mSupportedDevices & device) { 1367b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mOutputs.keyAt(i); 1368b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1369b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1370b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // then look for one available output that can be routed to this device 1371b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent const output_profile_t **outProfile = sAvailableOutputs; 1372b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent while (*outProfile) 1373b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent { 1374b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if ((*outProfile)->mSupportedDevices & device) { 1375b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent break; 1376b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1377b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outProfile++; 1378b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1379b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (*outProfile == NULL) { 1380b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGW("No output available for device %04x", device); 1381b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return output; 1382b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1383b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1384b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("opening output for device %08x", device); 1385b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc = new AudioOutputDescriptor(*outProfile); 1386b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc->mDevice = device; 1387f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent output = mpClientInterface->openOutput((uint32_t *)&outputDesc->mDevice, 1388b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &outputDesc->mSamplingRate, 1389b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &outputDesc->mFormat, 1390b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &outputDesc->mChannels, 1391b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent &outputDesc->mLatency, 1392b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc->mFlags); 1393b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1394b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (output != 0) { 1395b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t duplicatedOutput = 0; 1396b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // add output descriptor 1397b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent addOutput(output, outputDesc); 1398b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // set initial stream volume for device 1399b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent applyStreamVolumes(output, device); 1400b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1401b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent //TODO: configure audio effect output stage here 1402b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1403b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // open a duplicating output thread for the new output and the primary output 1404b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent duplicatedOutput = mpClientInterface->openDuplicateOutput(output, mPrimaryOutput); 1405b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (duplicatedOutput != 0) { 1406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // add duplicated output descriptor 1407b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL); 1408b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); 1409b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent dupOutputDesc->mOutput2 = mOutputs.valueFor(output); 1410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mSamplingRate = outputDesc->mSamplingRate; 1411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mFormat = outputDesc->mFormat; 1412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mChannels = outputDesc->mChannels; 1413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin dupOutputDesc->mLatency = outputDesc->mLatency; 1414b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent addOutput(duplicatedOutput, dupOutputDesc); 1415b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent applyStreamVolumes(duplicatedOutput, device); 1416b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 1417b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGW("getOutput() could not open duplicated output for %d and %d", 1418b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mPrimaryOutput, output); 1419b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(output); 1420b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(output); 1421b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete outputDesc; 1422b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1425b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGW("setDeviceConnectionState() could not open A2DP output for device %x", device); 1426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin delete outputDesc; 1427b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1430b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // we assume that one given device is supported by zero or one output 1431b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // check if one opened output is not needed any more after disconnecting one device 1432b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1433b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc = mOutputs.valueAt(i); 1434b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputDesc->mProfile && 1435b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent !(outputDesc->mProfile->mSupportedDevices & mAvailableOutputDevices)) { 1436b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent output = mOutputs.keyAt(i); 1437b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent break; 1438b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1442b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return output; 1443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1444f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1445b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::closeOutput(audio_io_handle_t output) 1446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1447b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput(%d)", output); 1448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1449b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 1450b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputDesc == NULL) { 1451b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGW("closeOutput() unknown output %d", output); 1452b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1453f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1454f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1455b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // look for duplicated outputs connected to the output being removed. 1456b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1457b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i); 1458b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->isDuplicated() && 1459b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (dupOutputDesc->mOutput1 == outputDesc || 1460b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent dupOutputDesc->mOutput2 == outputDesc)) { 1461b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc2; 1462b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (dupOutputDesc->mOutput1 == outputDesc) { 1463b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput2; 1464b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 1465b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2 = dupOutputDesc->mOutput1; 1466b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1467b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // As all active tracks on duplicated output will be deleted, 1468b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // and as they were also referenced on the other output, the reference 1469b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // count for their stream type must be adjusted accordingly on 1470b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // the other output. 1471b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (int j = 0; j < (int)AudioSystem::NUM_STREAM_TYPES; j++) { 1472b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent int refCount = dupOutputDesc->mRefCount[j]; 1473b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputDesc2->changeRefCount((AudioSystem::stream_type)j,-refCount); 1474b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1475b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i); 1476b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); 1477f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1478b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(duplicatedOutput); 1479b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(duplicatedOutput); 1480b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(duplicatedOutput); 1481f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1482f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1483b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1484b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioParameter param; 1485b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent param.add(String8("closing"), String8("true")); 1486b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(output, param.toString()); 1487b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1488b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->closeOutput(output); 1489b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent delete mOutputs.valueFor(output); 1490b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mOutputs.removeItem(output); 1491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1493f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManagerBase::getOutputsForDevice(audio_devices_t device) 1494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1495b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t> outputs; 1496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1497b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("getOutputsForDevice() device %04x", device); 1498b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 149912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ALOGV("output %d isDuplicated=%d device=%04x", 150012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi i, mOutputs.valueAt(i)->isDuplicated(), mOutputs.valueAt(i)->supportedDevices()); 1501b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if ((device & mOutputs.valueAt(i)->supportedDevices()) == device) { 1502b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("getOutputsForDevice() found output %d", mOutputs.keyAt(i)); 1503b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent outputs.add(mOutputs.keyAt(i)); 1504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1506b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return outputs; 1507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1509b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentbool AudioPolicyManagerBase::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, 1510b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t>& outputs2) 1511f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1512b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1.size() != outputs2.size()) { 1513b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 1514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1515b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < outputs1.size(); i++) { 1516b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (outputs1[i] != outputs2[i]) { 1517b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return false; 1518f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1519f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1520b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return true; 1521b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 1522b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1523b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentvoid AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy) 1524b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 1525b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t> srcOutputs = 1526b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent getOutputsForDevice(getDeviceForStrategy(strategy)); 1527b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = 1528b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent getOutputsForDevice(getDeviceForStrategy(strategy, false)); 1529b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1530b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // TODO: current implementation assumes that at most one output corresponds to a device. 153112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // this will change when supporting low power, low latency or tunneled output streams. 153212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // FIXME broken with A2DP + no wired headset. 153312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi //ALOG_ASSERT(srcOutputs.size() < 2, "checkOutputForStrategy(): " 153412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // "more than one (%d) source output for strategy %d", srcOutputs.size(), strategy); 153512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi //ALOG_ASSERT(dstOutputs.size() < 2, "checkOutputForStrategy(): " 153612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // "more than one (%d) destination output for strategy %d", dstOutputs.size(), strategy); 1537b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1538b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!vectorsEqual(srcOutputs,dstOutputs)) { 153912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // FIXME dstOutputs[0] happens to be the output to use, what guarantees it is always true? 1540b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", 1541b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent strategy, srcOutputs[0], dstOutputs[0]); 1542b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent // mute media strategy while moving tracks from one output to another 1543b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStrategyMute(strategy, true, srcOutputs[0]); 1544b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStrategyMute(strategy, false, srcOutputs[0], MUTE_TIME_MS); 1545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Move effects associated to this strategy from previous output to new output 1547f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mEffects.size(); i++) { 1548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin EffectDescriptor *desc = mEffects.valueAt(i); 1549f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (desc->mSession != AudioSystem::SESSION_OUTPUT_STAGE && 1550f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin desc->mStrategy == strategy && 1551b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent desc->mIo == srcOutputs[0]) { 1552b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent ALOGV("checkOutputForStrategy() moving effect %d to output %d", 1553b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mEffects.keyAt(i), dstOutputs[0]); 1554b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->moveEffects(desc->mSession, srcOutputs[0], dstOutputs[0]); 1555b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent desc->mIo = dstOutputs[0]; 1556f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1557f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 155812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // Invalidate the output of the streams associated with this strategy 1559f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 1560f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)i) == strategy) { 156112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi //FIXME see fixme on name change 1562b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, dstOutputs[0]); 1563f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1564f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1565f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1566f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1567f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1568f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkOutputForAllStrategies() 1569f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1570c16ac09f510437e8340be691720177a490ae78f0Eric Laurent checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 1571f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_PHONE); 1572f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_SONIFICATION); 157312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 1574f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_MEDIA); 1575f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin checkOutputForStrategy(STRATEGY_DTMF); 1576f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1577f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1578b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurentaudio_io_handle_t AudioPolicyManagerBase::getA2dpOutput() 1579b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 1580b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!sHasA2dp) { 1581b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1582b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1583b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1584b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1585b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 1586b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 1587b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mOutputs.keyAt(i); 1588b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1589b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1590b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1591b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return 0; 1592b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 1593b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1594f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::checkA2dpSuspend() 1595f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1596b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (!sHasA2dp) { 1597b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1598b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1599b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent audio_io_handle_t a2dpOutput = getA2dpOutput(); 1600b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (a2dpOutput == 0) { 1601b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return; 1602b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 1603b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 1604f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // suspend A2DP output if: 1605f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (NOT already suspended) && 1606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is connected && 1607f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage for communication || for record is SCO))) || 1608f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is ringing || in call) 1609f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1610f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // restore A2DP output if: 1611f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (Already suspended) && 1612f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // ((SCO device is NOT connected || 1613f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (forced usage NOT for communication && NOT for record is SCO))) && 1614f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // (phone state is NOT ringing && NOT in call) 1615f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1616f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mA2dpSuspended) { 1617f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress == "") || 1618f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) && 1619f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) && 1620f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState != AudioSystem::MODE_IN_CALL) && 1621f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState != AudioSystem::MODE_RINGTONE))) { 1622f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1623b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->restoreOutput(a2dpOutput); 1624f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = false; 1625f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1626f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1627f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (((mScoDeviceAddress != "") && 1628f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 1629f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) || 1630f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin ((mPhoneState == AudioSystem::MODE_IN_CALL) || 1631f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (mPhoneState == AudioSystem::MODE_RINGTONE))) { 1632f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1633b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->suspendOutput(a2dpOutput); 1634f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mA2dpSuspended = true; 1635f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1636f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1637f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1638f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1639f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache) 1640f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1641f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device = (audio_devices_t)0; 1642f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1643f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 1644f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // check the following by order of priority to request a routing change if necessary: 1645c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 1: the strategy enforced audible is active on the output: 1646c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // use device for strategy enforced audible 1647c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 2: we are in call or the strategy phone is active on the output: 1648f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy phone 1649c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // 3: the strategy sonification is active on the output: 1650f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy sonification 165112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 4: the strategy "respectful" sonification is active on the output: 165212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // use device for strategy "respectful" sonification 165312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 5: the strategy media is active on the output: 1654f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy media 165512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // 6: the strategy DTMF is active on the output: 1656f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // use device for strategy DTMF 1657c16ac09f510437e8340be691720177a490ae78f0Eric Laurent if (outputDesc->isUsedByStrategy(STRATEGY_ENFORCED_AUDIBLE)) { 1658c16ac09f510437e8340be691720177a490ae78f0Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 1659c16ac09f510437e8340be691720177a490ae78f0Eric Laurent } else if (isInCall() || 1660c16ac09f510437e8340be691720177a490ae78f0Eric Laurent outputDesc->isUsedByStrategy(STRATEGY_PHONE)) { 1661f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 1662f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) { 1663f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 166412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION_RESPECTFUL)) { 166512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // can't use the cache for this strategy as the device depends on what's currently playing 166612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, false); 1667f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) { 1668f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 1669f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) { 1670f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 1671f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1672f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 16736a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getNewDevice() selected device %x", device); 1674f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return device; 1675f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1676f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1677f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getStrategyForStream(AudioSystem::stream_type stream) { 1678f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return (uint32_t)getStrategy(stream); 1679f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1680f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1681f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDevicesForStream(AudioSystem::stream_type stream) { 1682f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t devices; 1683f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // By checking the range of stream before calling getStrategy, we avoid 16845efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 1685f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // and then return STRATEGY_MEDIA, but we want to return the empty set. 1686f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream < (AudioSystem::stream_type) 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { 1687f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent devices = (audio_devices_t)0; 1688f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1689f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioPolicyManagerBase::routing_strategy strategy = getStrategy(stream); 1690f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin devices = getDeviceForStrategy(strategy, true); 1691f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1692f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return devices; 1693f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1694f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1695f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy( 1696f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::stream_type stream) { 1697f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // stream to strategy mapping 1698f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (stream) { 1699f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::VOICE_CALL: 1700f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::BLUETOOTH_SCO: 1701f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_PHONE; 1702f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::RING: 1703f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::ALARM: 1704f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_SONIFICATION; 170512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::NOTIFICATION: 170612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi return STRATEGY_SONIFICATION_RESPECTFUL; 1707f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::DTMF: 1708f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_DTMF; 1709f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 17105efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("unknown stream type"); 1711f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::SYSTEM: 1712f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 1713f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // while key clicks are played produces a poor result 1714f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::TTS: 1715f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::MUSIC: 1716f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return STRATEGY_MEDIA; 1717c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case AudioSystem::ENFORCED_AUDIBLE: 1718c16ac09f510437e8340be691720177a490ae78f0Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 1719f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1720f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1721f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 172212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivivoid AudioPolicyManagerBase::handleNotificationRoutingForStream(AudioSystem::stream_type stream) { 172312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi switch(stream) { 172412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case AudioSystem::MUSIC: 172512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 172612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi updateDeviceForStrategy(); 172712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 172812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi default: 172912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 173012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 173112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi} 173212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 1733f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, bool fromCache) 1734f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1735f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device = 0; 1736f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1737f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (fromCache) { 17386a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForStrategy() from cache strategy %d, device %x", strategy, mDeviceForStrategy[strategy]); 1739f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mDeviceForStrategy[strategy]; 1740f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1741f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1742f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (strategy) { 174312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 174412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi case STRATEGY_SONIFICATION_RESPECTFUL: 174512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if (isInCall()) { 174612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi device = getDeviceForStrategy(STRATEGY_SONIFICATION, false); 174712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 174812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // while media is playing (or has recently played), use the same device 174912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi device = getDeviceForStrategy(STRATEGY_MEDIA, false); 175012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } else { 175112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi // when media is not playing anymore, fall back on the sonification behavior 175212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi device = getDeviceForStrategy(STRATEGY_SONIFICATION, false); 175312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi } 175412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 175512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi break; 175612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi 1757f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_DTMF: 1758f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall()) { 1759f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when off call, DTMF strategy follows the same rules as MEDIA strategy 1760f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_MEDIA, false); 1761f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1762f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1763f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when in call, DTMF and PHONE strategies follow the same rules 1764f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 1765f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1766f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_PHONE: 1767f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // for phone strategy, we first consider the forced use and then the available devices by order 1768f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // of priority 1769f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { 1770f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_BT_SCO: 1771f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (!isInCall() || strategy != STRATEGY_DTMF) { 1772f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 1773f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1774f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1775f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 1776f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1777f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO; 1778f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1779f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if SCO device is requested but no SCO device is available, fall back to default case 1780f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 1781f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1782f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: // FORCE_NONE 1783f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE; 1784f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1785f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; 1786f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1787f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 1788b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (sHasA2dp && !isInCall() && !mA2dpSuspended) { 1789f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; 1790f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1791f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 1792f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1793f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1794f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 1795f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 179655ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 179755ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent if (device) break; 1798f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 1799f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1800f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE; 1801f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 18025efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("getDeviceForStrategy() earpiece device not found"); 1803f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1804f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1805f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1806f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AudioSystem::FORCE_SPEAKER: 1807f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 1808f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // A2DP speaker when forcing to speaker output 1809b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (sHasA2dp && !isInCall() && !mA2dpSuspended) { 1810f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 1811f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1812f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1813f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 1814f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 181555ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 181655ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent if (device) break; 1817f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 1818f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device) break; 1819f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 1820f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 18215efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("getDeviceForStrategy() speaker device not found"); 1822f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1823f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1824f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1825f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1826f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1827f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_SONIFICATION: 1828f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1829f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 1830f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // handleIncallSonification(). 1831f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isInCall()) { 1832f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = getDeviceForStrategy(STRATEGY_PHONE, false); 1833f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1834f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1835c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // FALL THROUGH 1836c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 1837c16ac09f510437e8340be691720177a490ae78f0Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 1838c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 1839c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // except when in call where it doesn't default to STRATEGY_PHONE behavior 1840c16ac09f510437e8340be691720177a490ae78f0Eric Laurent 1841f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 1842f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 18435efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("getDeviceForStrategy() speaker device not found"); 1844f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1845f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // The second device used for sonification is the same as the device used by media strategy 1846f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // FALL THROUGH 1847f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1848f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case STRATEGY_MEDIA: { 1849f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE; 1850f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1851f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; 1852f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1853b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (sHasA2dp && (getA2dpOutput() != 0) && !mA2dpSuspended) { 1854f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1855f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; 1856f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1857f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1858f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 1859f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1860f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1861f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 1862f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1863f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1864f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 186555ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; 1866f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1867f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 186855ac23bc116ad9ae38266a5e660fd22f5104348eEric Laurent device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; 1869f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1870f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1871f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 1872f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1873f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device2 == 0) { 1874f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; 1875f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1876f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1877c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 1878c16ac09f510437e8340be691720177a490ae78f0Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, 0 otherwise 1879f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device |= device2; 1880f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 18815efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block ALOGE("getDeviceForStrategy() speaker device not found"); 1882f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1883f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } break; 1884f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1885f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 188664cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 1887f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1888f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1889f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 18906a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 1891f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)device; 1892f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1893f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1894f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::updateDeviceForStrategy() 1895f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1896f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < NUM_STRATEGIES; i++) { 1897f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false); 1898f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1899f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1900f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1901f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentvoid AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, 1902f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 1903f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent bool force, 1904f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent int delayMs) 1905f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 19066a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setOutputDevice() output %d device %x delayMs %d", output, device, delayMs); 1907f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 1908f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1909f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1910f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->isDuplicated()) { 1911f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); 1912f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); 1913f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 1914f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1915f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // filter devices according to output selected 1916f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices); 1917f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1918f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t prevDevice = outputDesc->device(); 1919f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Do not change the routing if: 1920f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the requestede device is 0 1921f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the requested device is the same as current device and force is not specified. 1922f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Doing this check here allows the caller to call setOutputDevice() without conditions 1923f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((device == 0 || device == prevDevice) && !force) { 19246a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setOutputDevice() setting same device %x or null device for output %d", device, output); 1925f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 1926f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1927f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1928f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mDevice = device; 1929f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // mute media streams if both speaker and headset are selected 1930b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (output == mPrimaryOutput && AudioSystem::popCount(device) == 2) { 1931f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStrategyMute(STRATEGY_MEDIA, true, output); 1932f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // wait for the PCM output buffers to empty before proceeding with the rest of the command 1933497fb4566204c88bd247aafc2412ddef8f85e480Eric Laurent // FIXME: increased delay due to larger buffers used for low power audio mode. 1934497fb4566204c88bd247aafc2412ddef8f85e480Eric Laurent // remove when low power audio is controlled by policy manager. 1935497fb4566204c88bd247aafc2412ddef8f85e480Eric Laurent usleep(outputDesc->mLatency*8*1000); 1936f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1937f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1938f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do the routing 1939f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioParameter param = AudioParameter(); 1940f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin param.addInt(String8(AudioParameter::keyRouting), (int)device); 1941b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, param.toString(), delayMs); 1942f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // update stream volumes according to new device 1943f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin applyStreamVolumes(output, device, delayMs); 1944f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1945f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if changing from a combined headset + speaker route, unmute media streams 1946f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent if (output == mPrimaryOutput && AudioSystem::popCount((uint32_t)prevDevice) == 2) { 1947f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStrategyMute(STRATEGY_MEDIA, false, output, delayMs); 1948f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1949f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1950f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1951f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) 1952f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1953f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device; 1954f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1955f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin switch(inputSource) { 1956f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_DEFAULT: 1957f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_MIC: 1958f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_RECOGNITION: 1959f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_COMMUNICATION: 1960f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO && 1961f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 1962f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; 1963f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 1964f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_WIRED_HEADSET; 1965f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1966f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BUILTIN_MIC; 1967f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1968f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1969f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_CAMCORDER: 1970f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (hasBackMicrophone()) { 1971f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BACK_MIC; 1972f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 1973f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_BUILTIN_MIC; 1974f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1975f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1976f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 1977f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 1978f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 1979f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = AudioSystem::DEVICE_IN_VOICE_CALL; 1980f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1981f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin default: 198264cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 1983f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = 0; 1984f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin break; 1985f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 19866a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 1987f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)device; 1988f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1989f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 1990f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinaudio_io_handle_t AudioPolicyManagerBase::getActiveInput() 1991f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 1992f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (size_t i = 0; i < mInputs.size(); i++) { 1993f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mInputs.valueAt(i)->mRefCount > 0) { 1994f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return mInputs.keyAt(i); 1995f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1996f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 1997f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0; 1998f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 1999f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2000e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2001c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentaudio_devices_t AudioPolicyManagerBase::getDeviceForVolume(audio_devices_t device) 2002e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2003e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent if (device == 0) { 2004e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // this happens when forcing a route update and no track is active on an output. 2005e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // In this case the returned category is not important. 2006c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 2007c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else if (AudioSystem::popCount(device) > 1) { 2008e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // Multiple device selection is either: 2009e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - speaker + one other device: give priority to speaker in this case. 2010e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 2011e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 2012e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent // selection if not the speaker. 2013c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 2014c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 2015c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } else { 2016c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 2017c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 2018e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 2019e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 202064cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW_IF(AudioSystem::popCount(device) != 1, 2021c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 2022e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device); 2023e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2024c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return device; 2025c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 2026c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2027f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric LaurentAudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(audio_devices_t device) 2028c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 2029f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent switch(getDeviceForVolume(device)) { 2030e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 2031e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_EARPIECE; 2032e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 2033e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 2034e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 2035e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 2036e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 2037e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 2038e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_HEADSET; 2039e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 2040e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 2041e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 2042c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent case AUDIO_DEVICE_OUT_AUX_DIGITAL: 2043e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent default: 2044e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent return DEVICE_CATEGORY_SPEAKER; 2045e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } 2046e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent} 2047e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2048f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentfloat AudioPolicyManagerBase::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, 2049e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int indexInUi) 2050e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2051e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent device_category deviceCategory = getDeviceCategory(device); 2052e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 2053e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2054f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // the volume index in the UI is relative to the min and max volume indices for this stream type 2055e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 2056e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[VOLMIN].mIndex; 2057f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 2058f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (streamDesc.mIndexMax - streamDesc.mIndexMin); 2059f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2060f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // find what part of the curve this index volume belongs to, or if it's out of bounds 2061f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int segment = 0; 2062e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 2063f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 0.0f; 2064e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 2065f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 0; 2066e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 2067f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 1; 2068e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 2069f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin segment = 2; 2070f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { // out of bounds 2071f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0f; 2072f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2073f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2074f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // linear interpolation in the attenuation table in dB 2075e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent float decibels = curve[segment].mDBAttenuation + 2076e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 2077e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ( (curve[segment+1].mDBAttenuation - 2078e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation) / 2079e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent ((float)(curve[segment+1].mIndex - 2080e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex)) ); 2081f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2082f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 2083f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 20846a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 2085e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mIndex, volIdx, 2086e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mIndex, 2087e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment].mDBAttenuation, 2088cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent decibels, 2089e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent curve[segment+1].mDBAttenuation, 2090f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin amplification); 2091f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2092f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return amplification; 2093f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2094f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2095cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2096e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2097e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 2098e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2099e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2100e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2101e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2102e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 2103cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent}; 2104cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent 2105e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2106e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2107e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 2108e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2109e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2110e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2111e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent AudioPolicyManagerBase::sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { 2112e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 2113e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2114e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2115e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2116e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentconst AudioPolicyManagerBase::VolumeCurvePoint 2117e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent *AudioPolicyManagerBase::sVolumeProfiles[AudioPolicyManagerBase::NUM_STRATEGIES] 2118e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent [AudioPolicyManagerBase::DEVICE_CATEGORY_CNT] = { 2119e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent { // STRATEGY_MEDIA 2120e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 2121e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2122e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 2123e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2124e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent { // STRATEGY_PHONE 2125e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2126e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2127e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2128e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 2129e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent { // STRATEGY_SONIFICATION 2130e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2131e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2132e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2133e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent }, 213412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi { // STRATEGY_SONIFICATION_RESPECTFUL uses same volumes as SONIFICATION 213512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 213612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 213712bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 213812bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi }, 2139e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent { // STRATEGY_DTMF 2140e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2141e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2142e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2143c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2144c16ac09f510437e8340be691720177a490ae78f0Eric Laurent { // STRATEGY_ENFORCED_AUDIBLE 2145c16ac09f510437e8340be691720177a490ae78f0Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 2146c16ac09f510437e8340be691720177a490ae78f0Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 2147c16ac09f510437e8340be691720177a490ae78f0Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 2148c16ac09f510437e8340be691720177a490ae78f0Eric Laurent }, 2149e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent}; 2150e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent 2151e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurentvoid AudioPolicyManagerBase::initializeVolumeCurves() 2152e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent{ 2153e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 2154e43c5c4ca4477a6b384711552c3e990609039d93Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 2155cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent mStreams[i].mVolumeCurve[j] = 2156cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent sVolumeProfiles[getStrategy((AudioSystem::stream_type)i)][j]; 2157cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2158cd057ad2774903c62f5c11bc71c4e7357aee71b8Eric Laurent } 2159f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2160f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2161c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentfloat AudioPolicyManagerBase::computeVolume(int stream, 2162c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2163c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2164f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device) 2165f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2166f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = 1.0; 2167f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2168f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 2169f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2170f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (device == 0) { 2171f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin device = outputDesc->device(); 2172f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2173f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2174f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if volume is not 0 (not muted), force media volume to max on digital output 2175f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::MUSIC && 2176f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin index != mStreams[stream].mIndexMin && 2177f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent (device == AUDIO_DEVICE_OUT_AUX_DIGITAL || 2178f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) { 2179f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return 1.0; 2180f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2181f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2182f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = volIndexToAmpl(device, streamDesc, index); 2183f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2184f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if a headset is connected, apply the following rules to ring tones and notifications 2185f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // to avoid sound level bursts in user's ears: 2186f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - always attenuate ring tones and notifications volume by 6dB 2187f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - if music is playing, always limit the volume to current music volume, 2188f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // with a minimum threshold at -36dB so that notification is always perceived. 218912bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 219012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if ((device & (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP | 219112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 219212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi AudioSystem::DEVICE_OUT_WIRED_HEADSET | 219312bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) && 219412bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION) 219512bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) 219612bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi || (stream == AudioSystem::SYSTEM)) && 2197f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin streamDesc.mCanBeMuted) { 2198f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 2199f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // when the phone is ringing we must consider that music could have been paused just before 2200f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // by the music application and behave as if music was active if the last music track was 2201f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // just stopped 2202f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[AudioSystem::MUSIC] || mLimitRingtoneVolume) { 2203c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float musicVol = computeVolume(AudioSystem::MUSIC, 2204f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mStreams[AudioSystem::MUSIC].getVolumeIndex(device), 2205c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2206f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent device); 2207c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 2208c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 2209f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume > minVol) { 2210f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = minVol; 22116a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 2212f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2213f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2214f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2215f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2216f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return volume; 2217f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2218f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2219c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentstatus_t AudioPolicyManagerBase::checkAndSetVolume(int stream, 2220c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int index, 2221c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent audio_io_handle_t output, 2222f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2223c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 2224c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 2225f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2226f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2227f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change actual stream volume if the stream is muted 2228f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 22296a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkAndSetVolume() stream %d muted count %d", stream, mOutputs.valueFor(output)->mMuteCount[stream]); 2230f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2231f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2232f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2233f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // do not change in call volume if bluetooth is connected and vice versa 2234f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || 2235f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) { 22366a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 2237f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, mForceUse[AudioSystem::FOR_COMMUNICATION]); 2238f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return INVALID_OPERATION; 2239f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2240f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2241f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float volume = computeVolume(stream, index, output, device); 2242f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // We actually change the volume if: 2243f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the float value returned by computeVolume() changed 2244f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // - the force flag is set 2245f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 2246f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin force) { 2247f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutputs.valueFor(output)->mCurVolume[stream] = volume; 22486a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setStreamVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 2249f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL || 2250f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::DTMF || 2251f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::BLUETOOTH_SCO) { 2252f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // offset value to reflect actual hardware volume that never reaches 0 2253f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java) 2254f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin volume = 0.01 + 0.99 * volume; 2255f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 2256f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // enabled 2257f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::BLUETOOTH_SCO) { 2258f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs); 2259f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2260f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2261f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2262f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); 2263f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2264f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2265f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL || 2266f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream == AudioSystem::BLUETOOTH_SCO) { 2267f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin float voiceVolume; 2268f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // Force voice volume to max for bluetooth SCO as volume is managed by the headset 2269f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stream == AudioSystem::VOICE_CALL) { 2270f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 2271f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2272f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin voiceVolume = 1.0; 2273f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2274f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2275b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { 2276f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 2277f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mLastVoiceVolume = voiceVolume; 2278f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2279f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2280f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2281f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2282f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2283f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2284c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, 2285f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device, 2286c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent int delayMs, 2287c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent bool force) 2288f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 22896a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("applyStreamVolumes() for output %d and device %x", output, device); 2290f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2291f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 2292c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 2293f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mStreams[stream].getVolumeIndex(device), 2294c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2295c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 2296c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs, 2297c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent force); 2298f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2299f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2300f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2301f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output, int delayMs) 2302f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 23036a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 2304f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { 2305f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)stream) == strategy) { 2306f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin setStreamMute(stream, on, output, delayMs); 2307f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2308f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2309f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2310f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2311f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs) 2312f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2313f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin StreamDescriptor &streamDesc = mStreams[stream]; 2314f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2315f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent audio_devices_t device = outputDesc->device(); 2316f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 23176a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, outputDesc->mMuteCount[stream]); 2318f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2319f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (on) { 2320f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 2321f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (streamDesc.mCanBeMuted) { 2322c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 2323f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2324f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2325f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 2326f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin outputDesc->mMuteCount[stream]++; 2327f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2328f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mMuteCount[stream] == 0) { 232964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("setStreamMute() unmuting non muted stream!"); 2330f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 2331f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2332f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (--outputDesc->mMuteCount[stream] == 0) { 2333c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent checkAndSetVolume(stream, 2334c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent streamDesc.getVolumeIndex((audio_devices_t)device), 2335c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent output, 2336c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device, 2337c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent delayMs); 2338f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2339f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2340f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2341f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2342f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, bool stateChange) 2343f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2344f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if the stream pertains to sonification strategy and we are in call we must 2345f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // mute the stream if it is low visibility. If it is high visibility, we must play a tone 2346f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // in the device used for phone strategy and play the tone if the selected device does not 2347f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // interfere with the device used for phone strategy 2348f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 2349f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // many times as there are active tracks on the output 235012bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); 235112bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi if ((stream_strategy == STRATEGY_SONIFICATION) || 235212bd6e4a5c26bd8035bf804d0cc821bd9b8cce9bJean-Michel Trivi ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { 2353b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 23546a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 2355f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin stream, starting, outputDesc->mDevice, stateChange); 2356f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->mRefCount[stream]) { 2357f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin int muteCount = 1; 2358f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (stateChange) { 2359f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin muteCount = outputDesc->mRefCount[stream]; 2360f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2361f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) { 23626a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 2363f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 2364b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 2365f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2366f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 23676a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility"); 2368f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (outputDesc->device() & getDeviceForStrategy(STRATEGY_PHONE)) { 23696a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 2370f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < muteCount; i++) { 2371b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 2372f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2373f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2374f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (starting) { 2375f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL); 2376f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2377f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mpClientInterface->stopTone(); 2378f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2379f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2380f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2381f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2382f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2383f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2384f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isInCall() 2385f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2386f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return isStateInCall(mPhoneState); 2387f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2388f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2389f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::isStateInCall(int state) { 2390f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((state == AudioSystem::MODE_IN_CALL) || 2391f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin (state == AudioSystem::MODE_IN_COMMUNICATION)); 2392f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2393f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2394f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinbool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream, 2395f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t samplingRate, 2396f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t format, 2397f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t channels, 2398f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin AudioSystem::output_flags flags, 2399f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t device) 2400f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2401f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) || 2402b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent (format != 0 && !AudioSystem::isLinearPCM(format))); 2403f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2404f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2405f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsCpuLoad() 2406f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2407f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_CPU_LOAD; 2408f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2409f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2410f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::getMaxEffectsMemory() 2411f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2412f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return MAX_EFFECTS_MEMORY; 2413f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2414f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2415f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioOutputDescriptor class implementation 2416f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2417b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric LaurentAudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor( 2418b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent const output_profile_t *profile) 2419f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin : mId(0), mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0), 2420f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mFlags((AudioSystem::output_flags)0), mDevice((audio_devices_t)0), 2421f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mOutput1(0), mOutput2(0), mProfile(profile) 2422f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2423f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // clear usage count for all stream types 2424f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 2425f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[i] = 0; 2426f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mCurVolume[i] = -1.0; 2427f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mMuteCount[i] = 0; 2428f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mStopTime[i] = 0; 2429f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2430f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2431f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2432f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::device() 2433f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2434f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 2435f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 2436f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } else { 2437f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return mDevice; 2438f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2439f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2440f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2441f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinvoid AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta) 2442f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2443f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin // forward usage count change to attached outputs 2444f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (isDuplicated()) { 2445f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput1->changeRefCount(stream, delta); 2446f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mOutput2->changeRefCount(stream, delta); 2447f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2448f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if ((delta + (int)mRefCount[stream]) < 0) { 244964cca04dcbf4e21a51131224b9d0f0c596f876d4Steve Block ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]); 2450f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] = 0; 2451f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return; 2452f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2453f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin mRefCount[stream] += delta; 24546a70518b93928d1c91457ff805e375c82d76b0e5Steve Block ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 2455f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2456f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2457f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::refCount() 2458f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2459f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t refcount = 0; 2460f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 2461f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin refcount += mRefCount[i]; 2462f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2463f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return refcount; 2464f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2465f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2466f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinuint32_t AudioPolicyManagerBase::AudioOutputDescriptor::strategyRefCount(routing_strategy strategy) 2467f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2468f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin uint32_t refCount = 0; 2469f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { 2470f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin if (getStrategy((AudioSystem::stream_type)i) == strategy) { 2471f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin refCount += mRefCount[i]; 2472f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2473f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2474f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return refCount; 2475f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2476f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2477f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurentaudio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::supportedDevices() 2478b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent{ 2479b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent if (isDuplicated()) { 2480f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 2481b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } else { 2482b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent return mProfile->mSupportedDevices ; 2483b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent } 2484b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent} 2485b4696fc22ba822ed37bd2e3a19bc17514ccc79c8Eric Laurent 2486f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd) 2487f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2488f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 2489f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 2490f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 2491f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2492f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 2493f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2494f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 2495f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2496f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Channels: %08x\n", mChannels); 2497f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2498f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 2499f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2500f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 2501f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2502f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", device()); 2503f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2504f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 2505f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2506f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { 2507f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 2508f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2509f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin } 2510f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 2511f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2512f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2513f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2514f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2515f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- AudioInputDescriptor class implementation 2516f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2517f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima ZavinAudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor() 2518f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin : mSamplingRate(0), mFormat(0), mChannels(0), 2519f9a4e2eccfbbe451512337af0806cfc54be0eaf9Eric Laurent mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice((audio_devices_t)0), mRefCount(0), 25201c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent mInputSource(0) 2521f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2522f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2523f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2524f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd) 2525f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2526f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 2527f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 2528f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 2529f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2530f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 2531f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2532f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Format: %d\n", mFormat); 2533f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2534f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Channels: %08x\n", mChannels); 2535f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2536f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics); 2537f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2538f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 2539f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2540f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 2541f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2542f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 2543f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2544f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2545f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2546f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2547f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- StreamDescriptor class implementation 2548f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2549c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric LaurentAudioPolicyManagerBase::StreamDescriptor::StreamDescriptor() 2550c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 2551c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 2552c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 2553c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 2554c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2555c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentint AudioPolicyManagerBase::StreamDescriptor::getVolumeIndex(audio_devices_t device) 2556c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent{ 2557c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AudioPolicyManagerBase::getDeviceForVolume(device); 2558c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 2559c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 2560c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 2561c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 2562c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent return mIndexCur.valueFor(device); 2563c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent} 2564c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2565c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurentvoid AudioPolicyManagerBase::StreamDescriptor::dump(int fd) 2566f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2567c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent const size_t SIZE = 256; 2568c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent char buffer[SIZE]; 2569c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent String8 result; 2570c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2571c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 2572c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 2573c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 2574c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 2575c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 2576c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.keyAt(i), 2577c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent mIndexCur.valueAt(i)); 2578c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append(buffer); 2579c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent } 2580c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent result.append("\n"); 2581c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent 2582c6f331b3f48455c9a9cdf00fc82894badd0a7da6Eric Laurent write(fd, result.string(), result.size()); 2583f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2584f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2585f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin// --- EffectDescriptor class implementation 2586f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2587f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavinstatus_t AudioPolicyManagerBase::EffectDescriptor::dump(int fd) 2588f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin{ 2589f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin const size_t SIZE = 256; 2590f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin char buffer[SIZE]; 2591f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin String8 result; 2592f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 25931c65a49da0c89f75e528354ef02de5dc93a28232Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 2594f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2595f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 2596f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2597f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Session: %d\n", mSession); 2598f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2599f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 2600f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin result.append(buffer); 2601582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 2602582a15744be109fb630db7dbd1d1bdf22ff44f12Eric Laurent result.append(buffer); 2603f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin write(fd, result.string(), result.size()); 2604f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2605f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin return NO_ERROR; 2606f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin} 2607f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2608f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2609f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin 2610f01215993dda68b6b52111d754bd0c7c2d5bcfa3Dima Zavin}; // namespace android 2611