AudioPolicyManager.cpp revision 5b61dddd0dba28922068da2487894761486aec6c
1e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent/* 2e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * Copyright (C) 2009 The Android Open Source Project 3e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * 4e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 5e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * you may not use this file except in compliance with the License. 6e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * You may obtain a copy of the License at 7e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * 8e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * http://www.apache.org/licenses/LICENSE-2.0 9e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * 10e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * Unless required by applicable law or agreed to in writing, software 11e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 12e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * See the License for the specific language governing permissions and 14e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent * limitations under the License. 15e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent */ 16e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 17e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent#define LOG_TAG "AudioPolicyManager" 18e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent//#define LOG_NDEBUG 0 19e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 20e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent//#define VERY_VERBOSE_LOGGING 21e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef VERY_VERBOSE_LOGGING 22e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#define ALOGVV ALOGV 23e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#else 24e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#define ALOGVV(a...) do { } while(0) 25e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif 26e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 27e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// A device mask for all audio input devices that are considered "virtual" when evaluating 28e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// active inputs in getActiveInput() 29e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL AUDIO_DEVICE_IN_REMOTE_SUBMIX 30e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// A device mask for all audio output devices that are considered "remote" when evaluating 31e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// active output devices in isStreamActiveRemotely() 32e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX 33e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 34d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <inttypes.h> 35d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <math.h> 36d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 37d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <cutils/properties.h> 38e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#include <utils/Log.h> 39e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#include <hardware/audio.h> 40d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <hardware/audio_effect.h> 41e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#include <hardware_legacy/audio_policy_conf.h> 423b73df74357b33869b39a1d69427673c780bd805Eric Laurent#include <media/AudioParameter.h> 43d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include "AudioPolicyManager.h" 44e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 453b73df74357b33869b39a1d69427673c780bd805Eric Laurentnamespace android { 46e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 47e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 483a4311c68348f728558e87b5db67d47605783890Eric Laurent// Definitions for audio_policy.conf file parsing 493a4311c68348f728558e87b5db67d47605783890Eric Laurent// ---------------------------------------------------------------------------- 503a4311c68348f728558e87b5db67d47605783890Eric Laurent 513a4311c68348f728558e87b5db67d47605783890Eric Laurentstruct StringToEnum { 523a4311c68348f728558e87b5db67d47605783890Eric Laurent const char *name; 533a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t value; 543a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 553a4311c68348f728558e87b5db67d47605783890Eric Laurent 563a4311c68348f728558e87b5db67d47605783890Eric Laurent#define STRING_TO_ENUM(string) { #string, string } 573a4311c68348f728558e87b5db67d47605783890Eric Laurent#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 583a4311c68348f728558e87b5db67d47605783890Eric Laurent 593a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sDeviceNameToEnumTable[] = { 603a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE), 613a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER), 623a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET), 633a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE), 643a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO), 653a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET), 663a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT), 673a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO), 683a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP), 693a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES), 703a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER), 713a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP), 723a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL), 733a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET), 743a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET), 753a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY), 763a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE), 773a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB), 783a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX), 793a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), 803a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), 813a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO), 823a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET), 833a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL), 843a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL), 853a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC), 863a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX), 873a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET), 883a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET), 893a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY), 90d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE), 913a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 923a4311c68348f728558e87b5db67d47605783890Eric Laurent 933a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFlagNameToEnumTable[] = { 943a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT), 953a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), 963a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), 973a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), 983a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD), 993a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING), 1003a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1013a4311c68348f728558e87b5db67d47605783890Eric Laurent 1023a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFormatNameToEnumTable[] = { 1033a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT), 1043a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT), 1053a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT), 1063a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT), 1073a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT), 1083a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED), 1093a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_MP3), 1103a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AAC), 1113a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_VORBIS), 1123a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1133a4311c68348f728558e87b5db67d47605783890Eric Laurent 1143a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sOutChannelsNameToEnumTable[] = { 1153a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO), 1163a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 1173a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 1183a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 1193a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1203a4311c68348f728558e87b5db67d47605783890Eric Laurent 1213a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sInChannelsNameToEnumTable[] = { 1223a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), 1233a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), 1243a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK), 1253a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1263a4311c68348f728558e87b5db67d47605783890Eric Laurent 1273a4311c68348f728558e87b5db67d47605783890Eric Laurent 1283a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::stringToEnum(const struct StringToEnum *table, 1293a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t size, 1303a4311c68348f728558e87b5db67d47605783890Eric Laurent const char *name) 1313a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1323a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < size; i++) { 1333a4311c68348f728558e87b5db67d47605783890Eric Laurent if (strcmp(table[i].name, name) == 0) { 1343a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("stringToEnum() found %s", table[i].name); 1353a4311c68348f728558e87b5db67d47605783890Eric Laurent return table[i].value; 1363a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1373a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1383a4311c68348f728558e87b5db67d47605783890Eric Laurent return 0; 1393a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1403a4311c68348f728558e87b5db67d47605783890Eric Laurent 1413a4311c68348f728558e87b5db67d47605783890Eric Laurentconst char *AudioPolicyManager::enumToString(const struct StringToEnum *table, 1423a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t size, 1433a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t value) 1443a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1453a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < size; i++) { 1463a4311c68348f728558e87b5db67d47605783890Eric Laurent if (table[i].value == value) { 1473a4311c68348f728558e87b5db67d47605783890Eric Laurent return table[i].name; 1483a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1493a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1503a4311c68348f728558e87b5db67d47605783890Eric Laurent return ""; 1513a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1523a4311c68348f728558e87b5db67d47605783890Eric Laurent 1533a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::stringToBool(const char *value) 1543a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1553a4311c68348f728558e87b5db67d47605783890Eric Laurent return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0)); 1563a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1573a4311c68348f728558e87b5db67d47605783890Eric Laurent 1583a4311c68348f728558e87b5db67d47605783890Eric Laurent 1593a4311c68348f728558e87b5db67d47605783890Eric Laurent// ---------------------------------------------------------------------------- 160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AudioPolicyInterface implementation 161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 164e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, 1653b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state, 166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *device_address) 167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1683a4311c68348f728558e87b5db67d47605783890Eric Laurent String8 address = String8(device_address); 169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); 171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // connect/disconnect only 1 device at a time 173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; 174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output devices 176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_output_device(device)) { 177d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector <audio_io_handle_t> outputs; 178d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 1793a4311c68348f728558e87b5db67d47605783890Eric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device, 1803a4311c68348f728558e87b5db67d47605783890Eric Laurent address, 1812f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent 0); 1823a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = mAvailableOutputDevices.indexOf(devDesc); 1833a4311c68348f728558e87b5db67d47605783890Eric Laurent 184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // save a copy of the opened output descriptors before any output is opened or closed 185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() 186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (state) 188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output device connection 1903b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: 1913a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device already connected: %x", device); 193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setDeviceConnectionState() connecting device %x", device); 196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1973a4311c68348f728558e87b5db67d47605783890Eric Laurent if (checkOutputsForDevice(device, state, outputs, address) != NO_ERROR) { 198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 200d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs", 201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.size()); 202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // register new device as available 2033a4311c68348f728558e87b5db67d47605783890Eric Laurent index = mAvailableOutputDevices.add(devDesc); 2043a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 2053a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices[index]->mId = nextUniqueId(); 2063a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 2073a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_MEMORY; 208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output device disconnection 2123b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: { 2133a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index < 0) { 214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device not connected: %x", device); 215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setDeviceConnectionState() disconnecting device %x", device); 219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // remove device from available output devices 2203a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.remove(devDesc); 2213a4311c68348f728558e87b5db67d47605783890Eric Laurent 2223a4311c68348f728558e87b5db67d47605783890Eric Laurent checkOutputsForDevice(device, state, outputs, address); 223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // not currently handling multiple simultaneous submixes: ignoring remote submix 224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // case and address 225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } break; 226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("setDeviceConnectionState() invalid state: %x", state); 229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2323a4311c68348f728558e87b5db67d47605783890Eric Laurent // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP 2333a4311c68348f728558e87b5db67d47605783890Eric Laurent // output is suspended before any tracks are moved to it 234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // outputs must be closed after checkOutputForAllStrategies() is executed 237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputs.isEmpty()) { 238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]); 240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // close unused outputs after device disconnection or direct outputs that have been 241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // opened by checkOutputsForDevice() to query dynamic parameters 2423b73df74357b33869b39a1d69427673c780bd805Eric Laurent if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) || 243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) && 244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (desc->mDirectOpenCount == 0))) { 245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent closeOutput(outputs[i]); 246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2483a4311c68348f728558e87b5db67d47605783890Eric Laurent // check again after closing A2DP output to reset mA2dpSuspended if needed 2493a4311c68348f728558e87b5db67d47605783890Eric Laurent checkA2dpSuspend(); 250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not force device change on duplicated output because if device is 0, it will 255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // also force a device 0 for the two outputs it is duplicated to which may override 256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // a valid device selection on those outputs. 257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(mOutputs.keyAt(i), 258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getNewDevice(mOutputs.keyAt(i), true /*fromCache*/), 259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent !mOutputs.valueAt(i)->isDuplicated(), 260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 0); 261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET) { 264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_WIRED_HEADSET; 265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO || 266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET || 267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 272d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end if is output device 273d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input devices 275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_input_device(device)) { 276d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector <audio_io_handle_t> inputs; 277d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2783a4311c68348f728558e87b5db67d47605783890Eric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device, 2793a4311c68348f728558e87b5db67d47605783890Eric Laurent address, 2802f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent 0); 281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2823a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = mAvailableInputDevices.indexOf(devDesc); 283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (state) 284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input device connection 2863b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: { 2873a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device already connected: %d", device); 289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 291d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (checkInputsForDevice(device, state, inputs, address) != NO_ERROR) { 292d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return INVALID_OPERATION; 293d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 294d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2953a4311c68348f728558e87b5db67d47605783890Eric Laurent index = mAvailableInputDevices.add(devDesc); 2963a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 2973a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices[index]->mId = nextUniqueId(); 2983a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 2993a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_MEMORY; 3003a4311c68348f728558e87b5db67d47605783890Eric Laurent } 301d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } break; 302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input device disconnection 3043b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: { 3053a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index < 0) { 306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device not connected: %d", device); 307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 309d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent checkInputsForDevice(device, state, inputs, address); 3103a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.remove(devDesc); 311d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } break; 312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("setDeviceConnectionState() invalid state: %x", state); 315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 318d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent closeAllInputs(); 319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 321d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end if is input device 322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() invalid device: %x", device); 324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 327e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device, 328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *device_address) 329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3303b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 address = String8(device_address); 3323a4311c68348f728558e87b5db67d47605783890Eric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device, 3333a4311c68348f728558e87b5db67d47605783890Eric Laurent String8(device_address), 3342f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent 0); 3353a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index; 3363a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceVector *deviceVector; 3373a4311c68348f728558e87b5db67d47605783890Eric Laurent 338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_output_device(device)) { 3393a4311c68348f728558e87b5db67d47605783890Eric Laurent deviceVector = &mAvailableOutputDevices; 340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (audio_is_input_device(device)) { 3413a4311c68348f728558e87b5db67d47605783890Eric Laurent deviceVector = &mAvailableInputDevices; 3423a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 3433a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("getDeviceConnectionState() invalid device type %08x", device); 3443a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3473a4311c68348f728558e87b5db67d47605783890Eric Laurent index = deviceVector->indexOf(devDesc); 3483a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 3493a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_AVAILABLE; 3503a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 3513a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 3523a4311c68348f728558e87b5db67d47605783890Eric Laurent } 353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 355e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setPhoneState(audio_mode_t state) 356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() state %d", state); 358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = AUDIO_DEVICE_NONE; 3593b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state < 0 || state >= AUDIO_MODE_CNT) { 360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setPhoneState() invalid state %d", state); 361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (state == mPhoneState ) { 365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setPhoneState() setting same state %d", state); 366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if leaving call state, handle special case of active streams 370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // pertaining to sonification strategy see handleIncallSonification() 371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() in call state management: new state is %d", state); 3733b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 3743b73df74357b33869b39a1d69427673c780bd805Eric Laurent handleIncallSonification((audio_stream_type_t)stream, false, true); 375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // store previous phone state for management of sonification strategy below 379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int oldState = mPhoneState; 380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPhoneState = state; 381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force = false; 382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // are we entering or starting a call 384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isStateInCall(oldState) && isStateInCall(state)) { 385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Entering call in setPhoneState()"); 386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when starting a call 387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j]; 392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isStateInCall(oldState) && !isStateInCall(state)) { 394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Exiting call in setPhoneState()"); 395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when exiting a call 396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[AUDIO_STREAM_DTMF][j]; 401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isStateInCall(state) && (state != oldState)) { 403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when switching between telephony and VoIP 405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check for device and output changes triggered by new phone state 410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/); 411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when ending call 418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) { 420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent newDevice = hwOutputDesc->device(); 421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs = 0; 424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(state)) { 425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute media and sonification strategies and delay device switch by the largest 429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // latency of any output where either strategy is active. 430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This avoid sending the ring tone or music tail into the earpiece or headset. 431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->isStrategyActive(STRATEGY_MEDIA, 432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime) || 434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->isStrategyActive(STRATEGY_SONIFICATION, 435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime)) && 437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (delayMs < (int)desc->mLatency*2)) { 438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs = desc->mLatency*2; 439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); 441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, 442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); 443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i)); 444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS, 445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/)); 446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // change routing is necessary 450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(mPrimaryOutput, newDevice, force, delayMs); 451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if entering in call state, handle special case of active streams 453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // pertaining to sonification strategy see handleIncallSonification() 454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(state)) { 455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() in call state management: new state is %d", state); 4563b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 4573b73df74357b33869b39a1d69427673c780bd805Eric Laurent handleIncallSonification((audio_stream_type_t)stream, true, true); 458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 4623b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state == AUDIO_MODE_RINGTONE && 4633b73df74357b33869b39a1d69427673c780bd805Eric Laurent isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume = true; 465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume = false; 467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 470e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setForceUse(audio_policy_force_use_t usage, 4713b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_forced_cfg_t config) 472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool forceVolumeReeval = false; 476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(usage) { 4773b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_COMMUNICATION: 4783b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO && 4793b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NONE) { 480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4863b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_MEDIA: 4873b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP && 4883b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 4893b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_ANALOG_DOCK && 4903b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE && 4913b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NO_BT_A2DP) { 492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4973b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_RECORD: 4983b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 4993b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NONE) { 500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5053b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_DOCK: 5063b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK && 5073b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_BT_DESK_DOCK && 5083b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 5093b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_ANALOG_DOCK && 5103b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) { 511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5163b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_SYSTEM: 5173b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_NONE && 5183b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { 519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config); 520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid usage %d", usage); 526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check for device and output changes triggered by new force usage 530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = getNewDevice(output, true /*fromCache*/); 536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE)); 537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) { 538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent applyStreamVolumes(output, newDevice, 0, true); 539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t activeInput = getActiveInput(); 543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (activeInput != 0) { 544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); 545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { 547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setForceUse() changing device from %x to %x for input %d", 548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mDevice, newDevice, activeInput); 549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mDevice = newDevice; 550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param = AudioParameter(); 551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); 552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(activeInput, param.toString()); 553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 558e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage) 559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mForceUse[usage]; 561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 563e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setSystemProperty(const char* property, const char* value) 564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setSystemProperty() property %s, value %s", property, value); 566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Find a direct output profile compatible with the parameters passed, even if the input flags do 569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// not explicitly request a direct output 570e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile *AudioPolicyManager::getProfileForDirectOutput( 571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_output_flags_t flags) 576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { 582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; 5833a4311c68348f728558e87b5db67d47605783890Eric Laurent bool found = false; 584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { 585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, 587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) { 5883a4311c68348f728558e87b5db67d47605783890Eric Laurent found = true; 589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, 593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_OUTPUT_FLAG_DIRECT)) { 5943a4311c68348f728558e87b5db67d47605783890Eric Laurent found = true; 595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5973a4311c68348f728558e87b5db67d47605783890Eric Laurent if (found && (mAvailableOutputDevices.types() & profile->mSupportedDevices.types())) { 5983a4311c68348f728558e87b5db67d47605783890Eric Laurent return profile; 5993a4311c68348f728558e87b5db67d47605783890Eric Laurent } 600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 605e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream, 606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 6093b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_output_flags_t flags, 610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const audio_offload_info_t *offloadInfo) 611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = 0; 613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t latency = 0; 6143b73df74357b33869b39a1d69427673c780bd805Eric Laurent routing_strategy strategy = getStrategy(stream); 615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x", 617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, stream, samplingRate, format, channelMask, flags); 618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mCurOutput != 0) { 621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", 622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTestOutputs[mCurOutput] == 0) { 625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() opening test output"); 626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = mTestDevice; 628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate = mTestSamplingRate; 629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFormat = mTestFormat; 630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mChannelMask = mTestChannels; 631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency = mTestLatencyMs; 6323b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc->mFlags = 6333b73df74357b33869b39a1d69427673c780bd805Eric Laurent (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0); 634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mRefCount[stream] = 0; 635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice, 636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags, 641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo); 642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTestOutputs[mCurOutput]) { 643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"),mCurOutput); 645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(mTestOutputs[mCurOutput], outputDesc); 647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mTestOutputs[mCurOutput]; 650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open a direct output if required by specified parameters 654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //force direct flag if offload flag is set: offloading implies a direct output stream 655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and all common behaviors are driven by checking only the direct flag 656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this should normally be set appropriately in the policy configuration file 657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 6583b73df74357b33869b39a1d69427673c780bd805Eric Laurent flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT); 659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // detects there is an active non offloadable effect. 664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the background. 667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent IOProfile *profile = NULL; 668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) || 669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent !isNonOffloadableEffectEnabled()) { 670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile = getProfileForDirectOutput(device, 671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, 672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent format, 673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, 674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (audio_output_flags_t)flags); 675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile != NULL) { 678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = NULL; 679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && (profile == desc->mProfile)) { 683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc = desc; 684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // reuse direct output if currently open and configured with same parameters 685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((samplingRate == outputDesc->mSamplingRate) && 686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (format == outputDesc->mFormat) && 687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (channelMask == outputDesc->mChannelMask)) { 688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDirectOpenCount++; 689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i)); 690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutputs.keyAt(i); 691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // close direct output if currently open and configured with different parameters 695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc != NULL) { 696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent closeOutput(outputDesc->mId); 697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc = new AudioOutputDescriptor(profile); 699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = device; 700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate = samplingRate; 701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFormat = format; 702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mChannelMask = channelMask; 703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency = 0; 704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags); 705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mRefCount[stream] = 0; 706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStopTime[stream] = 0; 707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDirectOpenCount = 1; 708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output = mpClientInterface->openOutput(profile->mModule->mHandle, 709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mDevice, 710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags, 715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo); 716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // only accept an output with the requested parameters 718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == 0 || 719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || 720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (format != AUDIO_FORMAT_DEFAULT && format != outputDesc->mFormat) || 721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { 722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," 723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "format %d %d, channelMask %04x %04x", output, samplingRate, 724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, 725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mChannelMask); 726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output != 0) { 727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete outputDesc; 730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t srcOutput = getOutputForEffect(); 733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, outputDesc); 734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dstOutput == output) { 736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput); 737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() returns new direct output %d", output); 740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ignoring channel mask due to downmix capability in mixer 744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open a non direct output 746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // for non direct outputs, only PCM is supported 748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_linear_pcm(format)) { 749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // get which output is suitable for the specified stream. The actual 750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // routing change will happen when startOutput() will be called 751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs); 752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output = selectOutput(outputs, flags); 754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d," 756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); 757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() returns output %d", output); 759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 763e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs, 7643b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_output_flags_t flags) 765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // select one output among several that provide a path to a particular device or set of 767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // devices (the list was previously build by getOutputsForDevice()). 768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The priority is as follows: 769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: the output with the highest number of requested policy flags 770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: the primary output 771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the first output in the list 772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 0) { 774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 1) { 777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int maxCommonFlags = 0; 781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputFlags = 0; 782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputPrimary = 0; 783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]); 786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputDesc->isDuplicated()) { 7873b73df74357b33869b39a1d69427673c780bd805Eric Laurent int commonFlags = popcount(outputDesc->mProfile->mFlags & flags); 788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (commonFlags > maxCommonFlags) { 789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputFlags = outputs[i]; 790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent maxCommonFlags = commonFlags; 791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); 792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputPrimary = outputs[i]; 795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputFlags != 0) { 800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputFlags; 801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputPrimary != 0) { 803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputPrimary; 804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 809e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startOutput(audio_io_handle_t output, 8103b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream, 811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session) 812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startOutput() unknown output %d", output); 817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // increment usage count for this stream on the requested output: 823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // NOTE that the usage count is the same for duplicated output and hardware output which is 824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // necessary for a correct control of hardware output routing by startOutput() and stopOutput() 825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->changeRefCount(stream, 1); 826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] == 1) { 828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent routing_strategy strategy = getStrategy(stream); 830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool shouldWait = (strategy == STRATEGY_SONIFICATION) || 831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (strategy == STRATEGY_SONIFICATION_RESPECTFUL); 832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t waitMs = 0; 833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force = false; 834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc != outputDesc) { 837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force a device change if any other output is managed by the same hw 838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // module and has a current device selection that differs from selected device. 839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // In this case, the audio HAL must receive the new device selection so that it can 840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // change the device currently selected by the other active output. 841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->sharesHwModuleWith(desc) && 842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->device() != newDevice) { 843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // wait for audio on other active outputs to be presented when starting 846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // a notification so that audio focus effect can propagate. 847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t latency = desc->latency(); 848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { 849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent waitMs = latency; 850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); 854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle special case for sonification while in call 856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleIncallSonification(stream, true, false); 858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // apply volume rules for current stream and device if necessary 861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].getVolumeIndex(newDevice), 863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent newDevice); 865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update the outputs if starting an output with a stream that can affect notification 867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // routing 868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleNotificationRoutingForStream(stream); 869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (waitMs > muteWaitMs) { 870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent usleep((waitMs - muteWaitMs) * 2 * 1000); 871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 877e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopOutput(audio_io_handle_t output, 8783b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream, 879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session) 880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopOutput() unknown output %d", output); 885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle special case for sonification while in call 891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleIncallSonification(stream, false, false); 893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] > 0) { 896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // decrement usage count of this stream on the output 897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->changeRefCount(stream, -1); 898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // store time at which the stream was stopped - see isStreamActive() 899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] == 0) { 900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStopTime[stream] = systemTime(); 901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); 902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // delay the device switch by twice the latency because stopOutput() is executed when 903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the track stop() command is received and at that time the audio track buffer can 904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // still contain data that needs to be drained. The latency only covers the audio HAL 905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and kernel buffers. Also the latency does not always include additional delay in the 906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // audio path (audio DSP, CODEC ...) 907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); 908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force restoring the device selection on other active outputs if it differs from the 910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // one being selected for this output 911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(i); 913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (curOutput != output && 915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->isActive() && 916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->sharesHwModuleWith(desc) && 917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (newDevice != desc->device())) { 918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(curOutput, 919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getNewDevice(curOutput, false /*fromCache*/), 920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent true, 921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency*2); 922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update the outputs if stopping one with a stream that can affect notification routing 925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleNotificationRoutingForStream(stream); 926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopOutput() refcount is already 0 for output %d", output); 930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 934e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::releaseOutput(audio_io_handle_t output) 935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseOutput() %d", output); 937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseOutput() releasing unknown output %d", output); 940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int testIndex = testOutputIndex(output); 945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (testIndex != 0) { 946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isActive()) { 948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mOutputs.valueAt(index); 950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(output); 951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[testIndex] = 0; 952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(index); 9583b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { 959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->mDirectOpenCount <= 0) { 960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseOutput() invalid open count %d for output %d", 961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mDirectOpenCount, output); 962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (--desc->mDirectOpenCount == 0) { 965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent closeOutput(output); 966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // If effects where present on the output, audioflinger moved them to the primary 967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // output by default: move them back to the appropriate output. 968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dstOutput != mPrimaryOutput) { 970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput); 971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 977e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, 978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 9813b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_in_acoustics_t acoustics) 982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t input = 0; 984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForInputSource(inputSource); 985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x", 987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputSource, samplingRate, format, channelMask, acoustics); 988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getInput() could not find device for inputSource %d", inputSource); 991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // adapt channel selection to input source 995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(inputSource) { 996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK; 998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_DOWNLINK: 1000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK; 1001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_CALL: 1003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK; 1004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 1006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent IOProfile *profile = getInputProfile(device, 1010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, 1011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent format, 1012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask); 1013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile == NULL) { 1014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d, " 1015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "channelMask %04x", 1016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, samplingRate, format, channelMask); 1017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mModule->mHandle == 0) { 1021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); 1022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile); 1026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mInputSource = inputSource; 1028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mDevice = device; 1029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mSamplingRate = samplingRate; 1030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mFormat = format; 1031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mChannelMask = channelMask; 1032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mRefCount = 0; 1033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent input = mpClientInterface->openInput(profile->mModule->mHandle, 1034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &inputDesc->mDevice, 1035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &inputDesc->mSamplingRate, 1036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &inputDesc->mFormat, 1037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &inputDesc->mChannelMask); 1038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // only accept input with the exact requested set of parameters 1040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (input == 0 || 1041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (samplingRate != inputDesc->mSamplingRate) || 1042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (format != inputDesc->mFormat) || 1043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (channelMask != inputDesc->mChannelMask)) { 1044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGI("getInput() failed opening input: samplingRate %d, format %d, channelMask %x", 1045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, format, channelMask); 1046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (input != 0) { 1047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeInput(input); 1048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete inputDesc; 1050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1052d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addInput(input, inputDesc); 1053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return input; 1054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1056e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startInput(audio_io_handle_t input) 1057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("startInput() input %d", input); 1059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startInput() unknown input %d", input); 1062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 1065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTestInput == 0) 1068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // refuse 2 active AudioRecord clients at the same time except if the active input 1071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // uses AUDIO_SOURCE_HOTWORD in which case it is closed. 1072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t activeInput = getActiveInput(); 1073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isVirtualInputDevice(inputDesc->mDevice) && activeInput != 0) { 1074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput); 1075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) { 1076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startInput() preempting already started low-priority input %d", activeInput); 1077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stopInput(activeInput); 1078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent releaseInput(activeInput); 1079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startInput() input %d failed: other input already started", input); 1081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); 1087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { 1088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mDevice = newDevice; 1089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // automatically enable the remote submix output when input is started 1092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 10943b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_POLICY_DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 1095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param = AudioParameter(); 1098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice); 1099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int aliasSource = (inputDesc->mInputSource == AUDIO_SOURCE_HOTWORD) ? 1101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_SOURCE_VOICE_RECOGNITION : inputDesc->mInputSource; 1102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.addInt(String8(AudioParameter::keyInputSource), aliasSource); 1104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 1105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(input, param.toString()); 1107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mRefCount = 1; 1109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1112e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopInput(audio_io_handle_t input) 1113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("stopInput() input %d", input); 1115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopInput() unknown input %d", input); 1118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 1121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (inputDesc->mRefCount == 0) { 1123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopInput() input %d already stopped", input); 1124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // automatically disable the remote submix output when input is stopped 1127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 11293b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 1130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param = AudioParameter(); 1133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.addInt(String8(AudioParameter::keyRouting), 0); 1134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(input, param.toString()); 1135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mRefCount = 0; 1136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1140e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::releaseInput(audio_io_handle_t input) 1141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseInput() %d", input); 1143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseInput() releasing unknown input %d", input); 1146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeInput(input); 1149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mInputs.valueAt(index); 1150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputs.removeItem(input); 1151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseInput() exit"); 1152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1154d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::closeAllInputs() { 1155d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for(size_t input_index = 0; input_index < mInputs.size(); input_index++) { 1156d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeInput(mInputs.keyAt(input_index)); 1157d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 1158d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mInputs.clear(); 1159d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 1160d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 1161e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initStreamVolume(audio_stream_type_t stream, 1162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexMin, 1163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexMax) 1164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 1166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (indexMin < 0 || indexMin >= indexMax) { 1167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 1168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexMin = indexMin; 1171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexMax = indexMax; 1172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1174e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream, 1175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 1176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 1177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 1180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device)) { 1183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force max volume if stream cannot be muted 1187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 1188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", 1190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, device, index); 1191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 1193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // clear all device specific values 1194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexCur.clear(); 1196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 1198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // compute and apply stream volume on all outputs according to connected device 1200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t status = NO_ERROR; 1201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t curDevice = 1203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForVolume(mOutputs.valueAt(i)->device()); 1204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) { 1205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); 1206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volStatus != NO_ERROR) { 1207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = volStatus; 1208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return status; 1212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1214e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream, 1215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int *index, 1216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 1217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index == NULL) { 1219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device)) { 1222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 1225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the strategy the stream belongs to. 1226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); 1228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForVolume(device); 1230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 1232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 1233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1236e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutputForEffects( 1237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const SortedVector<audio_io_handle_t>& outputs) 1238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // select one output among several suitable for global effects. 1240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The priority is as follows: 1241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: An offloaded output. If the effect ends up not being offloadable, 1242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // AudioFlinger will invalidate the track and the offloaded output 1243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // will be closed causing the effect to be moved to a PCM output. 1244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: A deep buffer output 1245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the first output in the list 1246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 0) { 1248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputOffloaded = 0; 1252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputDeepBuffer = 0; 1253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 1255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]); 1256d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags); 1257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 1258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputOffloaded = outputs[i]; 1259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) { 1261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDeepBuffer = outputs[i]; 1262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d", 1266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputOffloaded, outputDeepBuffer); 1267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputOffloaded != 0) { 1268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputOffloaded; 1269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDeepBuffer != 0) { 1271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputDeepBuffer; 1272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 1275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1277e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc) 1278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // apply simple rule where global effects are attached to the same output as MUSIC streams 1280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 12813b73df74357b33869b39a1d69427673c780bd805Eric Laurent routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC); 1282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 1283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs); 1284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = selectOutputForEffects(dstOutputs); 1286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutputForEffect() got output %d for fx %s flags %x", 1287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, (desc == NULL) ? "unspecified" : desc->name, (desc == NULL) ? 0 : desc->flags); 1288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 1290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1292e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc, 1293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t io, 1294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t strategy, 1295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session, 1296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int id) 1297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 1299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent index = mInputs.indexOfKey(io); 1301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("registerEffect() unknown io %d", io); 1303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 1308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 1309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->name, desc->memoryUsage); 1310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsMemory += desc->memoryUsage; 1313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 1314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->name, io, strategy, session, id); 1315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 1316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent EffectDescriptor *pDesc = new EffectDescriptor(); 1318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t)); 1319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mIo = io; 1320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mStrategy = (routing_strategy)strategy; 1321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mSession = session; 1322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mEnabled = false; 1323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.add(id, pDesc); 1325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1329e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::unregisterEffect(int id) 1330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() unknown effect ID %d", id); 1334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent EffectDescriptor *pDesc = mEffects.valueAt(index); 1338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setEffectEnabled(pDesc, false); 1340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) { 1342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() memory %d too big for total %d", 1343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.memoryUsage = mTotalEffectsMemory; 1345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsMemory -= pDesc->mDesc.memoryUsage; 1347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 1348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.removeItem(id); 1351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete pDesc; 1352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1356e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(int id, bool enabled) 1357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() unknown effect ID %d", id); 1361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 1365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1367e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(EffectDescriptor *pDesc, bool enabled) 1368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (enabled == pDesc->mEnabled) { 1370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(%s) effect already %s", 1371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 1372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (enabled) { 1376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 1377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 1378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10); 1379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad; 1382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 1383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) { 1385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 1386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 1387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 1388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad; 1390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 1391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mEnabled = enabled; 1393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1396e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isNonOffloadableEffectEnabled() 1397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 1399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const EffectDescriptor * const pDesc = mEffects.valueAt(i); 1400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (pDesc->mEnabled && (pDesc->mStrategy == STRATEGY_MEDIA) && 1401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((pDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) { 1402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d", 1403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.name, pDesc->mSession); 1404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1410e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 1411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 1413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 14153b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 1416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1422e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, 14233b73df74357b33869b39a1d69427673c780bd805Eric Laurent uint32_t inPastMs) const 1424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 1426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 1428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 14293b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 1430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1436e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isSourceActive(audio_source_t source) const 1437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 1439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const AudioInputDescriptor * inputDescriptor = mInputs.valueAt(i); 1440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((inputDescriptor->mInputSource == (int)source || 14413b73df74357b33869b39a1d69427673c780bd805Eric Laurent (source == AUDIO_SOURCE_VOICE_RECOGNITION && 1442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) 1443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent && (inputDescriptor->mRefCount > 0)) { 1444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1451e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::dump(int fd) 1452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 1454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 1455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 1456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 1458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 1459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput); 1461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 1462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 1463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 14643b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for communications %d\n", 14653b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]); 1466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 14673b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA]); 1468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 14693b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD]); 1470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 14713b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK]); 1472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 14733b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM]); 1474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 1475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14763a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, " Available output devices:\n"); 14773a4311c68348f728558e87b5db67d47605783890Eric Laurent result.append(buffer); 14783a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, result.string(), result.size()); 14793a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceDescriptor::dumpHeader(fd, 2); 14803a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) { 14813a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices[i]->dump(fd, 2); 14823a4311c68348f728558e87b5db67d47605783890Eric Laurent } 14833a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, "\n Available input devices:\n"); 14843a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, buffer, strlen(buffer)); 14853a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceDescriptor::dumpHeader(fd, 2); 14863a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size(); i++) { 14873a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices[i]->dump(fd, 2); 14883a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 1491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 1493d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1); 1494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules[i]->dump(fd); 1496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nOutputs dump:\n"); 1499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 1502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.valueAt(i)->dump(fd); 1504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nInputs dump:\n"); 1507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 1509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 1510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputs.valueAt(i)->dump(fd); 1512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nStreams dump:\n"); 1515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, 1517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 1518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 15193b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 1520d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " %02zu ", i); 1521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[i].dump(fd); 1523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 1526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 1527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "Registered effects:\n"); 1530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 1532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 1533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.valueAt(i)->dump(fd); 1535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This function checks for the parameters which can be offloaded. 1542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This can be enhanced depending on the capability of the DSP and policy 1543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// of the system. 1544e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo) 1545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d," 1547d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent " BitRate=%u, duration=%" PRId64 " us, has_video=%d", 1548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate, offloadInfo.channel_mask, 1549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format, 1550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us, 1551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.has_video); 1552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check if offload has been disabled 1554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char propValue[PROPERTY_VALUE_MAX]; 1555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (property_get("audio.offload.disable", propValue, "0")) { 1556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (atoi(propValue) != 0) { 1557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("offload disabled by audio.offload.disable=%s", propValue ); 1558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check if stream type is music, then only allow offload as of now. 1563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC) 1564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: stream_type != MUSIC, returning false"); 1566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //TODO: enable audio offloading with video when ready 1570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.has_video) 1571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: has_video == true, returning false"); 1573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //If duration is less than minimum value defined in property, return false 1577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (property_get("audio.offload.min.duration.secs", propValue, NULL)) { 1578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) { 1579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue); 1580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) { 1583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS); 1584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 1588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 1589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // detects there is an active non offloadable effect. 1590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 1591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 1592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the background. 1593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isNonOffloadableEffectEnabled()) { 1594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // See if there is a profile to support this. 1598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // AUDIO_DEVICE_NONE 1599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent IOProfile *profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */, 1600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate, 1601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format, 1602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.channel_mask, 1603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD); 1604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported() profile %sfound", profile != NULL ? "" : "NOT "); 1605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (profile != NULL); 1606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 1609e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent// AudioPolicyManager 1610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 1611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16123a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::nextUniqueId() 16133a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 16143a4311c68348f728558e87b5db67d47605783890Eric Laurent return android_atomic_inc(&mNextUniqueId); 16153a4311c68348f728558e87b5db67d47605783890Eric Laurent} 16163a4311c68348f728558e87b5db67d47605783890Eric Laurent 1617e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) 1618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : 1619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent Thread(false), 1621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput((audio_io_handle_t)0), 16233b73df74357b33869b39a1d69427673c780bd805Eric Laurent mPhoneState(AUDIO_MODE_NORMAL), 1624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 1625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 16263a4311c68348f728558e87b5db67d47605783890Eric Laurent mA2dpSuspended(false), 16273a4311c68348f728558e87b5db67d47605783890Eric Laurent mSpeakerDrcEnabled(false), mNextUniqueId(0) 1628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface = clientInterface; 1630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16313b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) { 16323b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[i] = AUDIO_POLICY_FORCE_NONE; 1633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16353a4311c68348f728558e87b5db67d47605783890Eric Laurent mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER); 1636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { 1637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { 1638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("could not load audio policy configuration file, setting defaults"); 1639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent defaultAudioPolicyConfig(); 1640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 16423a4311c68348f728558e87b5db67d47605783890Eric Laurent // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices 1643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // must be done after reading the policy 1645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent initializeVolumeCurves(); 1646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open all output streams needed to access attached devices 16483a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types(); 16493a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN; 1650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 1651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 1652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 1653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("could not open HW module %s", mHwModules[i]->mName); 1654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 1655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open all output streams needed to access attached devices 1657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // except for direct output streams that are only opened when they are actually 1658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // required by an app. 16593a4311c68348f728558e87b5db67d47605783890Eric Laurent // This also validates mAvailableOutputDevices list 1660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 1661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j]; 1663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16643a4311c68348f728558e87b5db67d47605783890Eric Laurent if (outProfile->mSupportedDevices.isEmpty()) { 16653a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName); 16663a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 16673a4311c68348f728558e87b5db67d47605783890Eric Laurent } 16683a4311c68348f728558e87b5db67d47605783890Eric Laurent 16693a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t profileTypes = outProfile->mSupportedDevices.types(); 16703a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((profileTypes & outputDeviceTypes) && 1671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) { 1672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile); 16733a4311c68348f728558e87b5db67d47605783890Eric Laurent 16743a4311c68348f728558e87b5db67d47605783890Eric Laurent outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice->mType & profileTypes); 1675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput( 1676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outProfile->mModule->mHandle, 1677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mDevice, 1678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 1679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 1680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 1681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 1682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags); 1683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == 0) { 16843a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Cannot open output stream for device %08x on hw module %s", 16853a4311c68348f728558e87b5db67d47605783890Eric Laurent outputDesc->mDevice, 16863a4311c68348f728558e87b5db67d47605783890Eric Laurent mHwModules[i]->mName); 1687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete outputDesc; 1688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 16895b61dddd0dba28922068da2487894761486aec6cEric Laurent for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { 16905b61dddd0dba28922068da2487894761486aec6cEric Laurent audio_devices_t type = outProfile->mSupportedDevices[k]->mType; 16913a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = 16925b61dddd0dba28922068da2487894761486aec6cEric Laurent mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]); 16933a4311c68348f728558e87b5db67d47605783890Eric Laurent // give a valid ID to an attached device once confirmed it is reachable 16943a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((index >= 0) && (mAvailableOutputDevices[index]->mId == 0)) { 16953a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices[index]->mId = nextUniqueId(); 16963a4311c68348f728558e87b5db67d47605783890Eric Laurent } 16973a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput == 0 && 1699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 1700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput = output; 1701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, outputDesc); 1703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, 17043a4311c68348f728558e87b5db67d47605783890Eric Laurent outputDesc->mDevice, 1705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent true); 1706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 17093a4311c68348f728558e87b5db67d47605783890Eric Laurent // open input streams needed to access attached devices to validate 17103a4311c68348f728558e87b5db67d47605783890Eric Laurent // mAvailableInputDevices list 17113a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 17123a4311c68348f728558e87b5db67d47605783890Eric Laurent { 17133a4311c68348f728558e87b5db67d47605783890Eric Laurent const IOProfile *inProfile = mHwModules[i]->mInputProfiles[j]; 17143a4311c68348f728558e87b5db67d47605783890Eric Laurent 17153a4311c68348f728558e87b5db67d47605783890Eric Laurent if (inProfile->mSupportedDevices.isEmpty()) { 17163a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName); 17173a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 17183a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 17203a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t profileTypes = inProfile->mSupportedDevices.types(); 17213a4311c68348f728558e87b5db67d47605783890Eric Laurent if (profileTypes & inputDeviceTypes) { 17223a4311c68348f728558e87b5db67d47605783890Eric Laurent AudioInputDescriptor *inputDesc = new AudioInputDescriptor(inProfile); 17233a4311c68348f728558e87b5db67d47605783890Eric Laurent 17243a4311c68348f728558e87b5db67d47605783890Eric Laurent inputDesc->mInputSource = AUDIO_SOURCE_MIC; 17253a4311c68348f728558e87b5db67d47605783890Eric Laurent inputDesc->mDevice = inProfile->mSupportedDevices[0]->mType; 17263a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_io_handle_t input = mpClientInterface->openInput( 17273a4311c68348f728558e87b5db67d47605783890Eric Laurent inProfile->mModule->mHandle, 17283a4311c68348f728558e87b5db67d47605783890Eric Laurent &inputDesc->mDevice, 17293a4311c68348f728558e87b5db67d47605783890Eric Laurent &inputDesc->mSamplingRate, 17303a4311c68348f728558e87b5db67d47605783890Eric Laurent &inputDesc->mFormat, 17313a4311c68348f728558e87b5db67d47605783890Eric Laurent &inputDesc->mChannelMask); 17323a4311c68348f728558e87b5db67d47605783890Eric Laurent 17333a4311c68348f728558e87b5db67d47605783890Eric Laurent if (input != 0) { 17345b61dddd0dba28922068da2487894761486aec6cEric Laurent for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { 17355b61dddd0dba28922068da2487894761486aec6cEric Laurent audio_devices_t type = inProfile->mSupportedDevices[k]->mType; 17363a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = 17375b61dddd0dba28922068da2487894761486aec6cEric Laurent mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]); 17383a4311c68348f728558e87b5db67d47605783890Eric Laurent // give a valid ID to an attached device once confirmed it is reachable 17393a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((index >= 0) && (mAvailableInputDevices[index]->mId == 0)) { 17403a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices[index]->mId = nextUniqueId(); 17413a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17423a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17433a4311c68348f728558e87b5db67d47605783890Eric Laurent mpClientInterface->closeInput(input); 17443a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 17453a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Cannot open input stream for device %08x on hw module %s", 17463a4311c68348f728558e87b5db67d47605783890Eric Laurent inputDesc->mDevice, 17473a4311c68348f728558e87b5db67d47605783890Eric Laurent mHwModules[i]->mName); 17483a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17493a4311c68348f728558e87b5db67d47605783890Eric Laurent delete inputDesc; 17503a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17513a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17523a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17533a4311c68348f728558e87b5db67d47605783890Eric Laurent // make sure all attached devices have been allocated a unique ID 17543a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableOutputDevices.size();) { 17553a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableOutputDevices[i]->mId == 0) { 17563a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mType); 17573a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.remove(mAvailableOutputDevices[i]); 17583a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 17593a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17603a4311c68348f728558e87b5db67d47605783890Eric Laurent i++; 17613a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17623a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size();) { 17633a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableInputDevices[i]->mId == 0) { 17643a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mType); 17653a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.remove(mAvailableInputDevices[i]); 17663a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 17673a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17683a4311c68348f728558e87b5db67d47605783890Eric Laurent i++; 17693a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17703a4311c68348f728558e87b5db67d47605783890Eric Laurent // make sure default device is reachable 17713a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) { 17723a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mType); 17733a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 1776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 1778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput != 0) { 1781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 1782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"), 0); 1783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestDevice = AUDIO_DEVICE_OUT_SPEAKER; 1786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestSamplingRate = 44100; 17873b73df74357b33869b39a1d69427673c780bd805Eric Laurent mTestFormat = AUDIO_FORMAT_PCM_16_BIT; 17883b73df74357b33869b39a1d69427673c780bd805Eric Laurent mTestChannels = AUDIO_CHANNEL_OUT_STEREO; 1789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestLatencyMs = 0; 1790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput = 0; 1791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = false; 1792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[i] = 0; 1794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 1797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 1798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 1799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent run(buffer, ANDROID_PRIORITY_AUDIO); 1800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1804e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::~AudioPolicyManager() 1805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent exit(); 1808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(mOutputs.keyAt(i)); 1811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mOutputs.valueAt(i); 1812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 1814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeInput(mInputs.keyAt(i)); 1815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mInputs.valueAt(i); 1816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 1818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mHwModules[i]; 1819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 18203a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.clear(); 18213a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.clear(); 1822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1824e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::initCheck() 1825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; 1827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1830e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::threadLoop() 1831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("entering threadLoop()"); 1833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (!exitPending()) 1834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 command; 1836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int valueInt; 1837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 value; 1838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent Mutex::Autolock _l(mLock); 1840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 1841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 1843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param = AudioParameter(command); 1844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 1846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent valueInt != 0) { 1847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Test command %s received", command.string()); 1848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 target; 1849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("target"), target) != NO_ERROR) { 1850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent target = "Manager"; 1851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 1853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_output")); 1854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput = valueInt; 1855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 1857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_direct")); 1858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "false") { 1859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = false; 1860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "true") { 1861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = true; 1862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 1865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_input")); 1866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestInput = valueInt; 1867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 1870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_format")); 18713b73df74357b33869b39a1d69427673c780bd805Eric Laurent int format = AUDIO_FORMAT_INVALID; 1872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "PCM 16 bits") { 18733b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_PCM_16_BIT; 1874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "PCM 8 bits") { 18753b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_PCM_8_BIT; 1876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "Compressed MP3") { 18773b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_MP3; 1878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 18793b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (format != AUDIO_FORMAT_INVALID) { 1880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 1881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestFormat = format; 1882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 1883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 1884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("format"), format); 1885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 1890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_channels")); 1891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int channels = 0; 1892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "Channels Stereo") { 18943b73df74357b33869b39a1d69427673c780bd805Eric Laurent channels = AUDIO_CHANNEL_OUT_STEREO; 1895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "Channels Mono") { 18963b73df74357b33869b39a1d69427673c780bd805Eric Laurent channels = AUDIO_CHANNEL_OUT_MONO; 1897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (channels != 0) { 1899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 1900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestChannels = channels; 1901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 1902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 1903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("channels"), channels); 1904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 1909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_sampleRate")); 1910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (valueInt >= 0 && valueInt <= 96000) { 1911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int samplingRate = valueInt; 1912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 1913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestSamplingRate = samplingRate; 1914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 1915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 1916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("sampling_rate"), samplingRate); 1917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 1923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_reopen")); 1924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 1926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(mPrimaryOutput); 1927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; 1929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mOutputs.valueFor(mPrimaryOutput); 1931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(mPrimaryOutput); 1932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 1934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; 1935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput = mpClientInterface->openOutput(moduleHandle, 1936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mDevice, 1937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 1938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 1939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 1940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 1941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags); 1942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput == 0) { 1943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d", 1944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); 1945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 1947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"), 0); 1948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(mPrimaryOutput, outputDesc); 1950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 1955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1960e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::exit() 1961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AutoMutex _l(mLock); 1964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent requestExit(); 1965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mWaitWorkCV.signal(); 1966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent requestExitAndWait(); 1968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1970e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::testOutputIndex(audio_io_handle_t output) 1971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == mTestOutputs[i]) return i; 1974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- 1980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1981e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc) 1982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mId = id; 1984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.add(id, outputDesc); 1985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1987d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::addInput(audio_io_handle_t id, AudioInputDescriptor *inputDesc) 1988d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 1989d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputDesc->mId = id; 1990d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mInputs.add(id, inputDesc); 1991d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 1992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19933a4311c68348f728558e87b5db67d47605783890Eric LaurentString8 AudioPolicyManager::addressToParameter(audio_devices_t device, const String8 address) 19943a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 19953a4311c68348f728558e87b5db67d47605783890Eric Laurent if (device & AUDIO_DEVICE_OUT_ALL_A2DP) { 19963a4311c68348f728558e87b5db67d47605783890Eric Laurent return String8("a2dp_sink_address=")+address; 19973a4311c68348f728558e87b5db67d47605783890Eric Laurent } 19983a4311c68348f728558e87b5db67d47605783890Eric Laurent return address; 19993a4311c68348f728558e87b5db67d47605783890Eric Laurent} 20003a4311c68348f728558e87b5db67d47605783890Eric Laurent 2001e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, 20023b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state, 2003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t>& outputs, 20043a4311c68348f728558e87b5db67d47605783890Eric Laurent const String8 address) 2005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc; 2007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 20083b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { 2009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // first list already open outputs that can be routed to this device 2010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(i); 20123a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) { 2013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i)); 2014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(mOutputs.keyAt(i)); 2015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // then look for output profiles that can be routed to this device 2018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<IOProfile *> profiles; 2019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 2020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 2022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 2025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 20263a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) { 2027d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i); 2028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profiles.add(mHwModules[i]->mOutputProfiles[j]); 2029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profiles.isEmpty() && outputs.isEmpty()) { 2034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 2035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 2036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open outputs for matching profiles if needed. Direct outputs are also opened to 2039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 2040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 2041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent IOProfile *profile = profiles[profile_index]; 2042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // nothing to do if one output is already opened for this profile 2044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent size_t j; 2045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (j = 0; j < mOutputs.size(); j++) { 2046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(j); 2047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && desc->mProfile == profile) { 2048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (j != mOutputs.size()) { 2052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 20553a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("opening output for device %08x with params %s", device, address.string()); 2056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = new AudioOutputDescriptor(profile); 2057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mDevice = device; 2058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; 2059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate = desc->mSamplingRate; 2060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format = desc->mFormat; 2061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.channel_mask = desc->mChannelMask; 2062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle, 2064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mDevice, 2065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mSamplingRate, 2066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mFormat, 2067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mChannelMask, 2068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mLatency, 2069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mFlags, 2070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &offloadInfo); 2071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output != 0) { 2072d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where the out_set_parameters() for card & device gets called 20733a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!address.isEmpty()) { 20743a4311c68348f728558e87b5db67d47605783890Eric Laurent mpClientInterface->setParameters(output, addressToParameter(device, address)); 2075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2077d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where we step through and resolve any "dynamic" fields 2078d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 reply; 2079d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char *value; 2080d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 2081d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 2082d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 2083d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice() direct output sup sampling rates %s", 2084d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2085d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2086d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 2087d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent loadSamplingRates(value + 1, profile); 2088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2089d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2090d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2091d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 2092d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 2093d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice() direct output sup formats %s", 2094d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2095d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2096d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 2097d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent loadFormats(value + 1, profile); 2098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2099d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2100d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 2101d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 2102d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 2103d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice() direct output sup channel masks %s", 2104d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2105d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2106d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 2107d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent loadOutChannels(value + 1, profile); 2108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2109d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2110d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (((profile->mSamplingRates[0] == 0) && 2111d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mSamplingRates.size() < 2)) || 2112d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) && 2113d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mFormats.size() < 2)) || 2114d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mChannelMasks[0] == 0) && 2115d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mChannelMasks.size() < 2))) { 2116d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkOutputsForDevice() direct output missing param"); 2117d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 2118d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent output = 0; 2119d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else if (profile->mSamplingRates[0] == 0) { 2120d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 2121d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc->mSamplingRate = profile->mSamplingRates[1]; 2122d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent offloadInfo.sample_rate = desc->mSamplingRate; 2123d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent output = mpClientInterface->openOutput( 2124d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mModule->mHandle, 2125d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mDevice, 2126d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mSamplingRate, 2127d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mFormat, 2128d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mChannelMask, 2129d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mLatency, 2130d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc->mFlags, 2131d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &offloadInfo); 2132d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2133d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2134d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (output != 0) { 2135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, desc); 2136d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { 2137d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent audio_io_handle_t duplicatedOutput = 0; 2138d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2139d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // set initial stream volume for device 2140d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent applyStreamVolumes(output, device, 0, true); 2141d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2142d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent //TODO: configure audio effect output stage here 2143d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2144d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // open a duplicating output thread for the new output and the primary output 2145d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent duplicatedOutput = mpClientInterface->openDuplicateOutput(output, 2146d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mPrimaryOutput); 2147d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (duplicatedOutput != 0) { 2148d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // add duplicated output descriptor 2149d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL); 2150d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); 2151d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mOutput2 = mOutputs.valueFor(output); 2152d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mSamplingRate = desc->mSamplingRate; 2153d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mFormat = desc->mFormat; 2154d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mChannelMask = desc->mChannelMask; 2155d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mLatency = desc->mLatency; 2156d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addOutput(duplicatedOutput, dupOutputDesc); 2157d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent applyStreamVolumes(duplicatedOutput, device, 0, true); 2158d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 2159d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkOutputsForDevice() could not open dup output for %d and %d", 2160d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mPrimaryOutput, output); 2161d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 2162d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mOutputs.removeItem(output); 2163d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent output = 0; 2164d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == 0) { 2169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice() could not open output for device %x", device); 2170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete desc; 2171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profiles.removeAt(profile_index); 2172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile_index--; 2173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(output); 2175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputsForDevice(): adding output %d", output); 2176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profiles.isEmpty()) { 2180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 2181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 2182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2183d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { // Disconnect 2184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check if one opened output is not needed any more after disconnecting one device 2185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(i); 2187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && 21883a4311c68348f728558e87b5db67d47605783890Eric Laurent !(desc->mProfile->mSupportedDevices.types() & 21893a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.types())) { 2190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i)); 2191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(mOutputs.keyAt(i)); 2192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2194d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Clear any profiles associated with the disconnected device. 2195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 2196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 2198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 2201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; 2203d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSupportedDevices.types() & device) { 2204d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice(): " 2205d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent "clearing direct output profile %zu on module %zu", j, i); 2206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mSamplingRates[0] == 0) { 2207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.clear(); 2208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(0); 2209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.clear(); 2212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 2213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mChannelMasks[0] == 0) { 2215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.clear(); 2216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(0); 2217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 2223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2225d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentstatus_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, 2226d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent audio_policy_dev_state_t state, 2227d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector<audio_io_handle_t>& inputs, 2228d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent const String8 address) 2229d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 2230d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent AudioInputDescriptor *desc; 2231d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { 2232d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // first list already open inputs that can be routed to this device 2233d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 2234d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 2235d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (desc->mProfile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) { 2236d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index)); 2237d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(mInputs.keyAt(input_index)); 2238d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2239d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2240d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2241d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // then look for input profiles that can be routed to this device 2242d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector<IOProfile *> profiles; 2243d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++) 2244d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent { 2245d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_idx]->mHandle == 0) { 2246d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 2247d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2248d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t profile_index = 0; 2249d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index < mHwModules[module_idx]->mInputProfiles.size(); 2250d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index++) 2251d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent { 2252d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_idx]->mInputProfiles[profile_index]->mSupportedDevices.types() 2253d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent & (device & ~AUDIO_DEVICE_BIT_IN)) { 2254d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding profile %d from module %d", 2255d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index, module_idx); 2256d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profiles.add(mHwModules[module_idx]->mInputProfiles[profile_index]); 2257d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2258d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2259d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2260d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2261d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profiles.isEmpty() && inputs.isEmpty()) { 2262d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 2263d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return BAD_VALUE; 2264d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2265d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2266d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // open inputs for matching profiles if needed. Direct inputs are also opened to 2267d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 2268d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 2269d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2270d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent IOProfile *profile = profiles[profile_index]; 2271d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // nothing to do if one input is already opened for this profile 2272d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent size_t input_index; 2273d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (input_index = 0; input_index < mInputs.size(); input_index++) { 2274d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 2275d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (desc->mProfile == profile) { 2276d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent break; 2277d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2278d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2279d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input_index != mInputs.size()) { 2280d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 2281d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2282d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2283d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("opening input for device 0x%X with params %s", device, address.string()); 2284d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = new AudioInputDescriptor(profile); 2285d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc->mDevice = device; 2286d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2287d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle, 2288d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mDevice, 2289d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mSamplingRate, 2290d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mFormat, 2291d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mChannelMask); 2292d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2293d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input != 0) { 2294d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (!address.isEmpty()) { 2295d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->setParameters(input, addressToParameter(device, address)); 2296d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2297d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2298d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where we step through and resolve any "dynamic" fields 2299d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 reply; 2300d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char *value; 2301d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 2302d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 2303d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 2304d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup sampling rates %s", 2305d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2306d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2307d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 2308d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent loadSamplingRates(value + 1, profile); 2309d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2310d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2311d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2312d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 2313d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 2314d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string()); 2315d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2316d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 2317d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent loadFormats(value + 1, profile); 2318d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2319d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2320d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 2321d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 2322d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 2323d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup channel masks %s", 2324d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2325d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2326d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 2327d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent loadInChannels(value + 1, profile); 2328d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2329d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2330d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) || 2331d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) || 2332d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) { 2333d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice() direct input missing param"); 2334d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeInput(input); 2335d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent input = 0; 2336d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2337d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2338d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input != 0) { 2339d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addInput(input, desc); 2340d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2341d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // endif input != 0 2342d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2343d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input == 0) { 2344d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice() could not open input for device 0x%X", device); 2345d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent delete desc; 2346d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profiles.removeAt(profile_index); 2347d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index--; 2348d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 2349d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(input); 2350d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding input %d", input); 2351d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2352d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end scan profiles 2353d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2354d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profiles.isEmpty()) { 2355d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 2356d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return BAD_VALUE; 2357d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2358d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 2359d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Disconnect 2360d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // check if one opened input is not needed any more after disconnecting one device 2361d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 2362d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 2363d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types())) { 2364d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): disconnecting adding input %d", 2365d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mInputs.keyAt(input_index)); 2366d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(mInputs.keyAt(input_index)); 2367d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2368d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2369d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Clear any profiles associated with the disconnected device. 2370d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) { 2371d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_index]->mHandle == 0) { 2372d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 2373d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2374d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t profile_index = 0; 2375d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index < mHwModules[module_index]->mInputProfiles.size(); 2376d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index++) { 2377d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent IOProfile *profile = mHwModules[module_index]->mInputProfiles[profile_index]; 2378d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSupportedDevices.types() & device) { 2379d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): clearing direct input profile %d on module %d", 2380d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index, module_index); 2381d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 2382d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mSamplingRates.clear(); 2383d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mSamplingRates.add(0); 2384d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2385d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2386d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mFormats.clear(); 2387d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 2388d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2389d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 2390d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mChannelMasks.clear(); 2391d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mChannelMasks.add(0); 2392d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2393d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2394d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2395d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2396d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end disconnect 2397d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2398d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return NO_ERROR; 2399d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 2400d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2401d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2402e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::closeOutput(audio_io_handle_t output) 2403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("closeOutput(%d)", output); 2405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc == NULL) { 2408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("closeOutput() unknown output %d", output); 2409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 2410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // look for duplicated outputs connected to the output being removed. 2413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i); 2415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dupOutputDesc->isDuplicated() && 2416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (dupOutputDesc->mOutput1 == outputDesc || 2417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent dupOutputDesc->mOutput2 == outputDesc)) { 2418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc2; 2419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dupOutputDesc->mOutput1 == outputDesc) { 2420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc2 = dupOutputDesc->mOutput2; 2421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc2 = dupOutputDesc->mOutput1; 2423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // As all active tracks on duplicated output will be deleted, 2425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and as they were also referenced on the other output, the reference 2426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // count for their stream type must be adjusted accordingly on 2427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the other output. 24283b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int j = 0; j < AUDIO_STREAM_CNT; j++) { 2429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int refCount = dupOutputDesc->mRefCount[j]; 24303b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount); 2431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i); 2433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); 2434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(duplicatedOutput); 2436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mOutputs.valueFor(duplicatedOutput); 2437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(duplicatedOutput); 2438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param; 2442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.add(String8("closing"), String8("true")); 2443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(output, param.toString()); 2444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 2446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete outputDesc; 2447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(output); 2448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 2449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2451e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device, 2452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs) 2453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> outputs; 2455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getOutputsForDevice() device %04x", device); 2457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < openOutputs.size(); i++) { 2458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("output %d isDuplicated=%d device=%04x", 2459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices()); 2460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) { 2461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i)); 2462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(openOutputs.keyAt(i)); 2463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs; 2466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2468e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, 2469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t>& outputs2) 2470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs1.size() != outputs2.size()) { 2472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs1.size(); i++) { 2475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs1[i] != outputs2[i]) { 2476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 2480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2482e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy) 2483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); 2485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); 2486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs); 2487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); 2488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!vectorsEqual(srcOutputs,dstOutputs)) { 2490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", 2491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent strategy, srcOutputs[0], dstOutputs[0]); 2492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute strategy while moving tracks from one output to another 2493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < srcOutputs.size(); i++) { 2494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]); 2495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->isStrategyActive(strategy)) { 2496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(strategy, true, srcOutputs[i]); 2497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); 2498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Move effects associated to this strategy from previous output to new output 2502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strategy == STRATEGY_MEDIA) { 2503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs); 2504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> moved; 2505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 2506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent EffectDescriptor *desc = mEffects.valueAt(i); 2507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX && 2508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mIo != fxOutput) { 2509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (moved.indexOf(desc->mIo) < 0) { 2510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputForStrategy() moving effect %d to output %d", 2511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.keyAt(i), fxOutput); 2512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, desc->mIo, 2513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent fxOutput); 2514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent moved.add(desc->mIo); 2515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mIo = fxOutput; 2517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Move tracks associated to this strategy from previous output to new output 25213b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 25223b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (getStrategy((audio_stream_type_t)i) == strategy) { 25233b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->invalidateStream((audio_stream_type_t)i); 2524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2529e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForAllStrategies() 2530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 2532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_PHONE); 2533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION); 2534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 2535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_MEDIA); 2536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_DTMF); 2537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2539e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getA2dpOutput() 2540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 2543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 2544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutputs.keyAt(i); 2545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 2549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2551e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkA2dpSuspend() 2552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t a2dpOutput = getA2dpOutput(); 2554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (a2dpOutput == 0) { 25553a4311c68348f728558e87b5db67d47605783890Eric Laurent mA2dpSuspended = false; 2556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 2557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 25593a4311c68348f728558e87b5db67d47605783890Eric Laurent bool isScoConnected = 25603a4311c68348f728558e87b5db67d47605783890Eric Laurent (mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) != 0; 2561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // suspend A2DP output if: 2562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (NOT already suspended) && 2563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ((SCO device is connected && 2564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (forced usage for communication || for record is SCO))) || 2565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (phone state is ringing || in call) 2566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // restore A2DP output if: 2568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (Already suspended) && 2569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ((SCO device is NOT connected || 2570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (forced usage NOT for communication && NOT for record is SCO))) && 2571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (phone state is NOT ringing && NOT in call) 2572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mA2dpSuspended) { 25743a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((!isScoConnected || 25753b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO) && 25763b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] != AUDIO_POLICY_FORCE_BT_SCO))) && 25773b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mPhoneState != AUDIO_MODE_IN_CALL) && 25783b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mPhoneState != AUDIO_MODE_RINGTONE))) { 2579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->restoreOutput(a2dpOutput); 2581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mA2dpSuspended = false; 2582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 25843a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((isScoConnected && 25853b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) || 25863b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO))) || 25873b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mPhoneState == AUDIO_MODE_IN_CALL) || 25883b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mPhoneState == AUDIO_MODE_RINGTONE))) { 2589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->suspendOutput(a2dpOutput); 2591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mA2dpSuspended = true; 2592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2596e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getNewDevice(audio_io_handle_t output, bool fromCache) 2597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = AUDIO_DEVICE_NONE; 2599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check the following by order of priority to request a routing change if necessary: 2602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: the strategy enforced audible is active on the output: 2603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy enforced audible 2604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: we are in call or the strategy phone is active on the output: 2605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy phone 2606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the strategy sonification is active on the output: 2607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy sonification 2608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 4: the strategy "respectful" sonification is active on the output: 2609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy "respectful" sonification 2610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 5: the strategy media is active on the output: 2611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy media 2612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 6: the strategy DTMF is active on the output: 2613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy DTMF 2614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { 2615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 2616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isInCall() || 2617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->isStrategyActive(STRATEGY_PHONE)) { 2618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 2619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) { 2620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 2621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { 2622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); 2623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { 2624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 2625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { 2626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 2627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getNewDevice() selected device %x", device); 2630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 2631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2633e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) { 2634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (uint32_t)getStrategy(stream); 2635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2637e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) { 2638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t devices; 2639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // By checking the range of stream before calling getStrategy, we avoid 2640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 2641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and then return STRATEGY_MEDIA, but we want to return the empty set. 26423b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_CNT) { 2643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devices = AUDIO_DEVICE_NONE; 2644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2645e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::routing_strategy strategy = getStrategy(stream); 2646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devices = getDeviceForStrategy(strategy, true /*fromCache*/); 2647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return devices; 2649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2651e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy( 26523b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream) { 2653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // stream to strategy mapping 2654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (stream) { 26553b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_VOICE_CALL: 26563b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_BLUETOOTH_SCO: 2657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_PHONE; 26583b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_RING: 26593b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_ALARM: 2660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_SONIFICATION; 26613b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_NOTIFICATION: 2662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_SONIFICATION_RESPECTFUL; 26633b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_DTMF: 2664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_DTMF; 2665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 2666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("unknown stream type"); 26673b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_SYSTEM: 2668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 2669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while key clicks are played produces a poor result 26703b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_TTS: 26713b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_MUSIC: 2672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_MEDIA; 26733b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_ENFORCED_AUDIBLE: 2674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 2675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2678e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) { 2679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(stream) { 26803b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_MUSIC: 2681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 2682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 2683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 2685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2689e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, 2690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool fromCache) 2691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 2693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (fromCache) { 2695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x", 2696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent strategy, mDeviceForStrategy[strategy]); 2697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mDeviceForStrategy[strategy]; 2698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 26993a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types(); 2700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (strategy) { 2701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_SONIFICATION_RESPECTFUL: 2703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 2704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 27053b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC, 2706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 2707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while media is playing on a remote device, use the the sonification behavior. 2708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Note that we test this usecase before testing if media is playing because 2709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the isStreamActive() method only informs about the activity of a stream, not 2710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if it's for local playback. Note also that we use the same delay between both tests 2711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 27123b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 2713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while media is playing (or has recently played), use the same device 2714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 2715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when media is not playing anymore, fall back on the sonification behavior 2717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 2718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_DTMF: 2723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isInCall()) { 2724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when off call, DTMF strategy follows the same rules as MEDIA strategy 2725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 2726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when in call, DTMF and PHONE strategies follow the same rules 2729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 2730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_PHONE: 2732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // for phone strategy, we first consider the forced use and then the available devices by order 2733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // of priority 27343b73df74357b33869b39a1d69427673c780bd805Eric Laurent switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) { 27353b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_BT_SCO: 2736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isInCall() || strategy != STRATEGY_DTMF) { 27373a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 2738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 27403a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 2741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27423a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; 2743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if SCO device is requested but no SCO device is available, fall back to default case 2745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 2746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: // FORCE_NONE 2748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 27493a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!isInCall() && 27503b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 2751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 27523a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 2753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27543a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 27573a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 2758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27593a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET; 2760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27613b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mPhoneState != AUDIO_MODE_IN_CALL) { 27623a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27643a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 2765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27663a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27683a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27703a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 27733a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE; 2774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27753a4311c68348f728558e87b5db67d47605783890Eric Laurent device = mDefaultOutputDevice->mType; 2776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); 2778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 27813b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_SPEAKER: 2782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 2783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // A2DP speaker when forcing to speaker output 27843a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!isInCall() && 27853b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 2786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 27873a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 27903b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mPhoneState != AUDIO_MODE_IN_CALL) { 27913a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27933a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 2794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27953a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27973a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27993a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 28023a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 2803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 28043a4311c68348f728558e87b5db67d47605783890Eric Laurent device = mDefaultOutputDevice->mType; 2805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); 2807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_SONIFICATION: 2813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 2815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handleIncallSonification(). 2816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 2817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); 2818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 2821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 2823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 2824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // except: 2825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - when in call where it doesn't default to STRATEGY_PHONE behavior 2826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - in countries where not enforced in which case it follows STRATEGY_MEDIA 2827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((strategy == STRATEGY_SONIFICATION) || 28293b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) { 28303a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 2831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); 2833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The second device used for sonification is the same as the device used by media strategy 2836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 2837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_MEDIA: { 2839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device2 = AUDIO_DEVICE_NONE; 2840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strategy != STRATEGY_SONIFICATION) { 2841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no sonification on remote submix (e.g. WFD) 28423a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; 2843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 28453b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 2846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 28473a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 2848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28493a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28523a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28563a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 2857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28593a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET; 2860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28623a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28653a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 2866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28683a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { 2871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no sonification on aux digital (e.g. HDMI) 28723a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 28753b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) { 28763a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28793a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 2880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 2883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise 2884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device |= device2; 2885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 28863a4311c68348f728558e87b5db67d47605783890Eric Laurent device = mDefaultOutputDevice->mType; 2887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); 2889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } break; 2891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 2893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 2894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 2898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 2899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2901e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::updateDevicesAndOutputs() 2902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_STRATEGIES; i++) { 2904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 2905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 2907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2909e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc, 2910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t prevDevice, 2911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t delayMs) 2912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute/unmute strategies using an incompatible device combination 2914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if muting, wait for the audio in pcm buffer to be drained before proceeding 2915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if unmuting, unmute only after the specified delay 2916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isDuplicated()) { 2917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 2918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs = 0; 2921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = outputDesc->device(); 29223b73df74357b33869b39a1d69427673c780bd805Eric Laurent bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2); 2923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // temporary mute output if device selection changes to avoid volume bursts due to 2924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // different per device volumes 2925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool tempMute = outputDesc->isActive() && (device != prevDevice); 2926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 2928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 2929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool mute = shouldMute && (curDevice & device) && (curDevice != device); 2930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool doMute = false; 2931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mute && !outputDesc->mStrategyMutedByDevice[i]) { 2933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent doMute = true; 2934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = true; 2935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){ 2936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent doMute = true; 2937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = false; 2938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (doMute || tempMute) { 2940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mOutputs.size(); j++) { 2941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(j); 2942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // skip output if it does not share any device with current output 2943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->supportedDevices() & outputDesc->supportedDevices()) 2944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent == AUDIO_DEVICE_NONE) { 2945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(j); 2948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", 2949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mute ? "muting" : "unmuting", i, curDevice, curOutput); 2950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); 2951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->isStrategyActive((routing_strategy)i)) { 2952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do tempMute only for current output 2953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (tempMute && (desc == outputDesc)) { 2954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute((routing_strategy)i, true, curOutput); 2955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute((routing_strategy)i, false, curOutput, 2956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->latency() * 2, device); 2957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((tempMute && (desc == outputDesc)) || mute) { 2959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (muteWaitMs < desc->latency()) { 2960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs = desc->latency(); 2961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FIXME: should not need to double latency if volume could be applied immediately by the 2969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // audioflinger mixer. We must account for the delay between now and the next time 2970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the audioflinger thread for this output will process a buffer (which corresponds to 2971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // one buffer size, usually 1/2 or 1/4 of the latency). 2972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs *= 2; 2973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // wait for the PCM output buffers to empty before proceeding with the rest of the command 2974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (muteWaitMs > delayMs) { 2975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs -= delayMs; 2976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent usleep(muteWaitMs * 1000); 2977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 2978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 2980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2982e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output, 2983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 2984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force, 2985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs) 2986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); 2988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param; 2990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs; 2991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isDuplicated()) { 2993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); 2994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); 2995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 2996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current 2998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // output profile 2999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device != AUDIO_DEVICE_NONE) && 30003a4311c68348f728558e87b5db67d47605783890Eric Laurent ((device & outputDesc->mProfile->mSupportedDevices.types()) == 0)) { 3001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 3002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // filter devices according to output selected 30053a4311c68348f728558e87b5db67d47605783890Eric Laurent device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices.types()); 3006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t prevDevice = outputDesc->mDevice; 3008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() prevDevice %04x", prevDevice); 3010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device != AUDIO_DEVICE_NONE) { 3012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = device; 3013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); 3015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not change the routing if: 3017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the requested device is AUDIO_DEVICE_NONE 3018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the requested device is the same as current device and force is not specified. 3019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Doing this check here allows the caller to call setOutputDevice() without conditions 3020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) { 3021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); 3022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 3023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() changing device"); 3026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do the routing 3027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.addInt(String8(AudioParameter::keyRouting), (int)device); 3028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(output, param.toString(), delayMs); 3029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update stream volumes according to new device 3031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent applyStreamVolumes(output, device, delayMs); 3032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 3034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3036e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile *AudioPolicyManager::getInputProfile(audio_devices_t device, 3037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 3038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 3039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask) 3040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Choose an input profile based on the requested capture parameters: select the first available 3042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // profile supporting all requested parameters. 3043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 3045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 3047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 3048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 3050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent IOProfile *profile = mHwModules[i]->mInputProfiles[j]; 3052d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // profile->log(); 3053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 3054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, AUDIO_OUTPUT_FLAG_NONE)) { 3055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return profile; 3056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NULL; 3060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3062e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource) 3063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 30653a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & 30663a4311c68348f728558e87b5db67d47605783890Eric Laurent ~AUDIO_DEVICE_BIT_IN; 3067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (inputSource) { 3068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 30693a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { 3070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 3071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 3074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_DEFAULT: 3076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_MIC: 3077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_RECOGNITION: 3078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_HOTWORD: 3079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_COMMUNICATION: 30803b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO && 30813a4311c68348f728558e87b5db67d47605783890Eric Laurent availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 3082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 30833a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { 3084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_WIRED_HEADSET; 3085d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { 3086d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent device = AUDIO_DEVICE_IN_USB_DEVICE; 30873a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 3088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 3089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_CAMCORDER: 30923a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) { 3093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BACK_MIC; 30943a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 3095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 3096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_DOWNLINK: 3099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_CALL: 31003a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { 3101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 3102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_REMOTE_SUBMIX: 31053a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { 3106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; 3107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 3110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 3111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 3114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 3115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3117e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device) 3118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & AUDIO_DEVICE_BIT_IN) != 0) { 3120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device &= ~AUDIO_DEVICE_BIT_IN; 3121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) 3122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3127e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs) 3128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 3130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const AudioInputDescriptor * input_descriptor = mInputs.valueAt(i); 3131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((input_descriptor->mRefCount > 0) 3132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) { 3133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mInputs.keyAt(i); 3134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 3137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3140e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device) 3141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this happens when forcing a route update and no track is active on an output. 3144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // In this case the returned category is not important. 3145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 31463b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (popcount(device) > 1) { 3147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Multiple device selection is either: 3148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - speaker + one other device: give priority to speaker in this case. 3149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 3150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 3151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // selection if not the speaker. 3152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 3153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 3154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 3156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 31593b73df74357b33869b39a1d69427673c780bd805Eric Laurent ALOGW_IF(popcount(device) != 1, 3160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 3161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device); 3162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 3164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3166e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device) 3167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(getDeviceForVolume(device)) { 3169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 3170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_EARPIECE; 3171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 3172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 3173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 3174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 3175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 3176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 3177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_HEADSET; 3178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 3179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 3180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 3181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_AUX_DIGITAL: 3182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_USB_ACCESSORY: 3183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_USB_DEVICE: 3184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_REMOTE_SUBMIX: 3185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 3186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_SPEAKER; 3187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3190e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, 3191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexInUi) 3192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device_category deviceCategory = getDeviceCategory(device); 3194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 3195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the volume index in the UI is relative to the min and max volume indices for this stream type 3197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 3198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[VOLMIN].mIndex; 3199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 3200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (streamDesc.mIndexMax - streamDesc.mIndexMin); 3201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // find what part of the curve this index volume belongs to, or if it's out of bounds 3203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int segment = 0; 3204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 3205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0.0f; 3206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 3207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 0; 3208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 3209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 1; 3210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 3211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 2; 3212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { // out of bounds 3213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 1.0f; 3214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // linear interpolation in the attenuation table in dB 3217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float decibels = curve[segment].mDBAttenuation + 3218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 3219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ( (curve[segment+1].mDBAttenuation - 3220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mDBAttenuation) / 3221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((float)(curve[segment+1].mIndex - 3222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mIndex)) ); 3223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 3225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 3227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mIndex, volIdx, 3228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment+1].mIndex, 3229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mDBAttenuation, 3230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent decibels, 3231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment+1].mDBAttenuation, 3232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent amplification); 3233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return amplification; 3235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3237e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3238e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultVolumeCurve[AudioPolicyManager::VOLCNT] = { 3239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 3240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3242e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3243e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { 3244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 3245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3247e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3248e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { 3249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 3250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3252e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3253e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = { 3254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 3255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3257e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3258e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 3259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f} 3260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks 3263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets. 3264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java). 3265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset. 3266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3267e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3268e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 3269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f} 3270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3272e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3273e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 3274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f} 3275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3277e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3278e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 3279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f} 3280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3282e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3283e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { 3284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f} 3285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3287e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3288e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { 3289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f} 3290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3292e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3293e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT] 3294e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent [AudioPolicyManager::DEVICE_CATEGORY_CNT] = { 3295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_VOICE_CALL 3296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 3297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 3299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_SYSTEM 3301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 3302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 3304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_RING 3306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 3307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 3309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_MUSIC 3311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 3312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 3314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_ALARM 3316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 3317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 3319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_NOTIFICATION 3321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 3322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 3324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_BLUETOOTH_SCO 3326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 3327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 3329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_ENFORCED_AUDIBLE 3331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 3332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 3334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_DTMF 3336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 3337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 3339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_TTS 3341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 3342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 3344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3347e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initializeVolumeCurves() 3348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 3350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 3351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[i].mVolumeCurve[j] = 3352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[i][j]; 3353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check availability of DRC on speaker path: if available, override some of the speaker curves 3357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mSpeakerDrcEnabled) { 3358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 3359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurveDrc; 3360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 3361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 3362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 3363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 3364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 3365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 3366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3369e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::computeVolume(audio_stream_type_t stream, 3370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 3371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 3372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 3373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float volume = 1.0; 3375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 3376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent StreamDescriptor &streamDesc = mStreams[stream]; 3377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = outputDesc->device(); 3380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if volume is not 0 (not muted), force media volume to max on digital output 33833b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_MUSIC && 3384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent index != mStreams[stream].mIndexMin && 3385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (device == AUDIO_DEVICE_OUT_AUX_DIGITAL || 3386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET || 3387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device == AUDIO_DEVICE_OUT_USB_ACCESSORY || 3388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device == AUDIO_DEVICE_OUT_USB_DEVICE)) { 3389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 1.0; 3390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume = volIndexToAmpl(device, streamDesc, index); 3393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if a headset is connected, apply the following rules to ring tones and notifications 3395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // to avoid sound level bursts in user's ears: 3396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - always attenuate ring tones and notifications volume by 6dB 3397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - if music is playing, always limit the volume to current music volume, 3398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // with a minimum threshold at -36dB so that notification is always perceived. 33993b73df74357b33869b39a1d69427673c780bd805Eric Laurent const routing_strategy stream_strategy = getStrategy(stream); 3400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | 3401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 3402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADSET | 3403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) && 3404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((stream_strategy == STRATEGY_SONIFICATION) 3405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) 34063b73df74357b33869b39a1d69427673c780bd805Eric Laurent || (stream == AUDIO_STREAM_SYSTEM) 3407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) && 34083b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) && 3409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent streamDesc.mCanBeMuted) { 3410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 3411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when the phone is ringing we must consider that music could have been paused just before 3412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by the music application and behave as if music was active if the last music track was 3413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // just stopped 34143b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || 3415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume) { 3416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/); 34173b73df74357b33869b39a1d69427673c780bd805Eric Laurent float musicVol = computeVolume(AUDIO_STREAM_MUSIC, 34183b73df74357b33869b39a1d69427673c780bd805Eric Laurent mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice), 3419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 3420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent musicDevice); 3421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 3422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 3423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volume > minVol) { 3424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume = minVol; 3425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 3426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return volume; 3431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3433e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream, 3434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 3435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 3436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 3437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 3438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force) 3439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not change actual stream volume if the stream is muted 3442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 3443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkAndSetVolume() stream %d muted count %d", 3444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, mOutputs.valueFor(output)->mMuteCount[stream]); 3445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 3446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not change in call volume if bluetooth is connected and vice versa 34493b73df74357b33869b39a1d69427673c780bd805Eric Laurent if ((stream == AUDIO_STREAM_VOICE_CALL && 34503b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) || 34513b73df74357b33869b39a1d69427673c780bd805Eric Laurent (stream == AUDIO_STREAM_BLUETOOTH_SCO && 34523b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO)) { 3453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 34543b73df74357b33869b39a1d69427673c780bd805Eric Laurent stream, mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]); 3455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 3456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float volume = computeVolume(stream, index, output, device); 3459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // We actually change the volume if: 3460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the float value returned by computeVolume() changed 3461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the force flag is set 3462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 3463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force) { 3464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.valueFor(output)->mCurVolume[stream] = volume; 3465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 3466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 3467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // enabled 34683b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_BLUETOOTH_SCO) { 34693b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs); 3470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 34713b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->setStreamVolume(stream, volume, output, delayMs); 3472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 34743b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_VOICE_CALL || 34753b73df74357b33869b39a1d69427673c780bd805Eric Laurent stream == AUDIO_STREAM_BLUETOOTH_SCO) { 3476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float voiceVolume; 3477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force voice volume to max for bluetooth SCO as volume is managed by the headset 34783b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_VOICE_CALL) { 3479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 3480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent voiceVolume = 1.0; 3482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { 3485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 3486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLastVoiceVolume = voiceVolume; 3487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 3491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3493e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output, 3494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 3495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 3496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force) 3497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("applyStreamVolumes() for output %d and device %x", output, device); 3499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 35003b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 35013b73df74357b33869b39a1d69427673c780bd805Eric Laurent checkAndSetVolume((audio_stream_type_t)stream, 3502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].getVolumeIndex(device), 3503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 3504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, 3505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs, 3506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force); 3507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3510e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStrategyMute(routing_strategy strategy, 3511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool on, 3512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 3513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 3514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 3515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 35173b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 35183b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (getStrategy((audio_stream_type_t)stream) == strategy) { 35193b73df74357b33869b39a1d69427673c780bd805Eric Laurent setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device); 3520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3524e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStreamMute(audio_stream_type_t stream, 3525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool on, 3526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 3527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 3528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 3529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent StreamDescriptor &streamDesc = mStreams[stream]; 3531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 3532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = outputDesc->device(); 3534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x", 3537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, on, output, outputDesc->mMuteCount[stream], device); 3538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (on) { 3540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mMuteCount[stream] == 0) { 3541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (streamDesc.mCanBeMuted && 35423b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) || 35433b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) { 3544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 3545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 3548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mMuteCount[stream]++; 3549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mMuteCount[stream] == 0) { 3551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setStreamMute() unmuting non muted stream!"); 3552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 3553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (--outputDesc->mMuteCount[stream] == 0) { 3555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 3556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent streamDesc.getVolumeIndex(device), 3557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 3558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, 3559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs); 3560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3564e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream, 35653b73df74357b33869b39a1d69427673c780bd805Eric Laurent bool starting, bool stateChange) 3566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if the stream pertains to sonification strategy and we are in call we must 3568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute the stream if it is low visibility. If it is high visibility, we must play a tone 3569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the device used for phone strategy and play the tone if the selected device does not 3570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // interfere with the device used for phone strategy 3571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 3572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // many times as there are active tracks on the output 35733b73df74357b33869b39a1d69427673c780bd805Eric Laurent const routing_strategy stream_strategy = getStrategy(stream); 3574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((stream_strategy == STRATEGY_SONIFICATION) || 3575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { 3576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 3577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 3578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, starting, outputDesc->mDevice, stateChange); 3579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream]) { 3580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int muteCount = 1; 3581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (stateChange) { 3582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteCount = outputDesc->mRefCount[stream]; 3583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 35843b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (audio_is_low_visibility(stream)) { 3585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 3586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < muteCount; i++) { 3587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 3588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() high visibility"); 3591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->device() & 3592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) { 3593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 3594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < muteCount; i++) { 3595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 3596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (starting) { 35993b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION, 36003b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_STREAM_VOICE_CALL); 3601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->stopTone(); 3603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3609e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isInCall() 3610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return isStateInCall(mPhoneState); 3612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3614e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStateInCall(int state) { 36153b73df74357b33869b39a1d69427673c780bd805Eric Laurent return ((state == AUDIO_MODE_IN_CALL) || 36163b73df74357b33869b39a1d69427673c780bd805Eric Laurent (state == AUDIO_MODE_IN_COMMUNICATION)); 3617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3619e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsCpuLoad() 3620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return MAX_EFFECTS_CPU_LOAD; 3622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3624e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsMemory() 3625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return MAX_EFFECTS_MEMORY; 3627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioOutputDescriptor class implementation 3630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3631e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor( 3632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const IOProfile *profile) 3633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : mId(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), 3634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mChannelMask(0), mLatency(0), 3635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), 3636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0) 3637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // clear usage count for all stream types 36393b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 3640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[i] = 0; 3641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurVolume[i] = -1.0; 3642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mMuteCount[i] = 0; 3643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStopTime[i] = 0; 3644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_STRATEGIES; i++) { 3646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStrategyMutedByDevice[i] = false; 3647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile != NULL) { 3649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mSamplingRate = profile->mSamplingRates[0]; 3650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mFormat = profile->mFormats[0]; 3651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mChannelMask = profile->mChannelMasks[0]; 3652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mFlags = profile->mFlags; 3653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3656e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::device() const 3657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 3659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 3660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mDevice; 3662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3665e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::AudioOutputDescriptor::latency() 3666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 3668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 3669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mLatency; 3671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3674e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith( 3675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const AudioOutputDescriptor *outputDesc) 3676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 3678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 3679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isDuplicated()){ 3680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2); 3681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mProfile->mModule == outputDesc->mProfile->mModule); 3683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3686e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 36873b73df74357b33869b39a1d69427673c780bd805Eric Laurent int delta) 3688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // forward usage count change to attached outputs 3690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 3691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput1->changeRefCount(stream, delta); 3692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput2->changeRefCount(stream, delta); 3693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((delta + (int)mRefCount[stream]) < 0) { 36953b73df74357b33869b39a1d69427673c780bd805Eric Laurent ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", 36963b73df74357b33869b39a1d69427673c780bd805Eric Laurent delta, stream, mRefCount[stream]); 3697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[stream] = 0; 3698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 3699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[stream] += delta; 3701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 3702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3704e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::supportedDevices() 3705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 3707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 3708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 37093a4311c68348f728558e87b5db67d47605783890Eric Laurent return mProfile->mSupportedDevices.types() ; 3710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3713e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isActive(uint32_t inPastMs) const 3714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return isStrategyActive(NUM_STRATEGIES, inPastMs); 3716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3718e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy, 3719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t inPastMs, 3720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime) const 3721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((sysTime == 0) && (inPastMs != 0)) { 3723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime = systemTime(); 3724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 37253b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 37263b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (((getStrategy((audio_stream_type_t)i) == strategy) || 3727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (NUM_STRATEGIES == strategy)) && 37283b73df74357b33869b39a1d69427673c780bd805Eric Laurent isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) { 3729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3735e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, 3736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t inPastMs, 3737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime) const 3738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mRefCount[stream] != 0) { 3740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (inPastMs == 0) { 3743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (sysTime == 0) { 3746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime = systemTime(); 3747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 3749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3755e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd) 3756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 3758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 3759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 3760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 3762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 3764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 3766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 3768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 3770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Devices %08x\n", device()); 3772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 3774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 37753b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 37763b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", 37773b73df74357b33869b39a1d69427673c780bd805Eric Laurent i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 3778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 3781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 3783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioInputDescriptor class implementation 3786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3787e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const IOProfile *profile) 3788d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent : mId(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(0), 3789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDevice(AUDIO_DEVICE_NONE), mRefCount(0), 37903b73df74357b33869b39a1d69427673c780bd805Eric Laurent mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile) 3791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 37923a4311c68348f728558e87b5db67d47605783890Eric Laurent if (profile != NULL) { 37933a4311c68348f728558e87b5db67d47605783890Eric Laurent mSamplingRate = profile->mSamplingRates[0]; 37943a4311c68348f728558e87b5db67d47605783890Eric Laurent mFormat = profile->mFormats[0]; 37953a4311c68348f728558e87b5db67d47605783890Eric Laurent mChannelMask = profile->mChannelMasks[0]; 37963a4311c68348f728558e87b5db67d47605783890Eric Laurent } 3797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3799e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioInputDescriptor::dump(int fd) 3800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 3802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 3803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 3804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 3806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Format: %d\n", mFormat); 3808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 3810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 3812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 3814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 3816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 3818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- StreamDescriptor class implementation 3821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3822e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::StreamDescriptor::StreamDescriptor() 3823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 3824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 3826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3828e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::StreamDescriptor::getVolumeIndex(audio_devices_t device) 3829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3830e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent device = AudioPolicyManager::getDeviceForVolume(device); 3831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 3832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 3833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 3834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mIndexCur.valueFor(device); 3836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3838e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::StreamDescriptor::dump(int fd) 3839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 3841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 3842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 3843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 3845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 3846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 3848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 3849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.keyAt(i), 3850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.valueAt(i)); 3851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append("\n"); 3854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 3856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- EffectDescriptor class implementation 3859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3860e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::EffectDescriptor::dump(int fd) 3861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 3863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 3864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 3865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 3867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 3869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Session: %d\n", mSession); 3871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 3873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 3875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 3877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 3879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- IOProfile class implementation 3882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3883e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::HwModule(const char *name) 3884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0) 3885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3888e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::~HwModule() 3889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 38913a4311c68348f728558e87b5db67d47605783890Eric Laurent mOutputProfiles[i]->mSupportedDevices.clear(); 38923a4311c68348f728558e87b5db67d47605783890Eric Laurent delete mOutputProfiles[i]; 3893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 38953a4311c68348f728558e87b5db67d47605783890Eric Laurent mInputProfiles[i]->mSupportedDevices.clear(); 38963a4311c68348f728558e87b5db67d47605783890Eric Laurent delete mInputProfiles[i]; 3897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free((void *)mName); 3899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3901e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::HwModule::dump(int fd) 3902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 3904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 3905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 3906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - name: %s\n", mName); 3908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 3910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 3912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mOutputProfiles.size()) { 3913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, " - outputs:\n", strlen(" - outputs:\n")); 3914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 3915d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " output %zu:\n", i); 3916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 3917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputProfiles[i]->dump(fd); 3918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mInputProfiles.size()) { 3921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, " - inputs:\n", strlen(" - inputs:\n")); 3922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 3923d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " input %zu:\n", i); 3924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 3925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputProfiles[i]->dump(fd); 3926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3930e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile::IOProfile(HwModule *module) 3931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : mFlags((audio_output_flags_t)0), mModule(module) 3932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3935e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile::~IOProfile() 3936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// checks if the IO profile is compatible with specified parameters. 3940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Sampling rate, format and channel mask must be specified in order to 3941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// get a valid a match 3942e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device, 3943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 3944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 3945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 3946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_output_flags_t flags) const 3947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (samplingRate == 0 || !audio_is_valid_format(format) || channelMask == 0) { 3949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 39523a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((mSupportedDevices.types() & device) != device) { 3953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((mFlags & flags) != flags) { 3956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent size_t i; 3959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (i = 0; i < mSamplingRates.size(); i++) 3960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mSamplingRates[i] == samplingRate) { 3962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (i == mSamplingRates.size()) { 3966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (i = 0; i < mFormats.size(); i++) 3969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mFormats[i] == format) { 3971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (i == mFormats.size()) { 3975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (i = 0; i < mChannelMasks.size(); i++) 3978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mChannelMasks[i] == channelMask) { 3980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (i == mChannelMasks.size()) { 3984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3989e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::IOProfile::dump(int fd) 3990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 3992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 3993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 3994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - sampling rates: "); 3996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 3998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%d", mSamplingRates[i]); 3999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(i == (mSamplingRates.size() - 1) ? "\n" : ", "); 4001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - channel masks: "); 4004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 4006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]); 4007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(i == (mChannelMasks.size() - 1) ? "\n" : ", "); 4009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - formats: "); 4012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 4014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "0x%08x", mFormats[i]); 4015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(i == (mFormats.size() - 1) ? "\n" : ", "); 4017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 40193a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, " - devices:\n"); 4020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 40213a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, result.string(), result.size()); 40223a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceDescriptor::dumpHeader(fd, 6); 40233a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mSupportedDevices.size(); i++) { 40243a4311c68348f728558e87b5db67d47605783890Eric Laurent mSupportedDevices[i]->dump(fd, 6); 40253a4311c68348f728558e87b5db67d47605783890Eric Laurent } 40263a4311c68348f728558e87b5db67d47605783890Eric Laurent 4027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - flags: 0x%04x\n", mFlags); 4028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 4031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4033d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::IOProfile::log() 4034d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 4035d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent const size_t SIZE = 256; 4036d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char buffer[SIZE]; 4037d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 result; 4038d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 4039d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - sampling rates: "); 4040d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 4041d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" %d", mSamplingRates[i]); 4042d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 4043d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 4044d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - channel masks: "); 4045d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 4046d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" 0x%04x", mChannelMasks[i]); 4047d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 4048d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 4049d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - formats: "); 4050d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 4051d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" 0x%08x", mFormats[i]); 4052d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 4053d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 4054d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - devices: 0x%04x\n", mSupportedDevices.types()); 4055d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - flags: 0x%04x\n", mFlags); 4056d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 4057d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 4058d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 40593a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- DeviceDescriptor implementation 4060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 40613a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const 40623a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 40633a4311c68348f728558e87b5db67d47605783890Eric Laurent // Devices are considered equal if they: 40643a4311c68348f728558e87b5db67d47605783890Eric Laurent // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE) 40653a4311c68348f728558e87b5db67d47605783890Eric Laurent // - have the same address or one device does not specify the address 40663a4311c68348f728558e87b5db67d47605783890Eric Laurent // - have the same channel mask or one device does not specify the channel mask 40673a4311c68348f728558e87b5db67d47605783890Eric Laurent return (mType == other->mType) && 40683a4311c68348f728558e87b5db67d47605783890Eric Laurent (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) && 40692f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent (mChannelMask == 0 || other->mChannelMask == 0 || 40703a4311c68348f728558e87b5db67d47605783890Eric Laurent mChannelMask == other->mChannelMask); 40713a4311c68348f728558e87b5db67d47605783890Eric Laurent} 4072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 40733a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::refreshTypes() 40743a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 40753a4311c68348f728558e87b5db67d47605783890Eric Laurent mTypes = AUDIO_DEVICE_NONE; 40763a4311c68348f728558e87b5db67d47605783890Eric Laurent for(size_t i = 0; i < size(); i++) { 40773a4311c68348f728558e87b5db67d47605783890Eric Laurent mTypes |= itemAt(i)->mType; 40783a4311c68348f728558e87b5db67d47605783890Eric Laurent } 40793a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("DeviceVector::refreshTypes() mTypes %08x", mTypes); 40803a4311c68348f728558e87b5db67d47605783890Eric Laurent} 4081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 40823a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const 40833a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 40843a4311c68348f728558e87b5db67d47605783890Eric Laurent for(size_t i = 0; i < size(); i++) { 40853a4311c68348f728558e87b5db67d47605783890Eric Laurent if (item->equals(itemAt(i))) { 40863a4311c68348f728558e87b5db67d47605783890Eric Laurent return i; 40873a4311c68348f728558e87b5db67d47605783890Eric Laurent } 40883a4311c68348f728558e87b5db67d47605783890Eric Laurent } 40893a4311c68348f728558e87b5db67d47605783890Eric Laurent return -1; 40903a4311c68348f728558e87b5db67d47605783890Eric Laurent} 4091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 40923a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::add(const sp<DeviceDescriptor>& item) 40933a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 40943a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t ret = indexOf(item); 4095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 40963a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret < 0) { 40973a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = SortedVector::add(item); 40983a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret >= 0) { 40993a4311c68348f728558e87b5db67d47605783890Eric Laurent refreshTypes(); 41003a4311c68348f728558e87b5db67d47605783890Eric Laurent } 41013a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 41023a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("DeviceVector::add device %08x already in", item->mType); 41033a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = -1; 41043a4311c68348f728558e87b5db67d47605783890Eric Laurent } 41053a4311c68348f728558e87b5db67d47605783890Eric Laurent return ret; 41063a4311c68348f728558e87b5db67d47605783890Eric Laurent} 4107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 41083a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::remove(const sp<DeviceDescriptor>& item) 41093a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 41103a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t i; 41113a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t ret = indexOf(item); 4112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 41133a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret < 0) { 41143a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("DeviceVector::remove device %08x not in", item->mType); 41153a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 41163a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = SortedVector::removeAt(ret); 41173a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret >= 0) { 41183a4311c68348f728558e87b5db67d47605783890Eric Laurent refreshTypes(); 41193a4311c68348f728558e87b5db67d47605783890Eric Laurent } 41203a4311c68348f728558e87b5db67d47605783890Eric Laurent } 41213a4311c68348f728558e87b5db67d47605783890Eric Laurent return ret; 41223a4311c68348f728558e87b5db67d47605783890Eric Laurent} 4123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 41243a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::loadDevicesFromType(audio_devices_t types) 4125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 41263a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceVector deviceList; 41273a4311c68348f728558e87b5db67d47605783890Eric Laurent 41283a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t role_bit = AUDIO_DEVICE_BIT_IN & types; 41293a4311c68348f728558e87b5db67d47605783890Eric Laurent types &= ~role_bit; 41303a4311c68348f728558e87b5db67d47605783890Eric Laurent 41313a4311c68348f728558e87b5db67d47605783890Eric Laurent while (types) { 41323a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t i = 31 - __builtin_clz(types); 41333a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t type = 1 << i; 41343a4311c68348f728558e87b5db67d47605783890Eric Laurent types &= ~type; 41353a4311c68348f728558e87b5db67d47605783890Eric Laurent add(new DeviceDescriptor(type | role_bit)); 4136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 41393a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceDescriptor::dumpHeader(int fd, int spaces) 4140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 41413a4311c68348f728558e87b5db67d47605783890Eric Laurent const size_t SIZE = 256; 41423a4311c68348f728558e87b5db67d47605783890Eric Laurent char buffer[SIZE]; 41433a4311c68348f728558e87b5db67d47605783890Eric Laurent 41443a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, "%*s%-48s %-2s %-8s %-32s \n", 41453a4311c68348f728558e87b5db67d47605783890Eric Laurent spaces, "", "Type", "ID", "Cnl Mask", "Address"); 41463a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, buffer, strlen(buffer)); 4147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 41493a4311c68348f728558e87b5db67d47605783890Eric Laurentstatus_t AudioPolicyManager::DeviceDescriptor::dump(int fd, int spaces) const 41503a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 41513a4311c68348f728558e87b5db67d47605783890Eric Laurent const size_t SIZE = 256; 41523a4311c68348f728558e87b5db67d47605783890Eric Laurent char buffer[SIZE]; 41533a4311c68348f728558e87b5db67d47605783890Eric Laurent 41543a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, "%*s%-48s %2d %08x %-32s \n", 41553a4311c68348f728558e87b5db67d47605783890Eric Laurent spaces, "", 41563a4311c68348f728558e87b5db67d47605783890Eric Laurent enumToString(sDeviceNameToEnumTable, 41573a4311c68348f728558e87b5db67d47605783890Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 41583a4311c68348f728558e87b5db67d47605783890Eric Laurent mType), 41593a4311c68348f728558e87b5db67d47605783890Eric Laurent mId, mChannelMask, mAddress.string()); 41603a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, buffer, strlen(buffer)); 41613a4311c68348f728558e87b5db67d47605783890Eric Laurent 41623a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_ERROR; 41633a4311c68348f728558e87b5db67d47605783890Eric Laurent} 41643a4311c68348f728558e87b5db67d47605783890Eric Laurent 41653a4311c68348f728558e87b5db67d47605783890Eric Laurent 41663a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- audio_policy.conf file parsing 41673a4311c68348f728558e87b5db67d47605783890Eric Laurent 4168e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_output_flags_t AudioPolicyManager::parseFlagNames(char *name) 4169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t flag = 0; 4171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // it is OK to cast name to non const here as we are not going to use it after 4173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // strtok() modifies it 4174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *flagName = strtok(name, "|"); 4175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (flagName != NULL) { 4176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strlen(flagName) != 0) { 4177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flag |= stringToEnum(sFlagNameToEnumTable, 4178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sFlagNameToEnumTable), 4179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flagName); 4180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flagName = strtok(NULL, "|"); 4182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //force direct flag if offload flag is set: offloading implies a direct output stream 4184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and all common behaviors are driven by checking only the direct flag 4185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this should normally be set appropriately in the policy configuration file 4186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 4187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flag |= AUDIO_OUTPUT_FLAG_DIRECT; 4188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_output_flags_t)flag; 4191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4193e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::parseDeviceNames(char *name) 4194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = 0; 4196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *devName = strtok(name, "|"); 4198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (devName != NULL) { 4199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strlen(devName) != 0) { 4200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device |= stringToEnum(sDeviceNameToEnumTable, 4201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 4202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devName); 42033a4311c68348f728558e87b5db67d47605783890Eric Laurent } 4204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devName = strtok(NULL, "|"); 42053a4311c68348f728558e87b5db67d47605783890Eric Laurent } 4206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 4207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4209e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadSamplingRates(char *name, IOProfile *profile) 4210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *str = strtok(name, "|"); 4212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling 4214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // rates should be read from the output stream after it is opened for the first time 4215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 4216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(0); 4217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (str != NULL) { 4221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t rate = atoi(str); 4222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (rate != 0) { 4223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadSamplingRates() adding rate %d", rate); 4224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(rate); 4225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent str = strtok(NULL, "|"); 4227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4231e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadFormats(char *name, IOProfile *profile) 4232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *str = strtok(name, "|"); 4234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by convention, "0' in the first entry in mFormats indicates the supported formats 4236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // should be read from the output stream after it is opened for the first time 4237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 4238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 4239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (str != NULL) { 4243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable, 4244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 4245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent str); 4246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (format != AUDIO_FORMAT_DEFAULT) { 4247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(format); 4248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent str = strtok(NULL, "|"); 4250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4254e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadInChannels(char *name, IOProfile *profile) 4255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *str = strtok(name, "|"); 4257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadInChannels() %s", name); 4259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 4261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(0); 4262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (str != NULL) { 4266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask = 4267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 4268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 4269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent str); 4270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (channelMask != 0) { 4271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadInChannels() adding channelMask %04x", channelMask); 4272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(channelMask); 4273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent str = strtok(NULL, "|"); 4275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4279e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadOutChannels(char *name, IOProfile *profile) 4280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *str = strtok(name, "|"); 4282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadOutChannels() %s", name); 4284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by convention, "0' in the first entry in mChannelMasks indicates the supported channel 4286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // masks should be read from the output stream after it is opened for the first time 4287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 4288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(0); 4289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (str != NULL) { 4293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask = 4294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 4295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 4296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent str); 4297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (channelMask != 0) { 4298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(channelMask); 4299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent str = strtok(NULL, "|"); 4301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4305e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadInput(cnode *root, HwModule *module) 4306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = root->first_child; 4308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent IOProfile *profile = new IOProfile(module); 4310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 4313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadSamplingRates((char *)node->value, profile); 4314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 4315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadFormats((char *)node->value, profile); 4316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 4317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadInChannels((char *)node->value, profile); 4318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 43193a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.loadDevicesFromType(parseDeviceNames((char *)node->value)); 4320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 43233a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW_IF(profile->mSupportedDevices.isEmpty(), 4324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadInput() invalid supported devices"); 4325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 4326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadInput() invalid supported channel masks"); 4327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 4328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadInput() invalid supported sampling rates"); 4329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 4330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadInput() invalid supported formats"); 43313a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!profile->mSupportedDevices.isEmpty() && 4332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mChannelMasks.size() != 0) && 4333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mSamplingRates.size() != 0) && 4334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mFormats.size() != 0)) { 4335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43363a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadInput() adding input Supported Devices %04x", 43373a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.types()); 4338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mInputProfiles.add(profile); 4340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete profile; 4343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 4344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4347e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadOutput(cnode *root, HwModule *module) 4348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = root->first_child; 4350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent IOProfile *profile = new IOProfile(module); 4352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 4355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadSamplingRates((char *)node->value, profile); 4356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 4357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadFormats((char *)node->value, profile); 4358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 4359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadOutChannels((char *)node->value, profile); 4360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 43613a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.loadDevicesFromType(parseDeviceNames((char *)node->value)); 4362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, FLAGS_TAG) == 0) { 4363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFlags = parseFlagNames((char *)node->value); 4364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 43673a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW_IF(profile->mSupportedDevices.isEmpty(), 4368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadOutput() invalid supported devices"); 4369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 4370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadOutput() invalid supported channel masks"); 4371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 4372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadOutput() invalid supported sampling rates"); 4373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 4374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadOutput() invalid supported formats"); 43753a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!profile->mSupportedDevices.isEmpty() && 4376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mChannelMasks.size() != 0) && 4377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mSamplingRates.size() != 0) && 4378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mFormats.size() != 0)) { 4379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43803a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x", 43813a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.types(), profile->mFlags); 4382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mOutputProfiles.add(profile); 4384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete profile; 4387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 4388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4391e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModule(cnode *root) 4392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, OUTPUTS_TAG); 4394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t status = NAME_NOT_FOUND; 4395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent HwModule *module = new HwModule(root->name); 4397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node != NULL) { 4399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 4400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModule() loading output %s", node->name); 4402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t tmpStatus = loadOutput(node, module); 4403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 4404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = tmpStatus; 4405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = config_find(root, INPUTS_TAG); 4410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node != NULL) { 4411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 4412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModule() loading input %s", node->name); 4414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t tmpStatus = loadInput(node, module); 4415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 4416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = tmpStatus; 4417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NO_ERROR) { 4422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules.add(module); 4423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete module; 4425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4428e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModules(cnode *root) 4429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); 4431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node == NULL) { 4432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 4436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModules() loading module %s", node->name); 4438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadHwModule(node); 4439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4443e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadGlobalConfig(cnode *root) 4444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, GLOBAL_CONFIG_TAG); 4446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node == NULL) { 4447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 4450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { 44523a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.loadDevicesFromType(parseDeviceNames((char *)node->value)); 44533a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadGlobalConfig() Attached Output Devices %08x", 44543a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.types()); 4455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { 44563a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t device = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable, 4457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 4458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (char *)node->value); 44593a4311c68348f728558e87b5db67d47605783890Eric Laurent if (device != AUDIO_DEVICE_NONE) { 44603a4311c68348f728558e87b5db67d47605783890Eric Laurent mDefaultOutputDevice = new DeviceDescriptor(device); 44613a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 44623a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("loadGlobalConfig() default device not specified"); 44633a4311c68348f728558e87b5db67d47605783890Eric Laurent } 44643a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", mDefaultOutputDevice->mType); 4465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { 44663a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.loadDevicesFromType(parseDeviceNames((char *)node->value)); 44673a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadGlobalConfig() Available InputDevices %08x", mAvailableInputDevices.types()); 4468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) { 4469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mSpeakerDrcEnabled = stringToBool((char *)node->value); 4470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled); 4471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4476e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadAudioPolicyConfig(const char *path) 4477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *root; 4479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *data; 4480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent data = (char *)load_file(path, NULL); 4482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (data == NULL) { 4483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return -ENODEV; 4484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent root = config_node("", ""); 4486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent config_load(root, data); 4487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadGlobalConfig(root); 4489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadHwModules(root); 4490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent config_free(root); 4492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free(root); 4493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free(data); 4494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGI("loadAudioPolicyConfig() loaded %s\n", path); 4496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4500e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::defaultAudioPolicyConfig(void) 4501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent HwModule *module; 4503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent IOProfile *profile; 45043a4311c68348f728558e87b5db67d47605783890Eric Laurent sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC); 45053a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.add(mDefaultOutputDevice); 45063a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.add(defaultInputDevice); 4507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module = new HwModule("primary"); 4509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile = new IOProfile(module); 4511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(44100); 4512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 4513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO); 45143a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.add(mDefaultOutputDevice); 4515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY; 4516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mOutputProfiles.add(profile); 4517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile = new IOProfile(module); 4519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(8000); 4520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 4521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO); 45223a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.add(defaultInputDevice); 4523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mInputProfiles.add(profile); 4524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules.add(module); 4526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; // namespace android 4529