AudioPolicyManager.cpp revision b71e58b64cd4992355cf6afaf3f3530f723bc72c
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), 731b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI), 743a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET), 753a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET), 763a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY), 773a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE), 783a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB), 793a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX), 801b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_TELEPHONY_TX), 811b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_LINE), 821b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC), 831b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPDIF), 841b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM), 853a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), 863a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), 873a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO), 883a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET), 893a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL), 901b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_HDMI), 913a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL), 921b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX), 933a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC), 943a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX), 953a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET), 963a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET), 973a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY), 98d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE), 991b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_FM_TUNER), 1001b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_TV_TUNER), 1011b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_LINE), 1021b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_SPDIF), 1033a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1043a4311c68348f728558e87b5db67d47605783890Eric Laurent 1053a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFlagNameToEnumTable[] = { 1063a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT), 1073a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), 1083a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), 1093a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), 1103a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD), 1113a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING), 1123a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1133a4311c68348f728558e87b5db67d47605783890Eric Laurent 1143a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFormatNameToEnumTable[] = { 1153a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT), 1163a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT), 1173a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT), 1183a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT), 1193a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT), 1203a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED), 1213a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_MP3), 1223a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AAC), 1233a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_VORBIS), 1243a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1253a4311c68348f728558e87b5db67d47605783890Eric Laurent 1263a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sOutChannelsNameToEnumTable[] = { 1273a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO), 1283a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 1293a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 1303a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 1313a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1323a4311c68348f728558e87b5db67d47605783890Eric Laurent 1333a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sInChannelsNameToEnumTable[] = { 1343a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), 1353a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), 1363a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK), 1373a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1383a4311c68348f728558e87b5db67d47605783890Eric Laurent 1393a4311c68348f728558e87b5db67d47605783890Eric Laurent 1403a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::stringToEnum(const struct StringToEnum *table, 1413a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t size, 1423a4311c68348f728558e87b5db67d47605783890Eric Laurent const char *name) 1433a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1443a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < size; i++) { 1453a4311c68348f728558e87b5db67d47605783890Eric Laurent if (strcmp(table[i].name, name) == 0) { 1463a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("stringToEnum() found %s", table[i].name); 1473a4311c68348f728558e87b5db67d47605783890Eric Laurent return table[i].value; 1483a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1493a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1503a4311c68348f728558e87b5db67d47605783890Eric Laurent return 0; 1513a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1523a4311c68348f728558e87b5db67d47605783890Eric Laurent 1533a4311c68348f728558e87b5db67d47605783890Eric Laurentconst char *AudioPolicyManager::enumToString(const struct StringToEnum *table, 1543a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t size, 1553a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t value) 1563a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1573a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < size; i++) { 1583a4311c68348f728558e87b5db67d47605783890Eric Laurent if (table[i].value == value) { 1593a4311c68348f728558e87b5db67d47605783890Eric Laurent return table[i].name; 1603a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1613a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1623a4311c68348f728558e87b5db67d47605783890Eric Laurent return ""; 1633a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1643a4311c68348f728558e87b5db67d47605783890Eric Laurent 1653a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::stringToBool(const char *value) 1663a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1673a4311c68348f728558e87b5db67d47605783890Eric Laurent return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0)); 1683a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1693a4311c68348f728558e87b5db67d47605783890Eric Laurent 1703a4311c68348f728558e87b5db67d47605783890Eric Laurent 1713a4311c68348f728558e87b5db67d47605783890Eric Laurent// ---------------------------------------------------------------------------- 172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AudioPolicyInterface implementation 173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 176e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, 1773b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state, 178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *device_address) 179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1803a4311c68348f728558e87b5db67d47605783890Eric Laurent String8 address = String8(device_address); 181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); 183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // connect/disconnect only 1 device at a time 185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; 186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output devices 188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_output_device(device)) { 189d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector <audio_io_handle_t> outputs; 190d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 1913a4311c68348f728558e87b5db67d47605783890Eric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device, 1923a4311c68348f728558e87b5db67d47605783890Eric Laurent address, 1932f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent 0); 1943a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = mAvailableOutputDevices.indexOf(devDesc); 1953a4311c68348f728558e87b5db67d47605783890Eric Laurent 196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // save a copy of the opened output descriptors before any output is opened or closed 197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() 198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (state) 200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output device connection 2023b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: 2033a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device already connected: %x", device); 205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setDeviceConnectionState() connecting device %x", device); 208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2093a4311c68348f728558e87b5db67d47605783890Eric Laurent if (checkOutputsForDevice(device, state, outputs, address) != NO_ERROR) { 210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 212d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs", 213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.size()); 214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // register new device as available 2153a4311c68348f728558e87b5db67d47605783890Eric Laurent index = mAvailableOutputDevices.add(devDesc); 2163a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 2173a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices[index]->mId = nextUniqueId(); 2183a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 2193a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_MEMORY; 220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output device disconnection 2243b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: { 2253a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index < 0) { 226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device not connected: %x", device); 227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setDeviceConnectionState() disconnecting device %x", device); 231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // remove device from available output devices 2323a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.remove(devDesc); 2333a4311c68348f728558e87b5db67d47605783890Eric Laurent 2343a4311c68348f728558e87b5db67d47605783890Eric Laurent checkOutputsForDevice(device, state, outputs, address); 235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // not currently handling multiple simultaneous submixes: ignoring remote submix 236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // case and address 237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } break; 238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("setDeviceConnectionState() invalid state: %x", state); 241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2443a4311c68348f728558e87b5db67d47605783890Eric Laurent // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP 2453a4311c68348f728558e87b5db67d47605783890Eric Laurent // output is suspended before any tracks are moved to it 246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // outputs must be closed after checkOutputForAllStrategies() is executed 249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputs.isEmpty()) { 250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]); 252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // close unused outputs after device disconnection or direct outputs that have been 253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // opened by checkOutputsForDevice() to query dynamic parameters 2543b73df74357b33869b39a1d69427673c780bd805Eric Laurent if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) || 255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) && 256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (desc->mDirectOpenCount == 0))) { 257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent closeOutput(outputs[i]); 258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2603a4311c68348f728558e87b5db67d47605783890Eric Laurent // check again after closing A2DP output to reset mA2dpSuspended if needed 2613a4311c68348f728558e87b5db67d47605783890Eric Laurent checkA2dpSuspend(); 262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not force device change on duplicated output because if device is 0, it will 267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // also force a device 0 for the two outputs it is duplicated to which may override 268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // a valid device selection on those outputs. 269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(mOutputs.keyAt(i), 2701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent getNewOutputDevice(mOutputs.keyAt(i), true /*fromCache*/), 271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent !mOutputs.valueAt(i)->isDuplicated(), 272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 0); 273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 275b71e58b64cd4992355cf6afaf3f3530f723bc72cEric Laurent return NO_ERROR; 276d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end if is output device 277d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input devices 279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_input_device(device)) { 280d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector <audio_io_handle_t> inputs; 281d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2823a4311c68348f728558e87b5db67d47605783890Eric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device, 2833a4311c68348f728558e87b5db67d47605783890Eric Laurent address, 2842f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent 0); 285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2863a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = mAvailableInputDevices.indexOf(devDesc); 287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (state) 288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input device connection 2903b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: { 2913a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device already connected: %d", device); 293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 295d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (checkInputsForDevice(device, state, inputs, address) != NO_ERROR) { 296d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return INVALID_OPERATION; 297d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 298d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2993a4311c68348f728558e87b5db67d47605783890Eric Laurent index = mAvailableInputDevices.add(devDesc); 3003a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 3013a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices[index]->mId = nextUniqueId(); 3023a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 3033a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_MEMORY; 3043a4311c68348f728558e87b5db67d47605783890Eric Laurent } 305d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } break; 306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input device disconnection 3083b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: { 3093a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index < 0) { 310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device not connected: %d", device); 311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 313d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent checkInputsForDevice(device, state, inputs, address); 3143a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.remove(devDesc); 315d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } break; 316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("setDeviceConnectionState() invalid state: %x", state); 319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 322d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent closeAllInputs(); 323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 325d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end if is input device 326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() invalid device: %x", device); 328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 331e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device, 332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *device_address) 333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3343b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 address = String8(device_address); 3363a4311c68348f728558e87b5db67d47605783890Eric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device, 3373a4311c68348f728558e87b5db67d47605783890Eric Laurent String8(device_address), 3382f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent 0); 3393a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index; 3403a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceVector *deviceVector; 3413a4311c68348f728558e87b5db67d47605783890Eric Laurent 342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_output_device(device)) { 3433a4311c68348f728558e87b5db67d47605783890Eric Laurent deviceVector = &mAvailableOutputDevices; 344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (audio_is_input_device(device)) { 3453a4311c68348f728558e87b5db67d47605783890Eric Laurent deviceVector = &mAvailableInputDevices; 3463a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 3473a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("getDeviceConnectionState() invalid device type %08x", device); 3483a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3513a4311c68348f728558e87b5db67d47605783890Eric Laurent index = deviceVector->indexOf(devDesc); 3523a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 3533a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_AVAILABLE; 3543a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 3553a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 3563a4311c68348f728558e87b5db67d47605783890Eric Laurent } 357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 359e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setPhoneState(audio_mode_t state) 360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() state %d", state); 362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = AUDIO_DEVICE_NONE; 3633b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state < 0 || state >= AUDIO_MODE_CNT) { 364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setPhoneState() invalid state %d", state); 365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (state == mPhoneState ) { 369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setPhoneState() setting same state %d", state); 370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if leaving call state, handle special case of active streams 374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // pertaining to sonification strategy see handleIncallSonification() 375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() in call state management: new state is %d", state); 3773b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 3783b73df74357b33869b39a1d69427673c780bd805Eric Laurent handleIncallSonification((audio_stream_type_t)stream, false, true); 379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // store previous phone state for management of sonification strategy below 383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int oldState = mPhoneState; 384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPhoneState = state; 385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force = false; 386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // are we entering or starting a call 388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isStateInCall(oldState) && isStateInCall(state)) { 389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Entering call in setPhoneState()"); 390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when starting a call 391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j]; 396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isStateInCall(oldState) && !isStateInCall(state)) { 398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Exiting call in setPhoneState()"); 399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when exiting a call 400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[AUDIO_STREAM_DTMF][j]; 405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isStateInCall(state) && (state != oldState)) { 407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when switching between telephony and VoIP 409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check for device and output changes triggered by new phone state 4141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/); 415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when ending call 422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) { 424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent newDevice = hwOutputDesc->device(); 425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs = 0; 428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(state)) { 429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute media and sonification strategies and delay device switch by the largest 433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // latency of any output where either strategy is active. 434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This avoid sending the ring tone or music tail into the earpiece or headset. 435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->isStrategyActive(STRATEGY_MEDIA, 436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime) || 438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->isStrategyActive(STRATEGY_SONIFICATION, 439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime)) && 441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (delayMs < (int)desc->mLatency*2)) { 442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs = desc->mLatency*2; 443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); 445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, 446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); 447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i)); 448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS, 449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/)); 450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // change routing is necessary 454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(mPrimaryOutput, newDevice, force, delayMs); 455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if entering in call state, handle special case of active streams 457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // pertaining to sonification strategy see handleIncallSonification() 458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(state)) { 459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() in call state management: new state is %d", state); 4603b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 4613b73df74357b33869b39a1d69427673c780bd805Eric Laurent handleIncallSonification((audio_stream_type_t)stream, true, true); 462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 4663b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state == AUDIO_MODE_RINGTONE && 4673b73df74357b33869b39a1d69427673c780bd805Eric Laurent isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume = true; 469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume = false; 471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 474e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setForceUse(audio_policy_force_use_t usage, 4753b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_forced_cfg_t config) 476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool forceVolumeReeval = false; 480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(usage) { 4813b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_COMMUNICATION: 4823b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO && 4833b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NONE) { 484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4903b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_MEDIA: 4913b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP && 4923b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 4933b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_ANALOG_DOCK && 4943b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE && 4953b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NO_BT_A2DP) { 496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5013b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_RECORD: 5023b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 5033b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NONE) { 504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5093b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_DOCK: 5103b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK && 5113b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_BT_DESK_DOCK && 5123b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 5133b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_ANALOG_DOCK && 5143b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) { 515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5203b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_SYSTEM: 5213b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_NONE && 5223b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { 523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config); 524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid usage %d", usage); 530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check for device and output changes triggered by new force usage 534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 5391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t newDevice = getNewOutputDevice(output, true /*fromCache*/); 540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE)); 541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) { 542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent applyStreamVolumes(output, newDevice, 0, true); 543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t activeInput = getActiveInput(); 547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (activeInput != 0) { 5481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setInputDevice(activeInput, getNewInputDevice(activeInput)); 549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 553e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage) 554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mForceUse[usage]; 556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 558e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setSystemProperty(const char* property, const char* value) 559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setSystemProperty() property %s, value %s", property, value); 561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Find a direct output profile compatible with the parameters passed, even if the input flags do 564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// not explicitly request a direct output 5651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::IOProfile> AudioPolicyManager::getProfileForDirectOutput( 566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_output_flags_t flags) 571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { 5771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j]; 5783a4311c68348f728558e87b5db67d47605783890Eric Laurent bool found = false; 579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { 580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, 582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) { 5833a4311c68348f728558e87b5db67d47605783890Eric Laurent found = true; 584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, 588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_OUTPUT_FLAG_DIRECT)) { 5893a4311c68348f728558e87b5db67d47605783890Eric Laurent found = true; 590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5923a4311c68348f728558e87b5db67d47605783890Eric Laurent if (found && (mAvailableOutputDevices.types() & profile->mSupportedDevices.types())) { 5933a4311c68348f728558e87b5db67d47605783890Eric Laurent return profile; 5943a4311c68348f728558e87b5db67d47605783890Eric Laurent } 595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 600e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream, 601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 6043b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_output_flags_t flags, 605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const audio_offload_info_t *offloadInfo) 606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = 0; 608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t latency = 0; 6093b73df74357b33869b39a1d69427673c780bd805Eric Laurent routing_strategy strategy = getStrategy(stream); 610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x", 612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, stream, samplingRate, format, channelMask, flags); 613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mCurOutput != 0) { 616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", 617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTestOutputs[mCurOutput] == 0) { 620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() opening test output"); 621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = mTestDevice; 623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate = mTestSamplingRate; 624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFormat = mTestFormat; 625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mChannelMask = mTestChannels; 626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency = mTestLatencyMs; 6273b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc->mFlags = 6283b73df74357b33869b39a1d69427673c780bd805Eric Laurent (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0); 629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mRefCount[stream] = 0; 630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice, 631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags, 636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo); 637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTestOutputs[mCurOutput]) { 638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"),mCurOutput); 640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(mTestOutputs[mCurOutput], outputDesc); 642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mTestOutputs[mCurOutput]; 645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open a direct output if required by specified parameters 649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //force direct flag if offload flag is set: offloading implies a direct output stream 650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and all common behaviors are driven by checking only the direct flag 651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this should normally be set appropriately in the policy configuration file 652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 6533b73df74357b33869b39a1d69427673c780bd805Eric Laurent flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT); 654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // detects there is an active non offloadable effect. 659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the background. 6621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile; 663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) || 664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent !isNonOffloadableEffectEnabled()) { 665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile = getProfileForDirectOutput(device, 666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, 667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent format, 668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, 669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (audio_output_flags_t)flags); 670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (profile != 0) { 673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = NULL; 674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && (profile == desc->mProfile)) { 678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc = desc; 679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // reuse direct output if currently open and configured with same parameters 680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((samplingRate == outputDesc->mSamplingRate) && 681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (format == outputDesc->mFormat) && 682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (channelMask == outputDesc->mChannelMask)) { 683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDirectOpenCount++; 684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i)); 685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutputs.keyAt(i); 686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // close direct output if currently open and configured with different parameters 690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc != NULL) { 6911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent closeOutput(outputDesc->mIoHandle); 692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc = new AudioOutputDescriptor(profile); 694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = device; 695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate = samplingRate; 696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFormat = format; 697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mChannelMask = channelMask; 698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency = 0; 699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags); 700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mRefCount[stream] = 0; 701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStopTime[stream] = 0; 702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDirectOpenCount = 1; 703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output = mpClientInterface->openOutput(profile->mModule->mHandle, 704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mDevice, 705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags, 710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo); 711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // only accept an output with the requested parameters 713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == 0 || 714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || 715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (format != AUDIO_FORMAT_DEFAULT && format != outputDesc->mFormat) || 716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { 717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," 718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "format %d %d, channelMask %04x %04x", output, samplingRate, 719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, 720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mChannelMask); 721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output != 0) { 722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete outputDesc; 725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t srcOutput = getOutputForEffect(); 728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, outputDesc); 729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dstOutput == output) { 731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput); 732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() returns new direct output %d", output); 735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ignoring channel mask due to downmix capability in mixer 739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open a non direct output 741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // for non direct outputs, only PCM is supported 743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_linear_pcm(format)) { 744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // get which output is suitable for the specified stream. The actual 745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // routing change will happen when startOutput() will be called 746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs); 747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output = selectOutput(outputs, flags); 749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d," 751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); 752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() returns output %d", output); 754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 758e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs, 7593b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_output_flags_t flags) 760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // select one output among several that provide a path to a particular device or set of 762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // devices (the list was previously build by getOutputsForDevice()). 763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The priority is as follows: 764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: the output with the highest number of requested policy flags 765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: the primary output 766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the first output in the list 767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 0) { 769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 1) { 772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int maxCommonFlags = 0; 776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputFlags = 0; 777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputPrimary = 0; 778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]); 781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputDesc->isDuplicated()) { 7823b73df74357b33869b39a1d69427673c780bd805Eric Laurent int commonFlags = popcount(outputDesc->mProfile->mFlags & flags); 783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (commonFlags > maxCommonFlags) { 784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputFlags = outputs[i]; 785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent maxCommonFlags = commonFlags; 786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); 787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputPrimary = outputs[i]; 790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputFlags != 0) { 795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputFlags; 796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputPrimary != 0) { 798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputPrimary; 799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 804e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startOutput(audio_io_handle_t output, 8053b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream, 806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session) 807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startOutput() unknown output %d", output); 812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // increment usage count for this stream on the requested output: 818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // NOTE that the usage count is the same for duplicated output and hardware output which is 819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // necessary for a correct control of hardware output routing by startOutput() and stopOutput() 820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->changeRefCount(stream, 1); 821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] == 1) { 8231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); 824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent routing_strategy strategy = getStrategy(stream); 825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool shouldWait = (strategy == STRATEGY_SONIFICATION) || 826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (strategy == STRATEGY_SONIFICATION_RESPECTFUL); 827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t waitMs = 0; 828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force = false; 829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc != outputDesc) { 832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force a device change if any other output is managed by the same hw 833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // module and has a current device selection that differs from selected device. 834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // In this case, the audio HAL must receive the new device selection so that it can 835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // change the device currently selected by the other active output. 836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->sharesHwModuleWith(desc) && 837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->device() != newDevice) { 838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // wait for audio on other active outputs to be presented when starting 841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // a notification so that audio focus effect can propagate. 842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t latency = desc->latency(); 843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { 844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent waitMs = latency; 845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); 849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle special case for sonification while in call 851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleIncallSonification(stream, true, false); 853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // apply volume rules for current stream and device if necessary 856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].getVolumeIndex(newDevice), 858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent newDevice); 860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update the outputs if starting an output with a stream that can affect notification 862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // routing 863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleNotificationRoutingForStream(stream); 864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (waitMs > muteWaitMs) { 865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent usleep((waitMs - muteWaitMs) * 2 * 1000); 866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 872e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopOutput(audio_io_handle_t output, 8733b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream, 874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session) 875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopOutput() unknown output %d", output); 880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle special case for sonification while in call 886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleIncallSonification(stream, false, false); 888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] > 0) { 891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // decrement usage count of this stream on the output 892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->changeRefCount(stream, -1); 893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // store time at which the stream was stopped - see isStreamActive() 894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] == 0) { 895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStopTime[stream] = systemTime(); 8961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); 897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // delay the device switch by twice the latency because stopOutput() is executed when 898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the track stop() command is received and at that time the audio track buffer can 899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // still contain data that needs to be drained. The latency only covers the audio HAL 900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and kernel buffers. Also the latency does not always include additional delay in the 901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // audio path (audio DSP, CODEC ...) 902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); 903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force restoring the device selection on other active outputs if it differs from the 905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // one being selected for this output 906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(i); 908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(i); 909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (curOutput != output && 910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->isActive() && 911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->sharesHwModuleWith(desc) && 912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (newDevice != desc->device())) { 913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(curOutput, 9141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent getNewOutputDevice(curOutput, false /*fromCache*/), 915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent true, 916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency*2); 917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update the outputs if stopping one with a stream that can affect notification routing 920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleNotificationRoutingForStream(stream); 921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopOutput() refcount is already 0 for output %d", output); 925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 929e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::releaseOutput(audio_io_handle_t output) 930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseOutput() %d", output); 932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseOutput() releasing unknown output %d", output); 935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int testIndex = testOutputIndex(output); 940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (testIndex != 0) { 941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); 942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isActive()) { 943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mOutputs.valueAt(index); 945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(output); 946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[testIndex] = 0; 947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(index); 9533b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { 954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->mDirectOpenCount <= 0) { 955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseOutput() invalid open count %d for output %d", 956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mDirectOpenCount, output); 957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (--desc->mDirectOpenCount == 0) { 960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent closeOutput(output); 961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // If effects where present on the output, audioflinger moved them to the primary 962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // output by default: move them back to the appropriate output. 963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dstOutput != mPrimaryOutput) { 965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput); 966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 972e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, 973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 9763b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_in_acoustics_t acoustics) 977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t input = 0; 979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForInputSource(inputSource); 980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x", 982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputSource, samplingRate, format, channelMask, acoustics); 983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getInput() could not find device for inputSource %d", inputSource); 986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // adapt channel selection to input source 990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(inputSource) { 991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK; 993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_DOWNLINK: 995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK; 996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_CALL: 998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK; 999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 1001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 10041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = getInputProfile(device, 1005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, 1006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent format, 1007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask); 10081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (profile == 0) { 1009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d, " 1010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "channelMask %04x", 1011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, samplingRate, format, channelMask); 1012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mModule->mHandle == 0) { 1016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); 1017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile); 1021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mInputSource = inputSource; 1023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mDevice = device; 1024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mSamplingRate = samplingRate; 1025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mFormat = format; 1026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mChannelMask = channelMask; 1027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mRefCount = 0; 1028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent input = mpClientInterface->openInput(profile->mModule->mHandle, 1029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &inputDesc->mDevice, 1030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &inputDesc->mSamplingRate, 1031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &inputDesc->mFormat, 1032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &inputDesc->mChannelMask); 1033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // only accept input with the exact requested set of parameters 1035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (input == 0 || 1036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (samplingRate != inputDesc->mSamplingRate) || 1037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (format != inputDesc->mFormat) || 1038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (channelMask != inputDesc->mChannelMask)) { 1039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGI("getInput() failed opening input: samplingRate %d, format %d, channelMask %x", 1040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, format, channelMask); 1041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (input != 0) { 1042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeInput(input); 1043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete inputDesc; 1045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1047d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addInput(input, inputDesc); 1048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return input; 1049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1051e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startInput(audio_io_handle_t input) 1052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("startInput() input %d", input); 1054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startInput() unknown input %d", input); 1057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 1060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTestInput == 0) 1063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // refuse 2 active AudioRecord clients at the same time except if the active input 1066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // uses AUDIO_SOURCE_HOTWORD in which case it is closed. 1067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t activeInput = getActiveInput(); 1068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isVirtualInputDevice(inputDesc->mDevice) && activeInput != 0) { 1069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput); 1070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) { 1071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startInput() preempting already started low-priority input %d", activeInput); 1072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stopInput(activeInput); 1073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent releaseInput(activeInput); 1074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startInput() input %d failed: other input already started", input); 1076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 10811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setInputDevice(input, getNewInputDevice(input), true /* force */); 1082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // automatically enable the remote submix output when input is started 1084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 10863b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_POLICY_DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 1087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 1090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mRefCount = 1; 1092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1095e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopInput(audio_io_handle_t input) 1096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("stopInput() input %d", input); 1098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopInput() unknown input %d", input); 1101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioInputDescriptor *inputDesc = mInputs.valueAt(index); 1104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (inputDesc->mRefCount == 0) { 1106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopInput() input %d already stopped", input); 1107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // automatically disable the remote submix output when input is stopped 1110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 11123b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 1113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 11151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent resetInputDevice(input); 1116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mRefCount = 0; 1117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1121e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::releaseInput(audio_io_handle_t input) 1122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseInput() %d", input); 1124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseInput() releasing unknown input %d", input); 1127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeInput(input); 1130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mInputs.valueAt(index); 1131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputs.removeItem(input); 1132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseInput() exit"); 1133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1135d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::closeAllInputs() { 1136d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for(size_t input_index = 0; input_index < mInputs.size(); input_index++) { 1137d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeInput(mInputs.keyAt(input_index)); 1138d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 1139d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mInputs.clear(); 1140d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 1141d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 1142e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initStreamVolume(audio_stream_type_t stream, 1143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexMin, 1144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexMax) 1145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 1147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (indexMin < 0 || indexMin >= indexMax) { 1148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 1149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexMin = indexMin; 1152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexMax = indexMax; 1153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1155e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream, 1156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 1157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 1158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 1161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device)) { 1164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force max volume if stream cannot be muted 1168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 1169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", 1171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, device, index); 1172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 1174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // clear all device specific values 1175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexCur.clear(); 1177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 1179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // compute and apply stream volume on all outputs according to connected device 1181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t status = NO_ERROR; 1182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t curDevice = 1184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForVolume(mOutputs.valueAt(i)->device()); 1185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) { 1186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); 1187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volStatus != NO_ERROR) { 1188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = volStatus; 1189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return status; 1193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1195e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream, 1196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int *index, 1197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 1198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index == NULL) { 1200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device)) { 1203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 1206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the strategy the stream belongs to. 1207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); 1209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForVolume(device); 1211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 1213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 1214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1217e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutputForEffects( 1218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const SortedVector<audio_io_handle_t>& outputs) 1219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // select one output among several suitable for global effects. 1221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The priority is as follows: 1222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: An offloaded output. If the effect ends up not being offloadable, 1223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // AudioFlinger will invalidate the track and the offloaded output 1224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // will be closed causing the effect to be moved to a PCM output. 1225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: A deep buffer output 1226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the first output in the list 1227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 0) { 1229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputOffloaded = 0; 1233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputDeepBuffer = 0; 1234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 1236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]); 1237d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags); 1238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 1239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputOffloaded = outputs[i]; 1240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) { 1242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDeepBuffer = outputs[i]; 1243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d", 1247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputOffloaded, outputDeepBuffer); 1248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputOffloaded != 0) { 1249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputOffloaded; 1250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDeepBuffer != 0) { 1252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputDeepBuffer; 1253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 1256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1258e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc) 1259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // apply simple rule where global effects are attached to the same output as MUSIC streams 1261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 12623b73df74357b33869b39a1d69427673c780bd805Eric Laurent routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC); 1263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 1264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs); 1265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = selectOutputForEffects(dstOutputs); 1267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutputForEffect() got output %d for fx %s flags %x", 1268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, (desc == NULL) ? "unspecified" : desc->name, (desc == NULL) ? 0 : desc->flags); 1269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 1271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1273e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc, 1274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t io, 1275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t strategy, 1276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session, 1277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int id) 1278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 1280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent index = mInputs.indexOfKey(io); 1282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("registerEffect() unknown io %d", io); 1284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 1289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 1290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->name, desc->memoryUsage); 1291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsMemory += desc->memoryUsage; 1294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 1295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->name, io, strategy, session, id); 1296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 1297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent EffectDescriptor *pDesc = new EffectDescriptor(); 1299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t)); 1300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mIo = io; 1301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mStrategy = (routing_strategy)strategy; 1302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mSession = session; 1303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mEnabled = false; 1304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.add(id, pDesc); 1306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1310e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::unregisterEffect(int id) 1311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() unknown effect ID %d", id); 1315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent EffectDescriptor *pDesc = mEffects.valueAt(index); 1319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setEffectEnabled(pDesc, false); 1321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) { 1323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() memory %d too big for total %d", 1324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.memoryUsage = mTotalEffectsMemory; 1326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsMemory -= pDesc->mDesc.memoryUsage; 1328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 1329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.removeItem(id); 1332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete pDesc; 1333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1337e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(int id, bool enabled) 1338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() unknown effect ID %d", id); 1342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 1346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1348e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(EffectDescriptor *pDesc, bool enabled) 1349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (enabled == pDesc->mEnabled) { 1351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(%s) effect already %s", 1352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 1353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (enabled) { 1357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 1358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 1359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10); 1360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad; 1363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 1364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) { 1366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 1367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 1368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 1369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad; 1371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 1372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mEnabled = enabled; 1374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1377e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isNonOffloadableEffectEnabled() 1378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 1380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const EffectDescriptor * const pDesc = mEffects.valueAt(i); 1381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (pDesc->mEnabled && (pDesc->mStrategy == STRATEGY_MEDIA) && 1382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((pDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) { 1383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d", 1384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent pDesc->mDesc.name, pDesc->mSession); 1385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1391e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 1392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 1394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 13963b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 1397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1403e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, 14043b73df74357b33869b39a1d69427673c780bd805Eric Laurent uint32_t inPastMs) const 1405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 1407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 1409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 14103b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 1411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1417e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isSourceActive(audio_source_t source) const 1418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 1420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const AudioInputDescriptor * inputDescriptor = mInputs.valueAt(i); 1421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((inputDescriptor->mInputSource == (int)source || 14223b73df74357b33869b39a1d69427673c780bd805Eric Laurent (source == AUDIO_SOURCE_VOICE_RECOGNITION && 1423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) 1424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent && (inputDescriptor->mRefCount > 0)) { 1425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1432e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::dump(int fd) 1433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 1435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 1436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 1437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 1439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 1440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput); 1442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 1443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 1444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 14453b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for communications %d\n", 14463b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]); 1447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 14483b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA]); 1449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 14503b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD]); 1451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 14523b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK]); 1453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 14543b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM]); 1455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 1456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14573a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, " Available output devices:\n"); 14583a4311c68348f728558e87b5db67d47605783890Eric Laurent result.append(buffer); 14593a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, result.string(), result.size()); 14603a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceDescriptor::dumpHeader(fd, 2); 14613a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) { 14623a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices[i]->dump(fd, 2); 14633a4311c68348f728558e87b5db67d47605783890Eric Laurent } 14643a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, "\n Available input devices:\n"); 14653a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, buffer, strlen(buffer)); 14663a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceDescriptor::dumpHeader(fd, 2); 14673a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size(); i++) { 14683a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices[i]->dump(fd, 2); 14693a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 1472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 1474d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1); 1475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules[i]->dump(fd); 1477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nOutputs dump:\n"); 1480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 1483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.valueAt(i)->dump(fd); 1485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nInputs dump:\n"); 1488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 1490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 1491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputs.valueAt(i)->dump(fd); 1493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nStreams dump:\n"); 1496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, 1498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 1499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 15003b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 1501d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " %02zu ", i); 1502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[i].dump(fd); 1504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 1507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 1508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "Registered effects:\n"); 1511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 1513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 1514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.valueAt(i)->dump(fd); 1516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This function checks for the parameters which can be offloaded. 1523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This can be enhanced depending on the capability of the DSP and policy 1524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// of the system. 1525e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo) 1526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d," 1528d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent " BitRate=%u, duration=%" PRId64 " us, has_video=%d", 1529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate, offloadInfo.channel_mask, 1530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format, 1531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us, 1532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.has_video); 1533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check if offload has been disabled 1535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char propValue[PROPERTY_VALUE_MAX]; 1536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (property_get("audio.offload.disable", propValue, "0")) { 1537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (atoi(propValue) != 0) { 1538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("offload disabled by audio.offload.disable=%s", propValue ); 1539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check if stream type is music, then only allow offload as of now. 1544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC) 1545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: stream_type != MUSIC, returning false"); 1547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //TODO: enable audio offloading with video when ready 1551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.has_video) 1552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: has_video == true, returning false"); 1554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //If duration is less than minimum value defined in property, return false 1558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (property_get("audio.offload.min.duration.secs", propValue, NULL)) { 1559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) { 1560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue); 1561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) { 1564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS); 1565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 1569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 1570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // detects there is an active non offloadable effect. 1571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 1572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 1573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the background. 1574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isNonOffloadableEffectEnabled()) { 1575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // See if there is a profile to support this. 1579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // AUDIO_DEVICE_NONE 15801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */, 1581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate, 1582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format, 1583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.channel_mask, 1584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD); 15851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT "); 15861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return (profile != 0); 1587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 1590e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent// AudioPolicyManager 1591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 1592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 15933a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::nextUniqueId() 15943a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 15953a4311c68348f728558e87b5db67d47605783890Eric Laurent return android_atomic_inc(&mNextUniqueId); 15963a4311c68348f728558e87b5db67d47605783890Eric Laurent} 15973a4311c68348f728558e87b5db67d47605783890Eric Laurent 1598e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) 1599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : 1600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent Thread(false), 1602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput((audio_io_handle_t)0), 16043b73df74357b33869b39a1d69427673c780bd805Eric Laurent mPhoneState(AUDIO_MODE_NORMAL), 1605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 1606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 16073a4311c68348f728558e87b5db67d47605783890Eric Laurent mA2dpSuspended(false), 16083a4311c68348f728558e87b5db67d47605783890Eric Laurent mSpeakerDrcEnabled(false), mNextUniqueId(0) 1609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface = clientInterface; 1611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16123b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) { 16133b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[i] = AUDIO_POLICY_FORCE_NONE; 1614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16163a4311c68348f728558e87b5db67d47605783890Eric Laurent mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER); 1617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { 1618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { 1619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("could not load audio policy configuration file, setting defaults"); 1620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent defaultAudioPolicyConfig(); 1621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 16233a4311c68348f728558e87b5db67d47605783890Eric Laurent // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices 1624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // must be done after reading the policy 1626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent initializeVolumeCurves(); 1627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open all output streams needed to access attached devices 16293a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types(); 16303a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN; 1631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 1632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 1633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 1634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("could not open HW module %s", mHwModules[i]->mName); 1635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 1636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open all output streams needed to access attached devices 1638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // except for direct output streams that are only opened when they are actually 1639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // required by an app. 16403a4311c68348f728558e87b5db67d47605783890Eric Laurent // This also validates mAvailableOutputDevices list 1641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 1642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 16431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j]; 1644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16453a4311c68348f728558e87b5db67d47605783890Eric Laurent if (outProfile->mSupportedDevices.isEmpty()) { 16463a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName); 16473a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 16483a4311c68348f728558e87b5db67d47605783890Eric Laurent } 16493a4311c68348f728558e87b5db67d47605783890Eric Laurent 16503a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t profileTypes = outProfile->mSupportedDevices.types(); 16513a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((profileTypes & outputDeviceTypes) && 1652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) { 1653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile); 16543a4311c68348f728558e87b5db67d47605783890Eric Laurent 16551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice->mDeviceType & profileTypes); 1656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput( 1657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outProfile->mModule->mHandle, 1658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mDevice, 1659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 1660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 1661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 1662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 1663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags); 1664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == 0) { 16653a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Cannot open output stream for device %08x on hw module %s", 16663a4311c68348f728558e87b5db67d47605783890Eric Laurent outputDesc->mDevice, 16673a4311c68348f728558e87b5db67d47605783890Eric Laurent mHwModules[i]->mName); 1668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete outputDesc; 1669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 16705b61dddd0dba28922068da2487894761486aec6cEric Laurent for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { 16711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType; 16723a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = 16735b61dddd0dba28922068da2487894761486aec6cEric Laurent mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]); 16743a4311c68348f728558e87b5db67d47605783890Eric Laurent // give a valid ID to an attached device once confirmed it is reachable 16753a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((index >= 0) && (mAvailableOutputDevices[index]->mId == 0)) { 16763a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices[index]->mId = nextUniqueId(); 16773a4311c68348f728558e87b5db67d47605783890Eric Laurent } 16783a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput == 0 && 1680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 1681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput = output; 1682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, outputDesc); 1684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, 16853a4311c68348f728558e87b5db67d47605783890Eric Laurent outputDesc->mDevice, 1686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent true); 1687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 16903a4311c68348f728558e87b5db67d47605783890Eric Laurent // open input streams needed to access attached devices to validate 16913a4311c68348f728558e87b5db67d47605783890Eric Laurent // mAvailableInputDevices list 16923a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 16933a4311c68348f728558e87b5db67d47605783890Eric Laurent { 16941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j]; 16953a4311c68348f728558e87b5db67d47605783890Eric Laurent 16963a4311c68348f728558e87b5db67d47605783890Eric Laurent if (inProfile->mSupportedDevices.isEmpty()) { 16973a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName); 16983a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 16993a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 17013a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t profileTypes = inProfile->mSupportedDevices.types(); 17023a4311c68348f728558e87b5db67d47605783890Eric Laurent if (profileTypes & inputDeviceTypes) { 17033a4311c68348f728558e87b5db67d47605783890Eric Laurent AudioInputDescriptor *inputDesc = new AudioInputDescriptor(inProfile); 17043a4311c68348f728558e87b5db67d47605783890Eric Laurent 17053a4311c68348f728558e87b5db67d47605783890Eric Laurent inputDesc->mInputSource = AUDIO_SOURCE_MIC; 17061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mDevice = inProfile->mSupportedDevices[0]->mDeviceType; 17073a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_io_handle_t input = mpClientInterface->openInput( 17083a4311c68348f728558e87b5db67d47605783890Eric Laurent inProfile->mModule->mHandle, 17093a4311c68348f728558e87b5db67d47605783890Eric Laurent &inputDesc->mDevice, 17103a4311c68348f728558e87b5db67d47605783890Eric Laurent &inputDesc->mSamplingRate, 17113a4311c68348f728558e87b5db67d47605783890Eric Laurent &inputDesc->mFormat, 17123a4311c68348f728558e87b5db67d47605783890Eric Laurent &inputDesc->mChannelMask); 17133a4311c68348f728558e87b5db67d47605783890Eric Laurent 17143a4311c68348f728558e87b5db67d47605783890Eric Laurent if (input != 0) { 17155b61dddd0dba28922068da2487894761486aec6cEric Laurent for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { 17161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType; 17173a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = 17185b61dddd0dba28922068da2487894761486aec6cEric Laurent mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]); 17193a4311c68348f728558e87b5db67d47605783890Eric Laurent // give a valid ID to an attached device once confirmed it is reachable 17203a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((index >= 0) && (mAvailableInputDevices[index]->mId == 0)) { 17213a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices[index]->mId = nextUniqueId(); 17223a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17233a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17243a4311c68348f728558e87b5db67d47605783890Eric Laurent mpClientInterface->closeInput(input); 17253a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 17263a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Cannot open input stream for device %08x on hw module %s", 17273a4311c68348f728558e87b5db67d47605783890Eric Laurent inputDesc->mDevice, 17283a4311c68348f728558e87b5db67d47605783890Eric Laurent mHwModules[i]->mName); 17293a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17303a4311c68348f728558e87b5db67d47605783890Eric Laurent delete inputDesc; 17313a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17323a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17333a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17343a4311c68348f728558e87b5db67d47605783890Eric Laurent // make sure all attached devices have been allocated a unique ID 17353a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableOutputDevices.size();) { 17363a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableOutputDevices[i]->mId == 0) { 17371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mDeviceType); 17383a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.remove(mAvailableOutputDevices[i]); 17393a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 17403a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17413a4311c68348f728558e87b5db67d47605783890Eric Laurent i++; 17423a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17433a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size();) { 17443a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableInputDevices[i]->mId == 0) { 17451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mDeviceType); 17463a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.remove(mAvailableInputDevices[i]); 17473a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 17483a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17493a4311c68348f728558e87b5db67d47605783890Eric Laurent i++; 17503a4311c68348f728558e87b5db67d47605783890Eric Laurent } 17513a4311c68348f728558e87b5db67d47605783890Eric Laurent // make sure default device is reachable 17523a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) { 17531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mDeviceType); 17543a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 1757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 1759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput != 0) { 1762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 1763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"), 0); 1764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestDevice = AUDIO_DEVICE_OUT_SPEAKER; 1767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestSamplingRate = 44100; 17683b73df74357b33869b39a1d69427673c780bd805Eric Laurent mTestFormat = AUDIO_FORMAT_PCM_16_BIT; 17693b73df74357b33869b39a1d69427673c780bd805Eric Laurent mTestChannels = AUDIO_CHANNEL_OUT_STEREO; 1770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestLatencyMs = 0; 1771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput = 0; 1772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = false; 1773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[i] = 0; 1775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 1778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 1779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 1780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent run(buffer, ANDROID_PRIORITY_AUDIO); 1781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1785e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::~AudioPolicyManager() 1786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent exit(); 1789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(mOutputs.keyAt(i)); 1792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mOutputs.valueAt(i); 1793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 1795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeInput(mInputs.keyAt(i)); 1796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mInputs.valueAt(i); 1797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 1799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mHwModules[i]; 1800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 18013a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.clear(); 18023a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.clear(); 1803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1805e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::initCheck() 1806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; 1808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1811e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::threadLoop() 1812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("entering threadLoop()"); 1814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (!exitPending()) 1815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 command; 1817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int valueInt; 1818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 value; 1819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent Mutex::Autolock _l(mLock); 1821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 1822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 1824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param = AudioParameter(command); 1825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 1827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent valueInt != 0) { 1828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Test command %s received", command.string()); 1829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 target; 1830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("target"), target) != NO_ERROR) { 1831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent target = "Manager"; 1832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 1834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_output")); 1835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput = valueInt; 1836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 1838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_direct")); 1839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "false") { 1840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = false; 1841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "true") { 1842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = true; 1843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 1846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_input")); 1847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestInput = valueInt; 1848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 1851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_format")); 18523b73df74357b33869b39a1d69427673c780bd805Eric Laurent int format = AUDIO_FORMAT_INVALID; 1853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "PCM 16 bits") { 18543b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_PCM_16_BIT; 1855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "PCM 8 bits") { 18563b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_PCM_8_BIT; 1857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "Compressed MP3") { 18583b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_MP3; 1859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 18603b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (format != AUDIO_FORMAT_INVALID) { 1861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 1862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestFormat = format; 1863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 1864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 1865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("format"), format); 1866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 1871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_channels")); 1872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int channels = 0; 1873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "Channels Stereo") { 18753b73df74357b33869b39a1d69427673c780bd805Eric Laurent channels = AUDIO_CHANNEL_OUT_STEREO; 1876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "Channels Mono") { 18773b73df74357b33869b39a1d69427673c780bd805Eric Laurent channels = AUDIO_CHANNEL_OUT_MONO; 1878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (channels != 0) { 1880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 1881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestChannels = channels; 1882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 1883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 1884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("channels"), channels); 1885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 1890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_sampleRate")); 1891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (valueInt >= 0 && valueInt <= 96000) { 1892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int samplingRate = valueInt; 1893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 1894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestSamplingRate = samplingRate; 1895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 1896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 1897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("sampling_rate"), samplingRate); 1898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 1899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 1904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_reopen")); 1905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 1907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(mPrimaryOutput); 1908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; 1910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mOutputs.valueFor(mPrimaryOutput); 1912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(mPrimaryOutput); 1913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); 1915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; 1916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput = mpClientInterface->openOutput(moduleHandle, 1917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mDevice, 1918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 1919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 1920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 1921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 1922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags); 1923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput == 0) { 1924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d", 1925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); 1926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 1928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"), 0); 1929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 1930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(mPrimaryOutput, outputDesc); 1931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 1936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1941e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::exit() 1942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AutoMutex _l(mLock); 1945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent requestExit(); 1946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mWaitWorkCV.signal(); 1947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent requestExitAndWait(); 1949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1951e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::testOutputIndex(audio_io_handle_t output) 1952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 1954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == mTestOutputs[i]) return i; 1955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- 1961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::addOutput(audio_io_handle_t output, AudioOutputDescriptor *outputDesc) 1963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 19641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mIoHandle = output; 19651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mId = nextUniqueId(); 19661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mOutputs.add(output, outputDesc); 1967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::addInput(audio_io_handle_t input, AudioInputDescriptor *inputDesc) 1970d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 19711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mIoHandle = input; 19721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mId = nextUniqueId(); 19731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mInputs.add(input, inputDesc); 1974d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 1975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19763a4311c68348f728558e87b5db67d47605783890Eric LaurentString8 AudioPolicyManager::addressToParameter(audio_devices_t device, const String8 address) 19773a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 19783a4311c68348f728558e87b5db67d47605783890Eric Laurent if (device & AUDIO_DEVICE_OUT_ALL_A2DP) { 19793a4311c68348f728558e87b5db67d47605783890Eric Laurent return String8("a2dp_sink_address=")+address; 19803a4311c68348f728558e87b5db67d47605783890Eric Laurent } 19813a4311c68348f728558e87b5db67d47605783890Eric Laurent return address; 19823a4311c68348f728558e87b5db67d47605783890Eric Laurent} 19833a4311c68348f728558e87b5db67d47605783890Eric Laurent 1984e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, 19853b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state, 1986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t>& outputs, 19873a4311c68348f728558e87b5db67d47605783890Eric Laurent const String8 address) 1988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc; 1990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19913b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { 1992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // first list already open outputs that can be routed to this device 1993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(i); 19953a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) { 1996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i)); 1997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(mOutputs.keyAt(i)); 1998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // then look for output profiles that can be routed to this device 20011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent SortedVector< sp<IOProfile> > profiles; 2002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 2003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 2005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 2008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 20093a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) { 2010d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i); 2011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profiles.add(mHwModules[i]->mOutputProfiles[j]); 2012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profiles.isEmpty() && outputs.isEmpty()) { 2017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 2018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 2019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open outputs for matching profiles if needed. Direct outputs are also opened to 2022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 2023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 20241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = profiles[profile_index]; 2025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // nothing to do if one output is already opened for this profile 2027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent size_t j; 2028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (j = 0; j < mOutputs.size(); j++) { 2029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(j); 2030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && desc->mProfile == profile) { 2031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (j != mOutputs.size()) { 2035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 20383a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("opening output for device %08x with params %s", device, address.string()); 2039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = new AudioOutputDescriptor(profile); 2040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mDevice = device; 2041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; 2042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate = desc->mSamplingRate; 2043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format = desc->mFormat; 2044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.channel_mask = desc->mChannelMask; 2045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle, 2047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mDevice, 2048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mSamplingRate, 2049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mFormat, 2050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mChannelMask, 2051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mLatency, 2052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mFlags, 2053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &offloadInfo); 2054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output != 0) { 2055d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where the out_set_parameters() for card & device gets called 20563a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!address.isEmpty()) { 20573a4311c68348f728558e87b5db67d47605783890Eric Laurent mpClientInterface->setParameters(output, addressToParameter(device, address)); 2058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2060d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where we step through and resolve any "dynamic" fields 2061d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 reply; 2062d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char *value; 2063d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 2064d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 2065d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 2066d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice() direct output sup sampling rates %s", 2067d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2068d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2069d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 20701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadSamplingRates(value + 1); 2071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2072d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2073d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2074d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 2075d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 2076d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice() direct output sup formats %s", 2077d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2078d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2079d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 20801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadFormats(value + 1); 2081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2082d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2083d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 2084d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 2085d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 2086d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice() direct output sup channel masks %s", 2087d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2088d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2089d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 20901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadOutChannels(value + 1); 2091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2092d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2093d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (((profile->mSamplingRates[0] == 0) && 2094d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mSamplingRates.size() < 2)) || 2095d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) && 2096d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mFormats.size() < 2)) || 2097d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mChannelMasks[0] == 0) && 2098d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mChannelMasks.size() < 2))) { 2099d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkOutputsForDevice() direct output missing param"); 2100d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 2101d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent output = 0; 2102d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else if (profile->mSamplingRates[0] == 0) { 2103d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 2104d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc->mSamplingRate = profile->mSamplingRates[1]; 2105d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent offloadInfo.sample_rate = desc->mSamplingRate; 2106d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent output = mpClientInterface->openOutput( 2107d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mModule->mHandle, 2108d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mDevice, 2109d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mSamplingRate, 2110d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mFormat, 2111d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mChannelMask, 2112d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mLatency, 2113d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc->mFlags, 2114d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &offloadInfo); 2115d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2116d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2117d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (output != 0) { 2118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, desc); 2119d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { 2120d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent audio_io_handle_t duplicatedOutput = 0; 2121d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2122d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // set initial stream volume for device 2123d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent applyStreamVolumes(output, device, 0, true); 2124d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2125d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent //TODO: configure audio effect output stage here 2126d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2127d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // open a duplicating output thread for the new output and the primary output 2128d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent duplicatedOutput = mpClientInterface->openDuplicateOutput(output, 2129d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mPrimaryOutput); 2130d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (duplicatedOutput != 0) { 2131d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // add duplicated output descriptor 2132d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL); 2133d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); 2134d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mOutput2 = mOutputs.valueFor(output); 2135d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mSamplingRate = desc->mSamplingRate; 2136d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mFormat = desc->mFormat; 2137d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mChannelMask = desc->mChannelMask; 2138d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mLatency = desc->mLatency; 2139d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addOutput(duplicatedOutput, dupOutputDesc); 2140d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent applyStreamVolumes(duplicatedOutput, device, 0, true); 2141d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 2142d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkOutputsForDevice() could not open dup output for %d and %d", 2143d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mPrimaryOutput, output); 2144d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 2145d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mOutputs.removeItem(output); 2146d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent output = 0; 2147d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == 0) { 2152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice() could not open output for device %x", device); 2153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete desc; 2154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profiles.removeAt(profile_index); 2155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile_index--; 2156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(output); 2158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputsForDevice(): adding output %d", output); 2159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profiles.isEmpty()) { 2163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 2164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 2165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2166d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { // Disconnect 2167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check if one opened output is not needed any more after disconnecting one device 2168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(i); 2170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && 21713a4311c68348f728558e87b5db67d47605783890Eric Laurent !(desc->mProfile->mSupportedDevices.types() & 21723a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.types())) { 2173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i)); 2174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(mOutputs.keyAt(i)); 2175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2177d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Clear any profiles associated with the disconnected device. 2178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 2179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 2181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 2184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 21851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j]; 2186d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSupportedDevices.types() & device) { 2187d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice(): " 2188d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent "clearing direct output profile %zu on module %zu", j, i); 2189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mSamplingRates[0] == 0) { 2190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.clear(); 2191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(0); 2192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.clear(); 2195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 2196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mChannelMasks[0] == 0) { 2198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.clear(); 2199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(0); 2200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 2206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2208d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentstatus_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, 2209d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent audio_policy_dev_state_t state, 2210d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector<audio_io_handle_t>& inputs, 2211d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent const String8 address) 2212d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 2213d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent AudioInputDescriptor *desc; 2214d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { 2215d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // first list already open inputs that can be routed to this device 2216d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 2217d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 2218d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (desc->mProfile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) { 2219d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index)); 2220d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(mInputs.keyAt(input_index)); 2221d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2222d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2223d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2224d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // then look for input profiles that can be routed to this device 22251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent SortedVector< sp<IOProfile> > profiles; 2226d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++) 2227d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent { 2228d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_idx]->mHandle == 0) { 2229d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 2230d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2231d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t profile_index = 0; 2232d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index < mHwModules[module_idx]->mInputProfiles.size(); 2233d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index++) 2234d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent { 2235d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_idx]->mInputProfiles[profile_index]->mSupportedDevices.types() 2236d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent & (device & ~AUDIO_DEVICE_BIT_IN)) { 2237d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding profile %d from module %d", 2238d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index, module_idx); 2239d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profiles.add(mHwModules[module_idx]->mInputProfiles[profile_index]); 2240d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2241d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2242d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2243d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2244d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profiles.isEmpty() && inputs.isEmpty()) { 2245d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 2246d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return BAD_VALUE; 2247d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2248d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2249d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // open inputs for matching profiles if needed. Direct inputs are also opened to 2250d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 2251d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 2252d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 22531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = profiles[profile_index]; 2254d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // nothing to do if one input is already opened for this profile 2255d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent size_t input_index; 2256d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (input_index = 0; input_index < mInputs.size(); input_index++) { 2257d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 2258d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (desc->mProfile == profile) { 2259d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent break; 2260d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2261d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2262d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input_index != mInputs.size()) { 2263d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 2264d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2265d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2266d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("opening input for device 0x%X with params %s", device, address.string()); 2267d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = new AudioInputDescriptor(profile); 2268d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc->mDevice = device; 2269d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2270d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle, 2271d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mDevice, 2272d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mSamplingRate, 2273d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mFormat, 2274d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mChannelMask); 2275d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2276d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input != 0) { 2277d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (!address.isEmpty()) { 2278d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->setParameters(input, addressToParameter(device, address)); 2279d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2280d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2281d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where we step through and resolve any "dynamic" fields 2282d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 reply; 2283d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char *value; 2284d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 2285d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 2286d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 2287d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup sampling rates %s", 2288d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2289d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2290d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 22911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadSamplingRates(value + 1); 2292d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2293d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2294d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2295d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 2296d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 2297d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string()); 2298d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2299d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 23001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadFormats(value + 1); 2301d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2302d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2303d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 2304d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 2305d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 2306d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup channel masks %s", 2307d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2308d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2309d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 23101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadInChannels(value + 1); 2311d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2312d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2313d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) || 2314d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) || 2315d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) { 2316d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice() direct input missing param"); 2317d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeInput(input); 2318d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent input = 0; 2319d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2320d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2321d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input != 0) { 2322d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addInput(input, desc); 2323d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2324d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // endif input != 0 2325d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2326d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input == 0) { 2327d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice() could not open input for device 0x%X", device); 2328d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent delete desc; 2329d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profiles.removeAt(profile_index); 2330d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index--; 2331d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 2332d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(input); 2333d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding input %d", input); 2334d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2335d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end scan profiles 2336d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2337d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profiles.isEmpty()) { 2338d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 2339d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return BAD_VALUE; 2340d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2341d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 2342d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Disconnect 2343d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // check if one opened input is not needed any more after disconnecting one device 2344d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 2345d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 2346d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types())) { 2347d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): disconnecting adding input %d", 2348d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mInputs.keyAt(input_index)); 2349d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(mInputs.keyAt(input_index)); 2350d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2351d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2352d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Clear any profiles associated with the disconnected device. 2353d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) { 2354d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_index]->mHandle == 0) { 2355d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 2356d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2357d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t profile_index = 0; 2358d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index < mHwModules[module_index]->mInputProfiles.size(); 2359d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index++) { 23601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index]; 2361d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSupportedDevices.types() & device) { 2362d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): clearing direct input profile %d on module %d", 2363d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index, module_index); 2364d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 2365d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mSamplingRates.clear(); 2366d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mSamplingRates.add(0); 2367d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2368d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2369d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mFormats.clear(); 2370d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 2371d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2372d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 2373d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mChannelMasks.clear(); 2374d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mChannelMasks.add(0); 2375d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2376d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2377d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2378d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2379d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end disconnect 2380d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2381d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return NO_ERROR; 2382d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 2383d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2384d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2385e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::closeOutput(audio_io_handle_t output) 2386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("closeOutput(%d)", output); 2388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc == NULL) { 2391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("closeOutput() unknown output %d", output); 2392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 2393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // look for duplicated outputs connected to the output being removed. 2396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i); 2398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dupOutputDesc->isDuplicated() && 2399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (dupOutputDesc->mOutput1 == outputDesc || 2400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent dupOutputDesc->mOutput2 == outputDesc)) { 2401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc2; 2402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dupOutputDesc->mOutput1 == outputDesc) { 2403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc2 = dupOutputDesc->mOutput2; 2404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc2 = dupOutputDesc->mOutput1; 2406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // As all active tracks on duplicated output will be deleted, 2408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and as they were also referenced on the other output, the reference 2409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // count for their stream type must be adjusted accordingly on 2410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the other output. 24113b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int j = 0; j < AUDIO_STREAM_CNT; j++) { 2412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int refCount = dupOutputDesc->mRefCount[j]; 24133b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount); 2414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i); 2416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); 2417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(duplicatedOutput); 2419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete mOutputs.valueFor(duplicatedOutput); 2420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(duplicatedOutput); 2421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param; 2425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.add(String8("closing"), String8("true")); 2426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(output, param.toString()); 2427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 2429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete outputDesc; 2430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(output); 2431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 2432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2434e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device, 2435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs) 2436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> outputs; 2438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getOutputsForDevice() device %04x", device); 2440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < openOutputs.size(); i++) { 2441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("output %d isDuplicated=%d device=%04x", 2442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices()); 2443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) { 2444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i)); 2445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(openOutputs.keyAt(i)); 2446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs; 2449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2451e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, 2452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t>& outputs2) 2453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs1.size() != outputs2.size()) { 2455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs1.size(); i++) { 2458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs1[i] != outputs2[i]) { 2459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 2463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2465e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy) 2466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); 2468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); 2469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs); 2470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); 2471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!vectorsEqual(srcOutputs,dstOutputs)) { 2473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", 2474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent strategy, srcOutputs[0], dstOutputs[0]); 2475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute strategy while moving tracks from one output to another 2476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < srcOutputs.size(); i++) { 2477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]); 2478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->isStrategyActive(strategy)) { 2479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(strategy, true, srcOutputs[i]); 2480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); 2481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Move effects associated to this strategy from previous output to new output 2485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strategy == STRATEGY_MEDIA) { 2486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs); 2487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> moved; 2488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 2489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent EffectDescriptor *desc = mEffects.valueAt(i); 2490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX && 2491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mIo != fxOutput) { 2492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (moved.indexOf(desc->mIo) < 0) { 2493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputForStrategy() moving effect %d to output %d", 2494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.keyAt(i), fxOutput); 2495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, desc->mIo, 2496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent fxOutput); 2497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent moved.add(desc->mIo); 2498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mIo = fxOutput; 2500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Move tracks associated to this strategy from previous output to new output 25043b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 25053b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (getStrategy((audio_stream_type_t)i) == strategy) { 25063b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->invalidateStream((audio_stream_type_t)i); 2507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2512e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForAllStrategies() 2513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 2515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_PHONE); 2516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION); 2517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 2518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_MEDIA); 2519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_DTMF); 2520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2522e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getA2dpOutput() 2523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); 2526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 2527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutputs.keyAt(i); 2528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 2532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2534e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkA2dpSuspend() 2535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t a2dpOutput = getA2dpOutput(); 2537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (a2dpOutput == 0) { 25383a4311c68348f728558e87b5db67d47605783890Eric Laurent mA2dpSuspended = false; 2539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 2540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 25423a4311c68348f728558e87b5db67d47605783890Eric Laurent bool isScoConnected = 25433a4311c68348f728558e87b5db67d47605783890Eric Laurent (mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) != 0; 2544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // suspend A2DP output if: 2545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (NOT already suspended) && 2546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ((SCO device is connected && 2547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (forced usage for communication || for record is SCO))) || 2548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (phone state is ringing || in call) 2549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // restore A2DP output if: 2551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (Already suspended) && 2552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ((SCO device is NOT connected || 2553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (forced usage NOT for communication && NOT for record is SCO))) && 2554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (phone state is NOT ringing && NOT in call) 2555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mA2dpSuspended) { 25573a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((!isScoConnected || 25583b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO) && 25593b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] != AUDIO_POLICY_FORCE_BT_SCO))) && 25603b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mPhoneState != AUDIO_MODE_IN_CALL) && 25613b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mPhoneState != AUDIO_MODE_RINGTONE))) { 2562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->restoreOutput(a2dpOutput); 2564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mA2dpSuspended = false; 2565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 25673a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((isScoConnected && 25683b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) || 25693b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO))) || 25703b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mPhoneState == AUDIO_MODE_IN_CALL) || 25713b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mPhoneState == AUDIO_MODE_RINGTONE))) { 2572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->suspendOutput(a2dpOutput); 2574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mA2dpSuspended = true; 2575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 25791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentaudio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, bool fromCache) 2580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = AUDIO_DEVICE_NONE; 2582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check the following by order of priority to request a routing change if necessary: 2585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: the strategy enforced audible is active on the output: 2586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy enforced audible 2587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: we are in call or the strategy phone is active on the output: 2588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy phone 2589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the strategy sonification is active on the output: 2590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy sonification 2591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 4: the strategy "respectful" sonification is active on the output: 2592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy "respectful" sonification 2593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 5: the strategy media is active on the output: 2594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy media 2595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 6: the strategy DTMF is active on the output: 2596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy DTMF 2597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { 2598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 2599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isInCall() || 2600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->isStrategyActive(STRATEGY_PHONE)) { 2601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 2602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) { 2603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 2604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { 2605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); 2606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { 2607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 2608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { 2609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 2610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 26121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("getNewOutputDevice() selected device %x", device); 26131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return device; 26141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 26151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 26161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentaudio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input) 26171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 26181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AudioInputDescriptor *inputDesc = mInputs.valueFor(input); 26191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t device = getDeviceForInputSource(inputDesc->mInputSource); 26201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 26211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("getNewInputDevice() selected device %x", device); 2622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 2623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2625e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) { 2626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (uint32_t)getStrategy(stream); 2627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2629e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) { 2630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t devices; 2631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // By checking the range of stream before calling getStrategy, we avoid 2632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 2633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and then return STRATEGY_MEDIA, but we want to return the empty set. 26343b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_CNT) { 2635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devices = AUDIO_DEVICE_NONE; 2636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2637e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::routing_strategy strategy = getStrategy(stream); 2638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devices = getDeviceForStrategy(strategy, true /*fromCache*/); 2639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return devices; 2641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2643e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy( 26443b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream) { 2645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // stream to strategy mapping 2646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (stream) { 26473b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_VOICE_CALL: 26483b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_BLUETOOTH_SCO: 2649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_PHONE; 26503b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_RING: 26513b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_ALARM: 2652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_SONIFICATION; 26533b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_NOTIFICATION: 2654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_SONIFICATION_RESPECTFUL; 26553b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_DTMF: 2656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_DTMF; 2657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 2658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("unknown stream type"); 26593b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_SYSTEM: 2660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 2661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while key clicks are played produces a poor result 26623b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_TTS: 26633b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_MUSIC: 2664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_MEDIA; 26653b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_ENFORCED_AUDIBLE: 2666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 2667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2670e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) { 2671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(stream) { 26723b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_MUSIC: 2673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 2674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 2675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 2677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2681e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, 2682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool fromCache) 2683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 2685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (fromCache) { 2687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x", 2688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent strategy, mDeviceForStrategy[strategy]); 2689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mDeviceForStrategy[strategy]; 2690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 26913a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types(); 2692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (strategy) { 2693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_SONIFICATION_RESPECTFUL: 2695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 2696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 26973b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC, 2698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 2699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while media is playing on a remote device, use the the sonification behavior. 2700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Note that we test this usecase before testing if media is playing because 2701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the isStreamActive() method only informs about the activity of a stream, not 2702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if it's for local playback. Note also that we use the same delay between both tests 2703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 27043b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 2705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while media is playing (or has recently played), use the same device 2706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 2707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when media is not playing anymore, fall back on the sonification behavior 2709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 2710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_DTMF: 2715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isInCall()) { 2716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when off call, DTMF strategy follows the same rules as MEDIA strategy 2717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 2718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when in call, DTMF and PHONE strategies follow the same rules 2721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 2722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_PHONE: 2724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // for phone strategy, we first consider the forced use and then the available devices by order 2725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // of priority 27263b73df74357b33869b39a1d69427673c780bd805Eric Laurent switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) { 27273b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_BT_SCO: 2728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isInCall() || strategy != STRATEGY_DTMF) { 27293a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 2730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 27323a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 2733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27343a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; 2735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if SCO device is requested but no SCO device is available, fall back to default case 2737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 2738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: // FORCE_NONE 2740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 27413a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!isInCall() && 27423b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 2743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 27443a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 2745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27463a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 27493a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 2750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27513a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET; 2752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27533b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mPhoneState != AUDIO_MODE_IN_CALL) { 27543a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27563a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 2757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27583a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27603a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27623a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 27653a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE; 2766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 2768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); 2770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 27733b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_SPEAKER: 2774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 2775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // A2DP speaker when forcing to speaker output 27763a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!isInCall() && 27773b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 2778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 27793a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 27823b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mPhoneState != AUDIO_MODE_IN_CALL) { 27833a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27853a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 2786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27873a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27893a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27913a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 2793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 27943a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 2795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 27961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 2797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); 2799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_SONIFICATION: 2805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 2807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handleIncallSonification(). 2808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 2809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); 2810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 2813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 2815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 2816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // except: 2817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - when in call where it doesn't default to STRATEGY_PHONE behavior 2818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - in countries where not enforced in which case it follows STRATEGY_MEDIA 2819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((strategy == STRATEGY_SONIFICATION) || 28213b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) { 28223a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 2823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); 2825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The second device used for sonification is the same as the device used by media strategy 2828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 2829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_MEDIA: { 2831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device2 = AUDIO_DEVICE_NONE; 2832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strategy != STRATEGY_SONIFICATION) { 2833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no sonification on remote submix (e.g. WFD) 28343a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; 2835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 28373b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 2838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 28393a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 2840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28413a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28443a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28483a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 2849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28513a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET; 2852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28543a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 2855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28573a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 2858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28603a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 2861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { 2863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no sonification on aux digital (e.g. HDMI) 28643a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 2865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 28673b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) { 28683a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 2869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 28713a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 2872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 2875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise 2876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device |= device2; 2877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 28781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 2879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 2880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); 2881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } break; 2883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 2885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 2886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 2890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 2891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2893e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::updateDevicesAndOutputs() 2894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_STRATEGIES; i++) { 2896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 2897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 2899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2901e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc, 2902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t prevDevice, 2903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t delayMs) 2904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute/unmute strategies using an incompatible device combination 2906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if muting, wait for the audio in pcm buffer to be drained before proceeding 2907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if unmuting, unmute only after the specified delay 2908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isDuplicated()) { 2909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 2910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs = 0; 2913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = outputDesc->device(); 29143b73df74357b33869b39a1d69427673c780bd805Eric Laurent bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2); 2915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 2917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 2918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool mute = shouldMute && (curDevice & device) && (curDevice != device); 2919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool doMute = false; 2920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mute && !outputDesc->mStrategyMutedByDevice[i]) { 2922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent doMute = true; 2923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = true; 2924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){ 2925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent doMute = true; 2926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = false; 2927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 292899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (doMute) { 2929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mOutputs.size(); j++) { 2930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *desc = mOutputs.valueAt(j); 2931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // skip output if it does not share any device with current output 2932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->supportedDevices() & outputDesc->supportedDevices()) 2933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent == AUDIO_DEVICE_NONE) { 2934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(j); 2937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", 2938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mute ? "muting" : "unmuting", i, curDevice, curOutput); 2939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); 2940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->isStrategyActive((routing_strategy)i)) { 294199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (mute) { 294299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // FIXME: should not need to double latency if volume could be applied 294399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // immediately by the audioflinger mixer. We must account for the delay 294499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // between now and the next time the audioflinger thread for this output 294599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // will process a buffer (which corresponds to one buffer size, 294699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // usually 1/2 or 1/4 of the latency). 294799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (muteWaitMs < desc->latency() * 2) { 294899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs = desc->latency() * 2; 2949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 295699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // temporary mute output if device selection changes to avoid volume bursts due to 295799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // different per device volumes 295899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (outputDesc->isActive() && (device != prevDevice)) { 295999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (muteWaitMs < outputDesc->latency() * 2) { 296099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs = outputDesc->latency() * 2; 296199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 296299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 296399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (outputDesc->isStrategyActive((routing_strategy)i)) { 29641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setStrategyMute((routing_strategy)i, true, outputDesc->mIoHandle); 296599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // do tempMute unmute after twice the mute wait time 29661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setStrategyMute((routing_strategy)i, false, outputDesc->mIoHandle, 296799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs *2, device); 296899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 296999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 297099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 297199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent 2972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // wait for the PCM output buffers to empty before proceeding with the rest of the command 2973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (muteWaitMs > delayMs) { 2974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs -= delayMs; 2975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent usleep(muteWaitMs * 1000); 2976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 2977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 2979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2981e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output, 2982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 2983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force, 2984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs) 2985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); 2987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 2988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param; 2989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs; 2990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isDuplicated()) { 29921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent muteWaitMs = setOutputDevice(outputDesc->mOutput1->mIoHandle, device, force, delayMs); 29931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent muteWaitMs += setOutputDevice(outputDesc->mOutput2->mIoHandle, device, force, delayMs); 2994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 2995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current 2997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // output profile 2998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device != AUDIO_DEVICE_NONE) && 29993a4311c68348f728558e87b5db67d47605783890Eric Laurent ((device & outputDesc->mProfile->mSupportedDevices.types()) == 0)) { 3000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 3001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // filter devices according to output selected 30043a4311c68348f728558e87b5db67d47605783890Eric Laurent device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices.types()); 3005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t prevDevice = outputDesc->mDevice; 3007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() prevDevice %04x", prevDevice); 3009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device != AUDIO_DEVICE_NONE) { 3011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = device; 3012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); 3014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not change the routing if: 3016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the requested device is AUDIO_DEVICE_NONE 3017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the requested device is the same as current device and force is not specified. 3018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Doing this check here allows the caller to call setOutputDevice() without conditions 3019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) { 3020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); 3021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 3022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() changing device"); 30251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 3026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do the routing 30271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (device == AUDIO_DEVICE_NONE) { 30281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent resetOutputDevice(output, delayMs); 30291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 30301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent DeviceVector deviceList = mAvailableOutputDevices.getDevicesFromType(device); 30311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (!deviceList.isEmpty()) { 30321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_patch patch; 30331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->toAudioPortConfig(&patch.sources[0]); 30341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sources = 1; 30351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks = 0; 30361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) { 30371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]); 30381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.sinks[i].ext.device.hw_module = patch.sources[0].ext.mix.hw_module; 30391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks++; 30401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 30411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_patch_handle_t patchHandle = outputDesc->mPatchHandle; 30421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = mpClientInterface->createAudioPatch(&patch, 30431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent &patchHandle, 30441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent delayMs); 30451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d" 30461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent "num_sources %d num_sinks %d", 30471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status, patchHandle, patch.num_sources, patch.num_sinks); 30481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (status == NO_ERROR) { 30491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mPatchHandle = patchHandle; 30501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 30511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 30521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 3053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update stream volumes according to new device 3055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent applyStreamVolumes(output, device, delayMs); 3056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 3058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output, 30611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent int delayMs) 30621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 30631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 30641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (outputDesc->mPatchHandle == 0) { 30651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return INVALID_OPERATION; 30661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 30671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = mpClientInterface->releaseAudioPatch(outputDesc->mPatchHandle, delayMs); 30681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status); 30691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mPatchHandle = 0; 30701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 30711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 30721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 30731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::setInputDevice(audio_io_handle_t input, 30741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t device, 30751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent bool force) 30761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 30771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 30781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 30791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AudioInputDescriptor *inputDesc = mInputs.valueFor(input); 30801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) { 30811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mDevice = device; 30821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 30831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device); 30841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (!deviceList.isEmpty()) { 30851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_patch patch; 30861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->toAudioPortConfig(&patch.sinks[0]); 30871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks = 1; 30881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent //only one input device for now 30891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]); 30901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.sources[0].ext.device.hw_module = patch.sinks[0].ext.mix.hw_module; 30911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sources = 1; 30921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_patch_handle_t patchHandle = inputDesc->mPatchHandle; 30931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = mpClientInterface->createAudioPatch(&patch, 30941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent &patchHandle, 30951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 0); 30961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d", 30971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status, patchHandle); 30981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (status == NO_ERROR) { 30991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mPatchHandle = patchHandle; 31001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 31011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 31021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 31031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 31041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 31051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 31061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input) 31071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 31081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AudioInputDescriptor *inputDesc = mInputs.valueFor(input); 31091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (inputDesc->mPatchHandle == 0) { 31101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return INVALID_OPERATION; 31111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 31121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = mpClientInterface->releaseAudioPatch(inputDesc->mPatchHandle, 0); 31131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("resetInputDevice() releaseAudioPatch returned %d", status); 31141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mPatchHandle = 0; 31151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 31161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 31171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 31181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device, 3119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 3120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 3121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask) 3122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Choose an input profile based on the requested capture parameters: select the first available 3124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // profile supporting all requested parameters. 3125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 3127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 3129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 3130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 3132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 31331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j]; 3134d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // profile->log(); 3135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 3136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, AUDIO_OUTPUT_FLAG_NONE)) { 3137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return profile; 3138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NULL; 3142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3144e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource) 3145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 31473a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & 31483a4311c68348f728558e87b5db67d47605783890Eric Laurent ~AUDIO_DEVICE_BIT_IN; 3149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (inputSource) { 3150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 31513a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { 3152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 3153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 3156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_DEFAULT: 3158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_MIC: 3159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_RECOGNITION: 3160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_HOTWORD: 3161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_COMMUNICATION: 31623b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO && 31633a4311c68348f728558e87b5db67d47605783890Eric Laurent availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 3164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 31653a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { 3166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_WIRED_HEADSET; 3167d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { 3168d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent device = AUDIO_DEVICE_IN_USB_DEVICE; 31693a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 3170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 3171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_CAMCORDER: 31743a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) { 3175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BACK_MIC; 31763a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 3177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 3178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_DOWNLINK: 3181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_CALL: 31823a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { 3183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 3184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_REMOTE_SUBMIX: 31873a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { 3188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; 3189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 3192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 3193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 3196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 3197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3199e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device) 3200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & AUDIO_DEVICE_BIT_IN) != 0) { 3202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device &= ~AUDIO_DEVICE_BIT_IN; 3203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) 3204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3209e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs) 3210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 3212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const AudioInputDescriptor * input_descriptor = mInputs.valueAt(i); 3213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((input_descriptor->mRefCount > 0) 3214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) { 3215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mInputs.keyAt(i); 3216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 3219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3222e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device) 3223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this happens when forcing a route update and no track is active on an output. 3226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // In this case the returned category is not important. 3227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 32283b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (popcount(device) > 1) { 3229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Multiple device selection is either: 3230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - speaker + one other device: give priority to speaker in this case. 3231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 3232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 3233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // selection if not the speaker. 3234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 3235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 3236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 3238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 32413b73df74357b33869b39a1d69427673c780bd805Eric Laurent ALOGW_IF(popcount(device) != 1, 3242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 3243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device); 3244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 3246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3248e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device) 3249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(getDeviceForVolume(device)) { 3251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 3252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_EARPIECE; 3253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 3254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 3255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 3256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 3257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 3258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 3259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_HEADSET; 3260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 3261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 3262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 3263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_AUX_DIGITAL: 3264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_USB_ACCESSORY: 3265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_USB_DEVICE: 3266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_REMOTE_SUBMIX: 3267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 3268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_SPEAKER; 3269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3272e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, 3273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexInUi) 3274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device_category deviceCategory = getDeviceCategory(device); 3276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 3277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the volume index in the UI is relative to the min and max volume indices for this stream type 3279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 3280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[VOLMIN].mIndex; 3281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 3282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (streamDesc.mIndexMax - streamDesc.mIndexMin); 3283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // find what part of the curve this index volume belongs to, or if it's out of bounds 3285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int segment = 0; 3286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 3287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0.0f; 3288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 3289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 0; 3290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 3291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 1; 3292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 3293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 2; 3294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { // out of bounds 3295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 1.0f; 3296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // linear interpolation in the attenuation table in dB 3299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float decibels = curve[segment].mDBAttenuation + 3300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 3301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ( (curve[segment+1].mDBAttenuation - 3302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mDBAttenuation) / 3303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((float)(curve[segment+1].mIndex - 3304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mIndex)) ); 3305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 3307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 3309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mIndex, volIdx, 3310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment+1].mIndex, 3311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mDBAttenuation, 3312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent decibels, 3313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment+1].mDBAttenuation, 3314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent amplification); 3315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return amplification; 3317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3319e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3320e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultVolumeCurve[AudioPolicyManager::VOLCNT] = { 3321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 3322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3324e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3325e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { 3326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 3327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3329e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3330e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { 3331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 3332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3334e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3335e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = { 3336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 3337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3339e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3340e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 3341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f} 3342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks 3345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets. 3346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java). 3347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset. 3348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3349e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3350e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 3351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f} 3352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3354e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3355e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 3356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f} 3357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3359e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3360e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 3361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f} 3362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3364e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3365e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { 3366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f} 3367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3369e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3370e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { 3371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f} 3372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3374e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 3375e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT] 3376e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent [AudioPolicyManager::DEVICE_CATEGORY_CNT] = { 3377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_VOICE_CALL 3378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 3379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 3381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_SYSTEM 3383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 3384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 3386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_RING 3388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 3389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 3391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_MUSIC 3393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 3394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 3396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_ALARM 3398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 3399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 3401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_NOTIFICATION 3403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 3404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 3406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_BLUETOOTH_SCO 3408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 3409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 3411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_ENFORCED_AUDIBLE 3413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 3414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 3416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_DTMF 3418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 3419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 3421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_TTS 3423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 3424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 3425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 3426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 3427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 3428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3429e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initializeVolumeCurves() 3430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 3432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 3433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[i].mVolumeCurve[j] = 3434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[i][j]; 3435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check availability of DRC on speaker path: if available, override some of the speaker curves 3439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mSpeakerDrcEnabled) { 3440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 3441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurveDrc; 3442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 3443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 3444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 3445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 3446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 3447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 3448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3451e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::computeVolume(audio_stream_type_t stream, 3452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 3453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 3454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 3455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float volume = 1.0; 3457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 3458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent StreamDescriptor &streamDesc = mStreams[stream]; 3459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = outputDesc->device(); 3462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if volume is not 0 (not muted), force media volume to max on digital output 34653b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_MUSIC && 3466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent index != mStreams[stream].mIndexMin && 3467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (device == AUDIO_DEVICE_OUT_AUX_DIGITAL || 3468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET || 3469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device == AUDIO_DEVICE_OUT_USB_ACCESSORY || 3470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device == AUDIO_DEVICE_OUT_USB_DEVICE)) { 3471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 1.0; 3472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume = volIndexToAmpl(device, streamDesc, index); 3475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if a headset is connected, apply the following rules to ring tones and notifications 3477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // to avoid sound level bursts in user's ears: 3478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - always attenuate ring tones and notifications volume by 6dB 3479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - if music is playing, always limit the volume to current music volume, 3480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // with a minimum threshold at -36dB so that notification is always perceived. 34813b73df74357b33869b39a1d69427673c780bd805Eric Laurent const routing_strategy stream_strategy = getStrategy(stream); 3482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | 3483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 3484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADSET | 3485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) && 3486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((stream_strategy == STRATEGY_SONIFICATION) 3487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) 34883b73df74357b33869b39a1d69427673c780bd805Eric Laurent || (stream == AUDIO_STREAM_SYSTEM) 3489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) && 34903b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) && 3491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent streamDesc.mCanBeMuted) { 3492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 3493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when the phone is ringing we must consider that music could have been paused just before 3494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by the music application and behave as if music was active if the last music track was 3495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // just stopped 34963b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || 3497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume) { 3498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/); 34993b73df74357b33869b39a1d69427673c780bd805Eric Laurent float musicVol = computeVolume(AUDIO_STREAM_MUSIC, 35003b73df74357b33869b39a1d69427673c780bd805Eric Laurent mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice), 3501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 3502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent musicDevice); 3503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 3504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 3505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volume > minVol) { 3506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume = minVol; 3507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 3508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return volume; 3513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3515e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream, 3516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 3517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 3518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 3519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 3520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force) 3521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not change actual stream volume if the stream is muted 3524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 3525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkAndSetVolume() stream %d muted count %d", 3526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, mOutputs.valueFor(output)->mMuteCount[stream]); 3527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 3528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not change in call volume if bluetooth is connected and vice versa 35313b73df74357b33869b39a1d69427673c780bd805Eric Laurent if ((stream == AUDIO_STREAM_VOICE_CALL && 35323b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) || 35333b73df74357b33869b39a1d69427673c780bd805Eric Laurent (stream == AUDIO_STREAM_BLUETOOTH_SCO && 35343b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO)) { 3535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 35363b73df74357b33869b39a1d69427673c780bd805Eric Laurent stream, mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]); 3537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 3538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float volume = computeVolume(stream, index, output, device); 3541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // We actually change the volume if: 3542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the float value returned by computeVolume() changed 3543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the force flag is set 3544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 3545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force) { 3546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.valueFor(output)->mCurVolume[stream] = volume; 3547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 3548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 3549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // enabled 35503b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_BLUETOOTH_SCO) { 35513b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs); 3552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 35533b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->setStreamVolume(stream, volume, output, delayMs); 3554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 35563b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_VOICE_CALL || 35573b73df74357b33869b39a1d69427673c780bd805Eric Laurent stream == AUDIO_STREAM_BLUETOOTH_SCO) { 3558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float voiceVolume; 3559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force voice volume to max for bluetooth SCO as volume is managed by the headset 35603b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_VOICE_CALL) { 3561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 3562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent voiceVolume = 1.0; 3564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { 3567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 3568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLastVoiceVolume = voiceVolume; 3569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 3573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3575e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output, 3576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 3577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 3578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force) 3579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("applyStreamVolumes() for output %d and device %x", output, device); 3581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 35823b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 35833b73df74357b33869b39a1d69427673c780bd805Eric Laurent checkAndSetVolume((audio_stream_type_t)stream, 3584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].getVolumeIndex(device), 3585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 3586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, 3587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs, 3588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force); 3589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3592e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStrategyMute(routing_strategy strategy, 3593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool on, 3594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 3595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 3596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 3597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 35993b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 36003b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (getStrategy((audio_stream_type_t)stream) == strategy) { 36013b73df74357b33869b39a1d69427673c780bd805Eric Laurent setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device); 3602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3606e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStreamMute(audio_stream_type_t stream, 3607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool on, 3608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 3609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 3610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 3611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent StreamDescriptor &streamDesc = mStreams[stream]; 3613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 3614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = outputDesc->device(); 3616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x", 3619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, on, output, outputDesc->mMuteCount[stream], device); 3620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (on) { 3622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mMuteCount[stream] == 0) { 3623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (streamDesc.mCanBeMuted && 36243b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) || 36253b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) { 3626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 3627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 3630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mMuteCount[stream]++; 3631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mMuteCount[stream] == 0) { 3633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setStreamMute() unmuting non muted stream!"); 3634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 3635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (--outputDesc->mMuteCount[stream] == 0) { 3637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 3638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent streamDesc.getVolumeIndex(device), 3639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 3640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, 3641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs); 3642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3646e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream, 36473b73df74357b33869b39a1d69427673c780bd805Eric Laurent bool starting, bool stateChange) 3648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if the stream pertains to sonification strategy and we are in call we must 3650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute the stream if it is low visibility. If it is high visibility, we must play a tone 3651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the device used for phone strategy and play the tone if the selected device does not 3652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // interfere with the device used for phone strategy 3653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 3654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // many times as there are active tracks on the output 36553b73df74357b33869b39a1d69427673c780bd805Eric Laurent const routing_strategy stream_strategy = getStrategy(stream); 3656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((stream_strategy == STRATEGY_SONIFICATION) || 3657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { 3658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); 3659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 3660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, starting, outputDesc->mDevice, stateChange); 3661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream]) { 3662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int muteCount = 1; 3663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (stateChange) { 3664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteCount = outputDesc->mRefCount[stream]; 3665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 36663b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (audio_is_low_visibility(stream)) { 3667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 3668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < muteCount; i++) { 3669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 3670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() high visibility"); 3673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->device() & 3674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) { 3675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 3676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < muteCount; i++) { 3677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 3678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (starting) { 36813b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION, 36823b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_STREAM_VOICE_CALL); 3683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->stopTone(); 3685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3691e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isInCall() 3692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return isStateInCall(mPhoneState); 3694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3696e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStateInCall(int state) { 36973b73df74357b33869b39a1d69427673c780bd805Eric Laurent return ((state == AUDIO_MODE_IN_CALL) || 36983b73df74357b33869b39a1d69427673c780bd805Eric Laurent (state == AUDIO_MODE_IN_COMMUNICATION)); 3699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3701e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsCpuLoad() 3702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return MAX_EFFECTS_CPU_LOAD; 3704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3706e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsMemory() 3707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return MAX_EFFECTS_MEMORY; 3709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioOutputDescriptor class implementation 3712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3713e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor( 37141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile>& profile) 37151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent : mId(0), mIoHandle(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), 3716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mChannelMask(0), mLatency(0), 37171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), 3718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0) 3719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // clear usage count for all stream types 37213b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 3722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[i] = 0; 3723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurVolume[i] = -1.0; 3724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mMuteCount[i] = 0; 3725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStopTime[i] = 0; 3726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_STRATEGIES; i++) { 3728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStrategyMutedByDevice[i] = false; 3729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile != NULL) { 3731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mSamplingRate = profile->mSamplingRates[0]; 3732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mFormat = profile->mFormats[0]; 3733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mChannelMask = profile->mChannelMasks[0]; 3734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mFlags = profile->mFlags; 3735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3738e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::device() const 3739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 3741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 3742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mDevice; 3744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3747e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::AudioOutputDescriptor::latency() 3748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 3750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 3751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mLatency; 3753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3756e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith( 3757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const AudioOutputDescriptor *outputDesc) 3758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 3760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 3761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isDuplicated()){ 3762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2); 3763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mProfile->mModule == outputDesc->mProfile->mModule); 3765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3768e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 37693b73df74357b33869b39a1d69427673c780bd805Eric Laurent int delta) 3770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // forward usage count change to attached outputs 3772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 3773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput1->changeRefCount(stream, delta); 3774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput2->changeRefCount(stream, delta); 3775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((delta + (int)mRefCount[stream]) < 0) { 37773b73df74357b33869b39a1d69427673c780bd805Eric Laurent ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", 37783b73df74357b33869b39a1d69427673c780bd805Eric Laurent delta, stream, mRefCount[stream]); 3779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[stream] = 0; 3780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 3781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[stream] += delta; 3783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 3784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3786e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::supportedDevices() 3787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 3789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 3790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 37913a4311c68348f728558e87b5db67d47605783890Eric Laurent return mProfile->mSupportedDevices.types() ; 3792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3795e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isActive(uint32_t inPastMs) const 3796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return isStrategyActive(NUM_STRATEGIES, inPastMs); 3798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3800e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy, 3801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t inPastMs, 3802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime) const 3803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((sysTime == 0) && (inPastMs != 0)) { 3805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime = systemTime(); 3806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 38073b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 38083b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (((getStrategy((audio_stream_type_t)i) == strategy) || 3809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (NUM_STRATEGIES == strategy)) && 38103b73df74357b33869b39a1d69427673c780bd805Eric Laurent isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) { 3811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3817e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, 3818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t inPastMs, 3819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime) const 3820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mRefCount[stream] != 0) { 3822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (inPastMs == 0) { 3825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (sysTime == 0) { 3828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime = systemTime(); 3829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 3831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 38361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::toAudioPortConfig( 38371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_port_config *config) const 38381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 38391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->id = mId; 38401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->role = AUDIO_PORT_ROLE_SOURCE; 38411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->type = AUDIO_PORT_TYPE_MIX; 38421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->sample_rate = mSamplingRate; 38431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->channel_mask = mChannelMask; 38441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->format = mFormat; 38451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->gain.index = -1; 38461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 38471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AUDIO_PORT_CONFIG_FORMAT; 38481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->ext.mix.hw_module = mProfile->mModule->mHandle; 38491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->ext.mix.handle = mIoHandle; 38501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 38511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 38521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 38531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::toAudioPort( 38541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_port *port) const 38551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 38561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mProfile->toAudioPort(port); 38571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 38581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.handle = mIoHandle; 38591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.latency_class = 38601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL; 38611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 3862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3863e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd) 3864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 3866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 3867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 3868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 3870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 3872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 3874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 3876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 3878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Devices %08x\n", device()); 3880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 3882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 38833b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 38843b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", 38853b73df74357b33869b39a1d69427673c780bd805Eric Laurent i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 3886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 3889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 3891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioInputDescriptor class implementation 3894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 38951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile) 38961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent : mId(0), mIoHandle(0), mSamplingRate(0), 38971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(0), 38981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mRefCount(0), 38993b73df74357b33869b39a1d69427673c780bd805Eric Laurent mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile) 3900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 39013a4311c68348f728558e87b5db67d47605783890Eric Laurent if (profile != NULL) { 39023a4311c68348f728558e87b5db67d47605783890Eric Laurent mSamplingRate = profile->mSamplingRates[0]; 39033a4311c68348f728558e87b5db67d47605783890Eric Laurent mFormat = profile->mFormats[0]; 39043a4311c68348f728558e87b5db67d47605783890Eric Laurent mChannelMask = profile->mChannelMasks[0]; 39053a4311c68348f728558e87b5db67d47605783890Eric Laurent } 3906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 39081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioInputDescriptor::toAudioPortConfig( 39091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_port_config *config) const 39101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 39111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->id = mId; 39121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->role = AUDIO_PORT_ROLE_SINK; 39131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->type = AUDIO_PORT_TYPE_MIX; 39141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->sample_rate = mSamplingRate; 39151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->channel_mask = mChannelMask; 39161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->format = mFormat; 39171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->gain.index = -1; 39181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 39191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AUDIO_PORT_CONFIG_FORMAT; 39201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->ext.mix.hw_module = mProfile->mModule->mHandle; 39211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->ext.mix.handle = mIoHandle; 39221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->ext.mix.usecase.source = (mInputSource == AUDIO_SOURCE_HOTWORD) ? 39231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AUDIO_SOURCE_VOICE_RECOGNITION : mInputSource; 39241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 39251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 39261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioInputDescriptor::toAudioPort( 39271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_port *port) const 39281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 39291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mProfile->toAudioPort(port); 39301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 39311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.handle = mIoHandle; 39321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL; 39331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 39341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 3935e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioInputDescriptor::dump(int fd) 3936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 3938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 3939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 3940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 3942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Format: %d\n", mFormat); 3944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 3946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 3948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 3950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 3952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 3954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- StreamDescriptor class implementation 3957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3958e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::StreamDescriptor::StreamDescriptor() 3959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 3960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 3962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3964e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::StreamDescriptor::getVolumeIndex(audio_devices_t device) 3965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3966e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent device = AudioPolicyManager::getDeviceForVolume(device); 3967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 3968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 3969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 3970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mIndexCur.valueFor(device); 3972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3974e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::StreamDescriptor::dump(int fd) 3975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 3977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 3978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 3979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 3981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 3982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 3984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 3985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.keyAt(i), 3986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.valueAt(i)); 3987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 3988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append("\n"); 3990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 3992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- EffectDescriptor class implementation 3995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3996e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::EffectDescriptor::dump(int fd) 3997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 3999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 4000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 4001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 4003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 4005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Session: %d\n", mSession); 4007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 4009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 4011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 4013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 40171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- HwModule class implementation 4018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4019e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::HwModule(const char *name) 4020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0) 4021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4024e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::~HwModule() 4025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 40273a4311c68348f728558e87b5db67d47605783890Eric Laurent mOutputProfiles[i]->mSupportedDevices.clear(); 4028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 40303a4311c68348f728558e87b5db67d47605783890Eric Laurent mInputProfiles[i]->mSupportedDevices.clear(); 4031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free((void *)mName); 4033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4035e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::HwModule::dump(int fd) 4036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 4038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 4039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 4040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - name: %s\n", mName); 4042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 4044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 4046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mOutputProfiles.size()) { 4047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, " - outputs:\n", strlen(" - outputs:\n")); 4048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 4049d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " output %zu:\n", i); 4050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 4051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputProfiles[i]->dump(fd); 4052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mInputProfiles.size()) { 4055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, " - inputs:\n", strlen(" - inputs:\n")); 4056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 4057d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " input %zu:\n", i); 4058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 4059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputProfiles[i]->dump(fd); 4060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 40641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- AudioPort class implementation 40651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 40661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const 40671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 40681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->role = mRole; 40691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->type = mType; 40701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent unsigned int i; 40711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) { 40721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->sample_rates[i] = mSamplingRates[i]; 40731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 40741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_sample_rates = i; 40751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) { 40761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->channel_masks[i] = mChannelMasks[i]; 40771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 40781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_channel_masks = i; 40791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) { 40801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->formats[i] = mFormats[i]; 40811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 40821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_formats = i; 40831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_gains = 0; 40841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 40851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 40861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 40871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadSamplingRates(char *name) 40881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 40891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent char *str = strtok(name, "|"); 40901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 40911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling 40921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // rates should be read from the output stream after it is opened for the first time 40931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 40941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mSamplingRates.add(0); 40951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 40961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 40971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 40981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 40991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent uint32_t rate = atoi(str); 41001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (rate != 0) { 41011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadSamplingRates() adding rate %d", rate); 41021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mSamplingRates.add(rate); 41031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 41041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 41051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 41061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 41071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 41081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadFormats(char *name) 41101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 41111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent char *str = strtok(name, "|"); 41121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mFormats indicates the supported formats 41141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // should be read from the output stream after it is opened for the first time 41151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 41161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFormats.add(AUDIO_FORMAT_DEFAULT); 41171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 41181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 41191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 41211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable, 41221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 41231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 41241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (format != AUDIO_FORMAT_DEFAULT) { 41251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFormats.add(format); 41261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 41271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 41281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 41291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 41301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 41311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadInChannels(char *name) 41331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 41341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const char *str = strtok(name, "|"); 41351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadInChannels() %s", name); 41371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 41391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(0); 41401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 41411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 41421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 41441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_channel_mask_t channelMask = 41451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 41461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 41471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 41481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (channelMask != 0) { 41491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadInChannels() adding channelMask %04x", channelMask); 41501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(channelMask); 41511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 41521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 41531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 41541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 41551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 41561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadOutChannels(char *name) 41581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 41591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const char *str = strtok(name, "|"); 41601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadOutChannels() %s", name); 41621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mChannelMasks indicates the supported channel 41641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // masks should be read from the output stream after it is opened for the first time 41651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 41661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(0); 41671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 41681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 41691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 41711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_channel_mask_t channelMask = 41721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 41731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 41741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 41751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (channelMask != 0) { 41761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(channelMask); 41771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 41781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 41791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 41801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 41811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 41821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- IOProfile class implementation 41841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 41851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::IOProfile::IOProfile(audio_port_role_t role, HwModule *module) 41861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent : AudioPort(AUDIO_PORT_TYPE_MIX, role, module), mFlags((audio_output_flags_t)0) 4187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4190e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile::~IOProfile() 4191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// checks if the IO profile is compatible with specified parameters. 4195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Sampling rate, format and channel mask must be specified in order to 4196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// get a valid a match 4197e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device, 4198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 4199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 4200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 4201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_output_flags_t flags) const 4202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (samplingRate == 0 || !audio_is_valid_format(format) || channelMask == 0) { 4204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 42073a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((mSupportedDevices.types() & device) != device) { 4208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((mFlags & flags) != flags) { 4211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent size_t i; 4214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (i = 0; i < mSamplingRates.size(); i++) 4215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 4216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mSamplingRates[i] == samplingRate) { 4217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (i == mSamplingRates.size()) { 4221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (i = 0; i < mFormats.size(); i++) 4224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 4225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mFormats[i] == format) { 4226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (i == mFormats.size()) { 4230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (i = 0; i < mChannelMasks.size(); i++) 4233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 4234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mChannelMasks[i] == channelMask) { 4235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (i == mChannelMasks.size()) { 4239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 4242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4244e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::IOProfile::dump(int fd) 4245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 4247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 4248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 4249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - sampling rates: "); 4251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 4253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%d", mSamplingRates[i]); 4254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(i == (mSamplingRates.size() - 1) ? "\n" : ", "); 4256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - channel masks: "); 4259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 4261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]); 4262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(i == (mChannelMasks.size() - 1) ? "\n" : ", "); 4264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - formats: "); 4267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 4269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "0x%08x", mFormats[i]); 4270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(i == (mFormats.size() - 1) ? "\n" : ", "); 4272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 42743a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, " - devices:\n"); 4275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 42763a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, result.string(), result.size()); 42773a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceDescriptor::dumpHeader(fd, 6); 42783a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mSupportedDevices.size(); i++) { 42793a4311c68348f728558e87b5db67d47605783890Eric Laurent mSupportedDevices[i]->dump(fd, 6); 42803a4311c68348f728558e87b5db67d47605783890Eric Laurent } 42813a4311c68348f728558e87b5db67d47605783890Eric Laurent 4282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - flags: 0x%04x\n", mFlags); 4283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 4286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4288d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::IOProfile::log() 4289d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 4290d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent const size_t SIZE = 256; 4291d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char buffer[SIZE]; 4292d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 result; 4293d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 4294d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - sampling rates: "); 4295d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 4296d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" %d", mSamplingRates[i]); 4297d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 4298d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 4299d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - channel masks: "); 4300d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 4301d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" 0x%04x", mChannelMasks[i]); 4302d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 4303d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 4304d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - formats: "); 4305d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 4306d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" 0x%08x", mFormats[i]); 4307d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 4308d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 4309d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - devices: 0x%04x\n", mSupportedDevices.types()); 4310d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - flags: 0x%04x\n", mFlags); 4311d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 4312d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 4313d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 43143a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- DeviceDescriptor implementation 4315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43163a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const 43173a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 43183a4311c68348f728558e87b5db67d47605783890Eric Laurent // Devices are considered equal if they: 43193a4311c68348f728558e87b5db67d47605783890Eric Laurent // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE) 43203a4311c68348f728558e87b5db67d47605783890Eric Laurent // - have the same address or one device does not specify the address 43213a4311c68348f728558e87b5db67d47605783890Eric Laurent // - have the same channel mask or one device does not specify the channel mask 43221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return (mDeviceType == other->mDeviceType) && 43233a4311c68348f728558e87b5db67d47605783890Eric Laurent (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) && 43242f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent (mChannelMask == 0 || other->mChannelMask == 0 || 43253a4311c68348f728558e87b5db67d47605783890Eric Laurent mChannelMask == other->mChannelMask); 43263a4311c68348f728558e87b5db67d47605783890Eric Laurent} 4327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43283a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::refreshTypes() 43293a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 43301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDeviceTypes = AUDIO_DEVICE_NONE; 43313a4311c68348f728558e87b5db67d47605783890Eric Laurent for(size_t i = 0; i < size(); i++) { 43321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDeviceTypes |= itemAt(i)->mDeviceType; 43333a4311c68348f728558e87b5db67d47605783890Eric Laurent } 43341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes); 43353a4311c68348f728558e87b5db67d47605783890Eric Laurent} 4336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43373a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const 43383a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 43393a4311c68348f728558e87b5db67d47605783890Eric Laurent for(size_t i = 0; i < size(); i++) { 43403a4311c68348f728558e87b5db67d47605783890Eric Laurent if (item->equals(itemAt(i))) { 43413a4311c68348f728558e87b5db67d47605783890Eric Laurent return i; 43423a4311c68348f728558e87b5db67d47605783890Eric Laurent } 43433a4311c68348f728558e87b5db67d47605783890Eric Laurent } 43443a4311c68348f728558e87b5db67d47605783890Eric Laurent return -1; 43453a4311c68348f728558e87b5db67d47605783890Eric Laurent} 4346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43473a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::add(const sp<DeviceDescriptor>& item) 43483a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 43493a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t ret = indexOf(item); 4350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43513a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret < 0) { 43523a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = SortedVector::add(item); 43533a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret >= 0) { 43543a4311c68348f728558e87b5db67d47605783890Eric Laurent refreshTypes(); 43553a4311c68348f728558e87b5db67d47605783890Eric Laurent } 43563a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 43571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("DeviceVector::add device %08x already in", item->mDeviceType); 43583a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = -1; 43593a4311c68348f728558e87b5db67d47605783890Eric Laurent } 43603a4311c68348f728558e87b5db67d47605783890Eric Laurent return ret; 43613a4311c68348f728558e87b5db67d47605783890Eric Laurent} 4362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43633a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::remove(const sp<DeviceDescriptor>& item) 43643a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 43653a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t i; 43663a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t ret = indexOf(item); 4367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43683a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret < 0) { 43691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("DeviceVector::remove device %08x not in", item->mDeviceType); 43703a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 43713a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = SortedVector::removeAt(ret); 43723a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret >= 0) { 43733a4311c68348f728558e87b5db67d47605783890Eric Laurent refreshTypes(); 43743a4311c68348f728558e87b5db67d47605783890Eric Laurent } 43753a4311c68348f728558e87b5db67d47605783890Eric Laurent } 43763a4311c68348f728558e87b5db67d47605783890Eric Laurent return ret; 43773a4311c68348f728558e87b5db67d47605783890Eric Laurent} 4378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43793a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::loadDevicesFromType(audio_devices_t types) 4380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 43813a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceVector deviceList; 43823a4311c68348f728558e87b5db67d47605783890Eric Laurent 43833a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t role_bit = AUDIO_DEVICE_BIT_IN & types; 43843a4311c68348f728558e87b5db67d47605783890Eric Laurent types &= ~role_bit; 43853a4311c68348f728558e87b5db67d47605783890Eric Laurent 43863a4311c68348f728558e87b5db67d47605783890Eric Laurent while (types) { 43873a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t i = 31 - __builtin_clz(types); 43883a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t type = 1 << i; 43893a4311c68348f728558e87b5db67d47605783890Eric Laurent types &= ~type; 43903a4311c68348f728558e87b5db67d47605783890Eric Laurent add(new DeviceDescriptor(type | role_bit)); 4391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDevice( 43951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type, String8 address) const 43961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 43971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<DeviceDescriptor> device; 43981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; i < size(); i++) { 43991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (itemAt(i)->mDeviceType == type) { 44001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = itemAt(i); 44011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (itemAt(i)->mAddress = address) { 44021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent break; 44031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 44041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 44051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 44061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("DeviceVector::getDevice() for type %d address %s found %p", 44071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent type, address.string(), device.get()); 44081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return device; 44091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 44101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 44111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromType( 44121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type) const 44131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 44141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent DeviceVector devices; 44151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) { 44161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (itemAt(i)->mDeviceType & type & ~AUDIO_DEVICE_BIT_IN) { 44171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent devices.add(itemAt(i)); 44181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent type &= ~itemAt(i)->mDeviceType; 44191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("DeviceVector::getDevicesFromType() for type %x found %p", 44201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent itemAt(i)->mDeviceType, itemAt(i).get()); 44211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 44221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 44231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return devices; 44241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 44251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 44261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::DeviceDescriptor::toAudioPortConfig(struct audio_port_config *config) const 44271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 44281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->id = mId; 44291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->role = audio_is_output_device(mDeviceType) ? 44301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE; 44311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->type = AUDIO_PORT_TYPE_DEVICE; 44321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->sample_rate = 0; 44331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->channel_mask = mChannelMask; 44341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->format = AUDIO_FORMAT_DEFAULT; 44351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK; 44361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->gain.index = -1; 44371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent config->ext.device.type = mDeviceType; 44381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent strncpy(config->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN); 44391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 44401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 44411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::DeviceDescriptor::toAudioPort(struct audio_port *port) const 44421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 44431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AudioPort::toAudioPort(port); 44441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 44451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.device.type = mDeviceType; 44461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN); 44471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 44481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 44493a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceDescriptor::dumpHeader(int fd, int spaces) 4450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 44513a4311c68348f728558e87b5db67d47605783890Eric Laurent const size_t SIZE = 256; 44523a4311c68348f728558e87b5db67d47605783890Eric Laurent char buffer[SIZE]; 44533a4311c68348f728558e87b5db67d47605783890Eric Laurent 44543a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, "%*s%-48s %-2s %-8s %-32s \n", 44553a4311c68348f728558e87b5db67d47605783890Eric Laurent spaces, "", "Type", "ID", "Cnl Mask", "Address"); 44563a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, buffer, strlen(buffer)); 4457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 44593a4311c68348f728558e87b5db67d47605783890Eric Laurentstatus_t AudioPolicyManager::DeviceDescriptor::dump(int fd, int spaces) const 44603a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 44613a4311c68348f728558e87b5db67d47605783890Eric Laurent const size_t SIZE = 256; 44623a4311c68348f728558e87b5db67d47605783890Eric Laurent char buffer[SIZE]; 44633a4311c68348f728558e87b5db67d47605783890Eric Laurent 44643a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, "%*s%-48s %2d %08x %-32s \n", 44653a4311c68348f728558e87b5db67d47605783890Eric Laurent spaces, "", 44663a4311c68348f728558e87b5db67d47605783890Eric Laurent enumToString(sDeviceNameToEnumTable, 44673a4311c68348f728558e87b5db67d47605783890Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 44681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDeviceType), 44693a4311c68348f728558e87b5db67d47605783890Eric Laurent mId, mChannelMask, mAddress.string()); 44703a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, buffer, strlen(buffer)); 44713a4311c68348f728558e87b5db67d47605783890Eric Laurent 44723a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_ERROR; 44733a4311c68348f728558e87b5db67d47605783890Eric Laurent} 44743a4311c68348f728558e87b5db67d47605783890Eric Laurent 44753a4311c68348f728558e87b5db67d47605783890Eric Laurent 44763a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- audio_policy.conf file parsing 44773a4311c68348f728558e87b5db67d47605783890Eric Laurent 4478e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_output_flags_t AudioPolicyManager::parseFlagNames(char *name) 4479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t flag = 0; 4481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // it is OK to cast name to non const here as we are not going to use it after 4483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // strtok() modifies it 4484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *flagName = strtok(name, "|"); 4485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (flagName != NULL) { 4486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strlen(flagName) != 0) { 4487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flag |= stringToEnum(sFlagNameToEnumTable, 4488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sFlagNameToEnumTable), 4489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flagName); 4490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flagName = strtok(NULL, "|"); 4492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //force direct flag if offload flag is set: offloading implies a direct output stream 4494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and all common behaviors are driven by checking only the direct flag 4495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this should normally be set appropriately in the policy configuration file 4496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 4497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flag |= AUDIO_OUTPUT_FLAG_DIRECT; 4498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_output_flags_t)flag; 4501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4503e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::parseDeviceNames(char *name) 4504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = 0; 4506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *devName = strtok(name, "|"); 4508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (devName != NULL) { 4509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strlen(devName) != 0) { 4510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device |= stringToEnum(sDeviceNameToEnumTable, 4511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 4512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devName); 45133a4311c68348f728558e87b5db67d47605783890Eric Laurent } 4514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devName = strtok(NULL, "|"); 45153a4311c68348f728558e87b5db67d47605783890Eric Laurent } 4516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 4517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4519e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadInput(cnode *root, HwModule *module) 4520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = root->first_child; 4522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 45231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = new IOProfile(AUDIO_PORT_ROLE_SINK, module); 4524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 45271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadSamplingRates((char *)node->value); 4528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 45291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadFormats((char *)node->value); 4530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 45311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadInChannels((char *)node->value); 4532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 45333a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.loadDevicesFromType(parseDeviceNames((char *)node->value)); 4534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 45373a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW_IF(profile->mSupportedDevices.isEmpty(), 4538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadInput() invalid supported devices"); 4539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 4540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadInput() invalid supported channel masks"); 4541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 4542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadInput() invalid supported sampling rates"); 4543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 4544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadInput() invalid supported formats"); 45453a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!profile->mSupportedDevices.isEmpty() && 4546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mChannelMasks.size() != 0) && 4547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mSamplingRates.size() != 0) && 4548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mFormats.size() != 0)) { 4549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 45503a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadInput() adding input Supported Devices %04x", 45513a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.types()); 4552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mInputProfiles.add(profile); 4554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 4557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4560e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadOutput(cnode *root, HwModule *module) 4561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = root->first_child; 4563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 45641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = new IOProfile(AUDIO_PORT_ROLE_SOURCE, module); 4565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 45681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadSamplingRates((char *)node->value); 4569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 45701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadFormats((char *)node->value); 4571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 45721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadOutChannels((char *)node->value); 4573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 45743a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.loadDevicesFromType(parseDeviceNames((char *)node->value)); 4575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(node->name, FLAGS_TAG) == 0) { 4576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFlags = parseFlagNames((char *)node->value); 4577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 45803a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW_IF(profile->mSupportedDevices.isEmpty(), 4581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadOutput() invalid supported devices"); 4582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 4583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadOutput() invalid supported channel masks"); 4584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 4585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadOutput() invalid supported sampling rates"); 4586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF(profile->mFormats.size() == 0, 4587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "loadOutput() invalid supported formats"); 45883a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!profile->mSupportedDevices.isEmpty() && 4589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mChannelMasks.size() != 0) && 4590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mSamplingRates.size() != 0) && 4591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (profile->mFormats.size() != 0)) { 4592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 45933a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x", 45943a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.types(), profile->mFlags); 4595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mOutputProfiles.add(profile); 4597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 4600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4603e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModule(cnode *root) 4604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, OUTPUTS_TAG); 4606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t status = NAME_NOT_FOUND; 4607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent HwModule *module = new HwModule(root->name); 4609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node != NULL) { 4611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 4612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModule() loading output %s", node->name); 4614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t tmpStatus = loadOutput(node, module); 4615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 4616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = tmpStatus; 4617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = config_find(root, INPUTS_TAG); 4622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node != NULL) { 4623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 4624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModule() loading input %s", node->name); 4626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t tmpStatus = loadInput(node, module); 4627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 4628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = tmpStatus; 4629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NO_ERROR) { 4634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules.add(module); 4635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delete module; 4637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4640e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModules(cnode *root) 4641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); 4643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node == NULL) { 4644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 4648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModules() loading module %s", node->name); 4650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadHwModule(node); 4651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4655e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadGlobalConfig(cnode *root) 4656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, GLOBAL_CONFIG_TAG); 4658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node == NULL) { 4659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 4662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 4663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { 46643a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.loadDevicesFromType(parseDeviceNames((char *)node->value)); 46653a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadGlobalConfig() Attached Output Devices %08x", 46663a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.types()); 4667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { 46683a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t device = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable, 4669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 4670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (char *)node->value); 46713a4311c68348f728558e87b5db67d47605783890Eric Laurent if (device != AUDIO_DEVICE_NONE) { 46723a4311c68348f728558e87b5db67d47605783890Eric Laurent mDefaultOutputDevice = new DeviceDescriptor(device); 46733a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 46743a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("loadGlobalConfig() default device not specified"); 46753a4311c68348f728558e87b5db67d47605783890Eric Laurent } 46761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", mDefaultOutputDevice->mDeviceType); 4677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { 46783a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.loadDevicesFromType(parseDeviceNames((char *)node->value)); 46793a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadGlobalConfig() Available InputDevices %08x", mAvailableInputDevices.types()); 4680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) { 4681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mSpeakerDrcEnabled = stringToBool((char *)node->value); 4682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled); 4683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 4685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4688e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadAudioPolicyConfig(const char *path) 4689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *root; 4691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *data; 4692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent data = (char *)load_file(path, NULL); 4694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (data == NULL) { 4695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return -ENODEV; 4696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent root = config_node("", ""); 4698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent config_load(root, data); 4699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadGlobalConfig(root); 4701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadHwModules(root); 4702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent config_free(root); 4704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free(root); 4705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free(data); 4706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGI("loadAudioPolicyConfig() loaded %s\n", path); 4708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4712e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::defaultAudioPolicyConfig(void) 4713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent HwModule *module; 47151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile; 47163a4311c68348f728558e87b5db67d47605783890Eric Laurent sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC); 47173a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.add(mDefaultOutputDevice); 47183a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.add(defaultInputDevice); 4719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module = new HwModule("primary"); 4721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 47221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile = new IOProfile(AUDIO_PORT_ROLE_SOURCE, module); 4723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(44100); 4724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 4725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO); 47263a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.add(mDefaultOutputDevice); 4727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY; 4728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mOutputProfiles.add(profile); 4729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 47301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile = new IOProfile(AUDIO_PORT_ROLE_SINK, module); 4731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(8000); 4732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 4733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO); 47343a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.add(defaultInputDevice); 4735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mInputProfiles.add(profile); 4736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules.add(module); 4738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; // namespace android 4741