AudioPolicyManager.cpp revision a204994e7dd7dab931297176c66b5d3b82e2c90b
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> 413b73df74357b33869b39a1d69427673c780bd805Eric Laurent#include <media/AudioParameter.h> 42d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include "AudioPolicyManager.h" 431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent#include "audio_policy_conf.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), 10341b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP), 1047999a2236cb641dc1d7bf7bd8d2499d40d0a806dTerry Heo STRING_TO_ENUM(AUDIO_DEVICE_IN_LOOPBACK), 1053a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1063a4311c68348f728558e87b5db67d47605783890Eric Laurent 1073a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFlagNameToEnumTable[] = { 1083a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT), 1093a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), 1103a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), 1113a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), 1123a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD), 1133a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING), 1143a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1153a4311c68348f728558e87b5db67d47605783890Eric Laurent 1163a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFormatNameToEnumTable[] = { 1173a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT), 1183a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT), 1193a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT), 1203a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT), 1213a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT), 1223a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED), 1233a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_MP3), 1243a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AAC), 1252829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_MAIN), 1262829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_LC), 1272829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_SSR), 1282829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_LTP), 1292829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V1), 1302829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_SCALABLE), 1312829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_ERLC), 1322829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_LD), 1332829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V2), 1342829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_ELD), 1353a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_VORBIS), 136ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V1), 137ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V2), 138ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_OPUS), 139ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AC3), 140ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_E_AC3), 1413a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1423a4311c68348f728558e87b5db67d47605783890Eric Laurent 1433a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sOutChannelsNameToEnumTable[] = { 1443a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO), 1453a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 1463a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 1473a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 1483a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1493a4311c68348f728558e87b5db67d47605783890Eric Laurent 1503a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sInChannelsNameToEnumTable[] = { 1513a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), 1523a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), 1533a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK), 1543a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1553a4311c68348f728558e87b5db67d47605783890Eric Laurent 1561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentconst StringToEnum sGainModeNameToEnumTable[] = { 1571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent STRING_TO_ENUM(AUDIO_GAIN_MODE_JOINT), 1581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent STRING_TO_ENUM(AUDIO_GAIN_MODE_CHANNELS), 1591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent STRING_TO_ENUM(AUDIO_GAIN_MODE_RAMP), 1601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent}; 1611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 1623a4311c68348f728558e87b5db67d47605783890Eric Laurent 1633a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::stringToEnum(const struct StringToEnum *table, 1643a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t size, 1653a4311c68348f728558e87b5db67d47605783890Eric Laurent const char *name) 1663a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1673a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < size; i++) { 1683a4311c68348f728558e87b5db67d47605783890Eric Laurent if (strcmp(table[i].name, name) == 0) { 1693a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("stringToEnum() found %s", table[i].name); 1703a4311c68348f728558e87b5db67d47605783890Eric Laurent return table[i].value; 1713a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1723a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1733a4311c68348f728558e87b5db67d47605783890Eric Laurent return 0; 1743a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1753a4311c68348f728558e87b5db67d47605783890Eric Laurent 1763a4311c68348f728558e87b5db67d47605783890Eric Laurentconst char *AudioPolicyManager::enumToString(const struct StringToEnum *table, 1773a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t size, 1783a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t value) 1793a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1803a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < size; i++) { 1813a4311c68348f728558e87b5db67d47605783890Eric Laurent if (table[i].value == value) { 1823a4311c68348f728558e87b5db67d47605783890Eric Laurent return table[i].name; 1833a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1843a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1853a4311c68348f728558e87b5db67d47605783890Eric Laurent return ""; 1863a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1873a4311c68348f728558e87b5db67d47605783890Eric Laurent 1883a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::stringToBool(const char *value) 1893a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1903a4311c68348f728558e87b5db67d47605783890Eric Laurent return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0)); 1913a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1923a4311c68348f728558e87b5db67d47605783890Eric Laurent 1933a4311c68348f728558e87b5db67d47605783890Eric Laurent 1943a4311c68348f728558e87b5db67d47605783890Eric Laurent// ---------------------------------------------------------------------------- 195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AudioPolicyInterface implementation 196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 199e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, 2003b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state, 201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *device_address) 202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2033a4311c68348f728558e87b5db67d47605783890Eric Laurent String8 address = String8(device_address); 204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); 206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // connect/disconnect only 1 device at a time 208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; 209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output devices 211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_output_device(device)) { 212d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector <audio_io_handle_t> outputs; 213d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); 2151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent devDesc->mAddress = address; 2163a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = mAvailableOutputDevices.indexOf(devDesc); 2173a4311c68348f728558e87b5db67d47605783890Eric Laurent 218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // save a copy of the opened output descriptors before any output is opened or closed 219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() 220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (state) 222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output device connection 2243b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: 2253a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device already connected: %x", device); 227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setDeviceConnectionState() connecting device %x", device); 230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2313a4311c68348f728558e87b5db67d47605783890Eric Laurent if (checkOutputsForDevice(device, state, outputs, address) != NO_ERROR) { 232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // outputs should never be empty here 2356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():" 2366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent "checkOutputsForDevice() returned no outputs but status OK"); 237d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs", 238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.size()); 239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // register new device as available 2403a4311c68348f728558e87b5db67d47605783890Eric Laurent index = mAvailableOutputDevices.add(devDesc); 2413a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 2423a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices[index]->mId = nextUniqueId(); 2431f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module = getModuleForDevice(device); 2446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOG_ASSERT(module != NULL, "setDeviceConnectionState():" 2456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent "could not find HW module for device %08x", device); 2466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableOutputDevices[index]->mModule = module; 2473a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 2483a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_MEMORY; 249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output device disconnection 2533b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: { 2543a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index < 0) { 255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device not connected: %x", device); 256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setDeviceConnectionState() disconnecting device %x", device); 260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // remove device from available output devices 2613a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.remove(devDesc); 2623a4311c68348f728558e87b5db67d47605783890Eric Laurent 2633a4311c68348f728558e87b5db67d47605783890Eric Laurent checkOutputsForDevice(device, state, outputs, address); 264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // not currently handling multiple simultaneous submixes: ignoring remote submix 265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // case and address 266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } break; 267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("setDeviceConnectionState() invalid state: %x", state); 270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2733a4311c68348f728558e87b5db67d47605783890Eric Laurent // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP 2743a4311c68348f728558e87b5db67d47605783890Eric Laurent // output is suspended before any tracks are moved to it 275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // outputs must be closed after checkOutputForAllStrategies() is executed 278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputs.isEmpty()) { 279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 2801f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]); 281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // close unused outputs after device disconnection or direct outputs that have been 282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // opened by checkOutputsForDevice() to query dynamic parameters 2833b73df74357b33869b39a1d69427673c780bd805Eric Laurent if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) || 284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) && 285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (desc->mDirectOpenCount == 0))) { 286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent closeOutput(outputs[i]); 287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2893a4311c68348f728558e87b5db67d47605783890Eric Laurent // check again after closing A2DP output to reset mA2dpSuspended if needed 2903a4311c68348f728558e87b5db67d47605783890Eric Laurent checkA2dpSuspend(); 291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not force device change on duplicated output because if device is 0, it will 296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // also force a device 0 for the two outputs it is duplicated to which may override 297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // a valid device selection on those outputs. 298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(mOutputs.keyAt(i), 2991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent getNewOutputDevice(mOutputs.keyAt(i), true /*fromCache*/), 300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent !mOutputs.valueAt(i)->isDuplicated(), 301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 0); 302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30472aa32f7dbbfb658097930b57659d8e50f24a953Eric Laurent mpClientInterface->onAudioPortListUpdate(); 305b71e58b64cd4992355cf6afaf3f3530f723bc72cEric Laurent return NO_ERROR; 306d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end if is output device 307d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input devices 309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_input_device(device)) { 310d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector <audio_io_handle_t> inputs; 311d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3121afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); 3131afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent devDesc->mAddress = address; 3143a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = mAvailableInputDevices.indexOf(devDesc); 315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (state) 316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input device connection 3183b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: { 3193a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device already connected: %d", device); 321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3231f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module = getModuleForDevice(device); 3246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (module == NULL) { 3256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("setDeviceConnectionState(): could not find HW module for device %08x", 3266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent device); 3276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 3286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 329d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (checkInputsForDevice(device, state, inputs, address) != NO_ERROR) { 330d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return INVALID_OPERATION; 331d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 332d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3333a4311c68348f728558e87b5db67d47605783890Eric Laurent index = mAvailableInputDevices.add(devDesc); 3343a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 3353a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices[index]->mId = nextUniqueId(); 3366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices[index]->mModule = module; 3373a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 3383a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_MEMORY; 3393a4311c68348f728558e87b5db67d47605783890Eric Laurent } 340d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } break; 341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input device disconnection 3433b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: { 3443a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index < 0) { 345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device not connected: %d", device); 346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 348d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent checkInputsForDevice(device, state, inputs, address); 3493a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.remove(devDesc); 350d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } break; 351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("setDeviceConnectionState() invalid state: %x", state); 354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 357d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent closeAllInputs(); 358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 359b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 361d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end if is input device 362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() invalid device: %x", device); 364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 367e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device, 368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *device_address) 369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3703b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 address = String8(device_address); 3721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); 3731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent devDesc->mAddress = String8(device_address); 3743a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index; 3753a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceVector *deviceVector; 3763a4311c68348f728558e87b5db67d47605783890Eric Laurent 377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_output_device(device)) { 3783a4311c68348f728558e87b5db67d47605783890Eric Laurent deviceVector = &mAvailableOutputDevices; 379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (audio_is_input_device(device)) { 3803a4311c68348f728558e87b5db67d47605783890Eric Laurent deviceVector = &mAvailableInputDevices; 3813a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 3823a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("getDeviceConnectionState() invalid device type %08x", device); 3833a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3863a4311c68348f728558e87b5db67d47605783890Eric Laurent index = deviceVector->indexOf(devDesc); 3873a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 3883a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_AVAILABLE; 3893a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 3903a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 3913a4311c68348f728558e87b5db67d47605783890Eric Laurent } 392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 394e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setPhoneState(audio_mode_t state) 395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() state %d", state); 397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = AUDIO_DEVICE_NONE; 3983b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state < 0 || state >= AUDIO_MODE_CNT) { 399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setPhoneState() invalid state %d", state); 400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (state == mPhoneState ) { 404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setPhoneState() setting same state %d", state); 405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if leaving call state, handle special case of active streams 409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // pertaining to sonification strategy see handleIncallSonification() 410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() in call state management: new state is %d", state); 4123b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 4133b73df74357b33869b39a1d69427673c780bd805Eric Laurent handleIncallSonification((audio_stream_type_t)stream, false, true); 414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // store previous phone state for management of sonification strategy below 418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int oldState = mPhoneState; 419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPhoneState = state; 420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force = false; 421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // are we entering or starting a call 423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isStateInCall(oldState) && isStateInCall(state)) { 424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Entering call in setPhoneState()"); 425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when starting a call 426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j]; 431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isStateInCall(oldState) && !isStateInCall(state)) { 433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Exiting call in setPhoneState()"); 434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when exiting a call 435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[AUDIO_STREAM_DTMF][j]; 440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isStateInCall(state) && (state != oldState)) { 442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when switching between telephony and VoIP 444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check for device and output changes triggered by new phone state 4491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/); 450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4541f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when ending call 457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) { 459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent newDevice = hwOutputDesc->device(); 460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs = 0; 463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(state)) { 464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 4661f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute media and sonification strategies and delay device switch by the largest 468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // latency of any output where either strategy is active. 469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This avoid sending the ring tone or music tail into the earpiece or headset. 470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->isStrategyActive(STRATEGY_MEDIA, 471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime) || 473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->isStrategyActive(STRATEGY_SONIFICATION, 474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime)) && 476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (delayMs < (int)desc->mLatency*2)) { 477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs = desc->mLatency*2; 478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); 480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, 481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); 482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i)); 483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS, 484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/)); 485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // change routing is necessary 489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(mPrimaryOutput, newDevice, force, delayMs); 490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if entering in call state, handle special case of active streams 492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // pertaining to sonification strategy see handleIncallSonification() 493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(state)) { 494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() in call state management: new state is %d", state); 4953b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 4963b73df74357b33869b39a1d69427673c780bd805Eric Laurent handleIncallSonification((audio_stream_type_t)stream, true, true); 497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 5013b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state == AUDIO_MODE_RINGTONE && 5023b73df74357b33869b39a1d69427673c780bd805Eric Laurent isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume = true; 504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume = false; 506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 509e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setForceUse(audio_policy_force_use_t usage, 5103b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_forced_cfg_t config) 511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool forceVolumeReeval = false; 515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(usage) { 5163b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_COMMUNICATION: 5173b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO && 5183b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NONE) { 519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5253b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_MEDIA: 5263b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP && 5273b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 5283b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_ANALOG_DOCK && 5293b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE && 5300c94309d3c6db555b57f2e2e2dc3a0a2676ac6b7Jungshik Jang config != AUDIO_POLICY_FORCE_NO_BT_A2DP) { 531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5363b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_RECORD: 5373b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 5383b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NONE) { 539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5443b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_DOCK: 5453b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK && 5463b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_BT_DESK_DOCK && 5473b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 5483b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_ANALOG_DOCK && 5493b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) { 550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5553b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_SYSTEM: 5563b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_NONE && 5573b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { 558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config); 559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5637b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO: 5647b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang if (config != AUDIO_POLICY_FORCE_NONE && 5657b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) { 5667b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang ALOGW("setForceUse() invalid config %d forHDMI_SYSTEM_AUDIO", config); 5677b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang } 5687b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang mForceUse[usage] = config; 5697b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang break; 570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid usage %d", usage); 572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check for device and output changes triggered by new force usage 576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 5811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t newDevice = getNewOutputDevice(output, true /*fromCache*/); 582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE)); 583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) { 584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent applyStreamVolumes(output, newDevice, 0, true); 585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t activeInput = getActiveInput(); 589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (activeInput != 0) { 5901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setInputDevice(activeInput, getNewInputDevice(activeInput)); 591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 595e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage) 596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mForceUse[usage]; 598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 600e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setSystemProperty(const char* property, const char* value) 601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setSystemProperty() property %s, value %s", property, value); 603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Find a direct output profile compatible with the parameters passed, even if the input flags do 606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// not explicitly request a direct output 6071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::IOProfile> AudioPolicyManager::getProfileForDirectOutput( 608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_output_flags_t flags) 613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { 6191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j]; 6203a4311c68348f728558e87b5db67d47605783890Eric Laurent bool found = false; 621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { 622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, 624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) { 6253a4311c68348f728558e87b5db67d47605783890Eric Laurent found = true; 626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, 630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_OUTPUT_FLAG_DIRECT)) { 6313a4311c68348f728558e87b5db67d47605783890Eric Laurent found = true; 632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6343a4311c68348f728558e87b5db67d47605783890Eric Laurent if (found && (mAvailableOutputDevices.types() & profile->mSupportedDevices.types())) { 6353a4311c68348f728558e87b5db67d47605783890Eric Laurent return profile; 6363a4311c68348f728558e87b5db67d47605783890Eric Laurent } 637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 642e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream, 643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 6463b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_output_flags_t flags, 647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const audio_offload_info_t *offloadInfo) 648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6495bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 6503b73df74357b33869b39a1d69427673c780bd805Eric Laurent routing_strategy strategy = getStrategy(stream); 651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x", 653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, stream, samplingRate, format, channelMask, flags); 654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6555bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return getOutputForDevice(device, stream, samplingRate,format, channelMask, flags, 6565bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi offloadInfo); 6575bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi} 6585bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 6595bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_io_handle_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr, 6605bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi uint32_t samplingRate, 6615bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_format_t format, 6625bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_channel_mask_t channelMask, 6635bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_output_flags_t flags, 6645bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi const audio_offload_info_t *offloadInfo) 6655bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{ 6665bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi if (attr == NULL) { 6675bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi ALOGE("getOutputForAttr() called with NULL audio attributes"); 6685bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return 0; 6695bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 6705bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s", 6715bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi attr->usage, attr->content_type, attr->tags); 6725bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 6735bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // TODO this is where filtering for custom policies (rerouting, dynamic sources) will go 6745bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi routing_strategy strategy = (routing_strategy) getStrategyForAttr(attr); 6755bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 6765bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi ALOGV("getOutputForAttr() device %d, samplingRate %d, format %x, channelMask %x, flags %x", 6775bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi device, samplingRate, format, channelMask, flags); 6785bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 6795bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_stream_type_t stream = streamTypefromAttributesInt(attr); 6805bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return getOutputForDevice(device, stream, samplingRate, format, channelMask, flags, 6815bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi offloadInfo); 6825bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi} 6835bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 6845bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_io_handle_t AudioPolicyManager::getOutputForDevice( 6855bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_devices_t device, 6865bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_stream_type_t stream, 6875bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi uint32_t samplingRate, 6885bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_format_t format, 6895bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_channel_mask_t channelMask, 6905bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_output_flags_t flags, 6915bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi const audio_offload_info_t *offloadInfo) 6925bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{ 6935bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_io_handle_t output = 0; 6945bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi uint32_t latency = 0; 6955bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mCurOutput != 0) { 698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", 699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTestOutputs[mCurOutput] == 0) { 702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() opening test output"); 7031f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL); 704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = mTestDevice; 705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate = mTestSamplingRate; 706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFormat = mTestFormat; 707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mChannelMask = mTestChannels; 708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency = mTestLatencyMs; 7093b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc->mFlags = 7103b73df74357b33869b39a1d69427673c780bd805Eric Laurent (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0); 711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mRefCount[stream] = 0; 712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice, 713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags, 718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo); 719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTestOutputs[mCurOutput]) { 720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"),mCurOutput); 722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(mTestOutputs[mCurOutput], outputDesc); 724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mTestOutputs[mCurOutput]; 727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open a direct output if required by specified parameters 731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //force direct flag if offload flag is set: offloading implies a direct output stream 732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and all common behaviors are driven by checking only the direct flag 733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this should normally be set appropriately in the policy configuration file 734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 7353b73df74357b33869b39a1d69427673c780bd805Eric Laurent flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT); 736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // detects there is an active non offloadable effect. 741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the background. 7441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile; 745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) || 746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent !isNonOffloadableEffectEnabled()) { 747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile = getProfileForDirectOutput(device, 748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, 749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent format, 750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, 751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (audio_output_flags_t)flags); 752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (profile != 0) { 7551f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = NULL; 756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 7581f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && (profile == desc->mProfile)) { 760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc = desc; 761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // reuse direct output if currently open and configured with same parameters 762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((samplingRate == outputDesc->mSamplingRate) && 763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (format == outputDesc->mFormat) && 764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (channelMask == outputDesc->mChannelMask)) { 765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDirectOpenCount++; 766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i)); 767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutputs.keyAt(i); 768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // close direct output if currently open and configured with different parameters 772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc != NULL) { 7731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent closeOutput(outputDesc->mIoHandle); 774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc = new AudioOutputDescriptor(profile); 776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = device; 777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate = samplingRate; 778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFormat = format; 779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mChannelMask = channelMask; 780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency = 0; 781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags); 782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mRefCount[stream] = 0; 783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStopTime[stream] = 0; 784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDirectOpenCount = 1; 785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output = mpClientInterface->openOutput(profile->mModule->mHandle, 786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mDevice, 787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags, 792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo); 793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // only accept an output with the requested parameters 795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == 0 || 796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || 797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (format != AUDIO_FORMAT_DEFAULT && format != outputDesc->mFormat) || 798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { 799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," 800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "format %d %d, channelMask %04x %04x", output, samplingRate, 801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, 802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mChannelMask); 803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output != 0) { 804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t srcOutput = getOutputForEffect(); 809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, outputDesc); 810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dstOutput == output) { 812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput); 813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() returns new direct output %d", output); 816b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ignoring channel mask due to downmix capability in mixer 821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open a non direct output 823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // for non direct outputs, only PCM is supported 825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_linear_pcm(format)) { 826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // get which output is suitable for the specified stream. The actual 827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // routing change will happen when startOutput() will be called 828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs); 829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output = selectOutput(outputs, flags); 831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d," 833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); 834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() returns output %d", output); 836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 840e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs, 8413b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_output_flags_t flags) 842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // select one output among several that provide a path to a particular device or set of 844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // devices (the list was previously build by getOutputsForDevice()). 845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The priority is as follows: 846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: the output with the highest number of requested policy flags 847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: the primary output 848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the first output in the list 849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 0) { 851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 1) { 854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int maxCommonFlags = 0; 858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputFlags = 0; 859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputPrimary = 0; 860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 8621f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); 863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputDesc->isDuplicated()) { 8643b73df74357b33869b39a1d69427673c780bd805Eric Laurent int commonFlags = popcount(outputDesc->mProfile->mFlags & flags); 865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (commonFlags > maxCommonFlags) { 866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputFlags = outputs[i]; 867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent maxCommonFlags = commonFlags; 868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); 869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputPrimary = outputs[i]; 872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputFlags != 0) { 877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputFlags; 878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputPrimary != 0) { 880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputPrimary; 881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 886e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startOutput(audio_io_handle_t output, 8873b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream, 888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session) 889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startOutput() unknown output %d", output); 894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 8971f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); 898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // increment usage count for this stream on the requested output: 900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // NOTE that the usage count is the same for duplicated output and hardware output which is 901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // necessary for a correct control of hardware output routing by startOutput() and stopOutput() 902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->changeRefCount(stream, 1); 903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] == 1) { 9051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); 906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent routing_strategy strategy = getStrategy(stream); 907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool shouldWait = (strategy == STRATEGY_SONIFICATION) || 908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (strategy == STRATEGY_SONIFICATION_RESPECTFUL); 909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t waitMs = 0; 910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force = false; 911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 9121f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc != outputDesc) { 914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force a device change if any other output is managed by the same hw 915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // module and has a current device selection that differs from selected device. 916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // In this case, the audio HAL must receive the new device selection so that it can 917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // change the device currently selected by the other active output. 918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->sharesHwModuleWith(desc) && 919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->device() != newDevice) { 920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // wait for audio on other active outputs to be presented when starting 923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // a notification so that audio focus effect can propagate. 924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t latency = desc->latency(); 925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { 926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent waitMs = latency; 927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); 931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle special case for sonification while in call 933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleIncallSonification(stream, true, false); 935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // apply volume rules for current stream and device if necessary 938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].getVolumeIndex(newDevice), 940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent newDevice); 942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update the outputs if starting an output with a stream that can affect notification 944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // routing 945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleNotificationRoutingForStream(stream); 946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (waitMs > muteWaitMs) { 947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent usleep((waitMs - muteWaitMs) * 2 * 1000); 948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 954e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopOutput(audio_io_handle_t output, 9553b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream, 956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session) 957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopOutput() unknown output %d", output); 962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 9651f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); 966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle special case for sonification while in call 968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleIncallSonification(stream, false, false); 970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] > 0) { 973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // decrement usage count of this stream on the output 974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->changeRefCount(stream, -1); 975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // store time at which the stream was stopped - see isStreamActive() 976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] == 0) { 977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStopTime[stream] = systemTime(); 9781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); 979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // delay the device switch by twice the latency because stopOutput() is executed when 980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the track stop() command is received and at that time the audio track buffer can 981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // still contain data that needs to be drained. The latency only covers the audio HAL 982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and kernel buffers. Also the latency does not always include additional delay in the 983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // audio path (audio DSP, CODEC ...) 984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); 985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force restoring the device selection on other active outputs if it differs from the 987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // one being selected for this output 988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(i); 9901f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (curOutput != output && 992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->isActive() && 993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->sharesHwModuleWith(desc) && 994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (newDevice != desc->device())) { 995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(curOutput, 9961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent getNewOutputDevice(curOutput, false /*fromCache*/), 997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent true, 998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency*2); 999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update the outputs if stopping one with a stream that can affect notification routing 1002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleNotificationRoutingForStream(stream); 1003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopOutput() refcount is already 0 for output %d", output); 1007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1011e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::releaseOutput(audio_io_handle_t output) 1012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseOutput() %d", output); 1014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 1015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseOutput() releasing unknown output %d", output); 1017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int testIndex = testOutputIndex(output); 1022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (testIndex != 0) { 10231f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); 1024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isActive()) { 1025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 1026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(output); 1027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[testIndex] = 0; 1028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 10331f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(index); 10343b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { 1035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->mDirectOpenCount <= 0) { 1036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseOutput() invalid open count %d for output %d", 1037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mDirectOpenCount, output); 1038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (--desc->mDirectOpenCount == 0) { 1041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent closeOutput(output); 1042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // If effects where present on the output, audioflinger moved them to the primary 1043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // output by default: move them back to the appropriate output. 1044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 1045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dstOutput != mPrimaryOutput) { 1046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput); 1047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1048b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 1049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1054e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, 1055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 1056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 1057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 10583b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_in_acoustics_t acoustics) 1059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t input = 0; 1061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForInputSource(inputSource); 1062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x", 1064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputSource, samplingRate, format, channelMask, acoustics); 1065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 1067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getInput() could not find device for inputSource %d", inputSource); 1068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // adapt channel selection to input source 1072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(inputSource) { 1073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 1074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK; 1075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_DOWNLINK: 1077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK; 1078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_CALL: 1080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK; 1081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 1083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 10861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = getInputProfile(device, 1087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, 1088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent format, 1089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask); 10901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (profile == 0) { 1091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d, " 1092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "channelMask %04x", 1093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, samplingRate, format, channelMask); 1094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mModule->mHandle == 0) { 1098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); 1099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 11021f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile); 1103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mInputSource = inputSource; 1105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mDevice = device; 1106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mSamplingRate = samplingRate; 1107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mFormat = format; 1108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mChannelMask = channelMask; 1109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mRefCount = 0; 1110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent input = mpClientInterface->openInput(profile->mModule->mHandle, 1111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &inputDesc->mDevice, 1112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &inputDesc->mSamplingRate, 1113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &inputDesc->mFormat, 1114ec40d284218466d8f0e832e7eb88e6ea6c479c88Glenn Kasten &inputDesc->mChannelMask, 1115ec40d284218466d8f0e832e7eb88e6ea6c479c88Glenn Kasten AUDIO_INPUT_FLAG_FAST /*FIXME*/); 1116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // only accept input with the exact requested set of parameters 1118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (input == 0 || 1119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (samplingRate != inputDesc->mSamplingRate) || 1120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (format != inputDesc->mFormat) || 1121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (channelMask != inputDesc->mChannelMask)) { 1122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGI("getInput() failed opening input: samplingRate %d, format %d, channelMask %x", 1123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, format, channelMask); 1124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (input != 0) { 1125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeInput(input); 1126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1129d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addInput(input, inputDesc); 1130b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 1131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return input; 1132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1134e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startInput(audio_io_handle_t input) 1135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("startInput() input %d", input); 1137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startInput() unknown input %d", input); 1140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 11421f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); 1143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTestInput == 0) 1146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // refuse 2 active AudioRecord clients at the same time except if the active input 1149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // uses AUDIO_SOURCE_HOTWORD in which case it is closed. 1150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t activeInput = getActiveInput(); 1151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isVirtualInputDevice(inputDesc->mDevice) && activeInput != 0) { 11521f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput); 1153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) { 1154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startInput() preempting already started low-priority input %d", activeInput); 1155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stopInput(activeInput); 1156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent releaseInput(activeInput); 1157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startInput() input %d failed: other input already started", input); 1159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 11641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setInputDevice(input, getNewInputDevice(input), true /* force */); 1165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // automatically enable the remote submix output when input is started 1167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 11693b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_POLICY_DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 1170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 1173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mRefCount = 1; 1175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1178e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopInput(audio_io_handle_t input) 1179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("stopInput() input %d", input); 1181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopInput() unknown input %d", input); 1184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 11861f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); 1187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (inputDesc->mRefCount == 0) { 1189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopInput() input %d already stopped", input); 1190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // automatically disable the remote submix output when input is stopped 1193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 11953b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 1196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 11981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent resetInputDevice(input); 1199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mRefCount = 0; 1200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1204e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::releaseInput(audio_io_handle_t input) 1205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseInput() %d", input); 1207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseInput() releasing unknown input %d", input); 1210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeInput(input); 1213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputs.removeItem(input); 12146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 1215b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 1216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseInput() exit"); 1217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1219d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::closeAllInputs() { 1220d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for(size_t input_index = 0; input_index < mInputs.size(); input_index++) { 1221d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeInput(mInputs.keyAt(input_index)); 1222d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 1223d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mInputs.clear(); 12246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 1225d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 1226d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 1227e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initStreamVolume(audio_stream_type_t stream, 1228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexMin, 1229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexMax) 1230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 1232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (indexMin < 0 || indexMin >= indexMax) { 1233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 1234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexMin = indexMin; 1237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexMax = indexMax; 1238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1240e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream, 1241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 1242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 1243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 1246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device)) { 1249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force max volume if stream cannot be muted 1253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 1254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", 1256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, device, index); 1257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 1259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // clear all device specific values 1260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexCur.clear(); 1262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 1264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // compute and apply stream volume on all outputs according to connected device 1266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t status = NO_ERROR; 1267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t curDevice = 1269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForVolume(mOutputs.valueAt(i)->device()); 1270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) { 1271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); 1272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volStatus != NO_ERROR) { 1273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = volStatus; 1274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return status; 1278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1280e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream, 1281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int *index, 1282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 1283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index == NULL) { 1285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device)) { 1288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 1291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the strategy the stream belongs to. 1292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); 1294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForVolume(device); 1296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 1298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 1299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1302e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutputForEffects( 1303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const SortedVector<audio_io_handle_t>& outputs) 1304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // select one output among several suitable for global effects. 1306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The priority is as follows: 1307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: An offloaded output. If the effect ends up not being offloadable, 1308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // AudioFlinger will invalidate the track and the offloaded output 1309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // will be closed causing the effect to be moved to a PCM output. 1310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: A deep buffer output 1311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the first output in the list 1312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 0) { 1314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputOffloaded = 0; 1318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputDeepBuffer = 0; 1319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 13211f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]); 1322d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags); 1323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 1324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputOffloaded = outputs[i]; 1325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) { 1327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDeepBuffer = outputs[i]; 1328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d", 1332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputOffloaded, outputDeepBuffer); 1333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputOffloaded != 0) { 1334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputOffloaded; 1335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDeepBuffer != 0) { 1337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputDeepBuffer; 1338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 1341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1343e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc) 1344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // apply simple rule where global effects are attached to the same output as MUSIC streams 1346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 13473b73df74357b33869b39a1d69427673c780bd805Eric Laurent routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC); 1348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 1349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs); 1350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = selectOutputForEffects(dstOutputs); 1352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutputForEffect() got output %d for fx %s flags %x", 1353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, (desc == NULL) ? "unspecified" : desc->name, (desc == NULL) ? 0 : desc->flags); 1354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 1356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1358e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc, 1359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t io, 1360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t strategy, 1361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session, 1362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int id) 1363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 1365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent index = mInputs.indexOfKey(io); 1367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("registerEffect() unknown io %d", io); 1369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 1374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 1375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->name, desc->memoryUsage); 1376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsMemory += desc->memoryUsage; 1379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 1380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->name, io, strategy, session, id); 1381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 1382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 13831f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = new EffectDescriptor(); 13841f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t)); 13851f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mIo = io; 13861f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mStrategy = (routing_strategy)strategy; 13871f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mSession = session; 13881f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mEnabled = false; 1389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 13901f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mEffects.add(id, effectDesc); 1391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1395e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::unregisterEffect(int id) 1396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() unknown effect ID %d", id); 1400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14031f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = mEffects.valueAt(index); 1404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14051f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent setEffectEnabled(effectDesc, false); 1406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14071f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (mTotalEffectsMemory < effectDesc->mDesc.memoryUsage) { 1408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() memory %d too big for total %d", 14091f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.memoryUsage, mTotalEffectsMemory); 14101f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.memoryUsage = mTotalEffectsMemory; 1411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 14121f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mTotalEffectsMemory -= effectDesc->mDesc.memoryUsage; 1413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 14141f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.name, id, effectDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.removeItem(id); 1417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1421e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(int id, bool enabled) 1422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() unknown effect ID %d", id); 1426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 1430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14321f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(const sp<EffectDescriptor>& effectDesc, bool enabled) 1433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 14341f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (enabled == effectDesc->mEnabled) { 1435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(%s) effect already %s", 1436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 1437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (enabled) { 14411f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (mTotalEffectsCpuLoad + effectDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 1442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 14431f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.name, (float)effectDesc->mDesc.cpuLoad/10); 1444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 14461f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mTotalEffectsCpuLoad += effectDesc->mDesc.cpuLoad; 1447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 1448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 14491f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (mTotalEffectsCpuLoad < effectDesc->mDesc.cpuLoad) { 1450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 14511f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 14521f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 1453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 14541f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mTotalEffectsCpuLoad -= effectDesc->mDesc.cpuLoad; 1455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 1456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 14571f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mEnabled = enabled; 1458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1461e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isNonOffloadableEffectEnabled() 1462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 14641f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = mEffects.valueAt(i); 14651f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) && 14661f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) { 1467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d", 14681f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.name, effectDesc->mSession); 1469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1475e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 1476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 1478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 14791f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); 14803b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 1481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1487e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, 14883b73df74357b33869b39a1d69427673c780bd805Eric Laurent uint32_t inPastMs) const 1489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 1491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 14921f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); 1493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 14943b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 1495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1501e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isSourceActive(audio_source_t source) const 1502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 15041f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i); 1505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((inputDescriptor->mInputSource == (int)source || 15063b73df74357b33869b39a1d69427673c780bd805Eric Laurent (source == AUDIO_SOURCE_VOICE_RECOGNITION && 1507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) 1508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent && (inputDescriptor->mRefCount > 0)) { 1509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1516e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::dump(int fd) 1517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 1519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 1520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 1521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 1523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 1524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput); 1526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 1527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 1528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 15293b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for communications %d\n", 15303b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]); 1531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 15323b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA]); 1533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 15343b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD]); 1535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 15363b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK]); 1537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 15383b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM]); 1539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 15407b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n", 15417b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO]); 15427b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang result.append(buffer); 1543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 15443a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, " Available output devices:\n"); 15453a4311c68348f728558e87b5db67d47605783890Eric Laurent result.append(buffer); 15463a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, result.string(), result.size()); 15473a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) { 15481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableOutputDevices[i]->dump(fd, 2, i); 15493a4311c68348f728558e87b5db67d47605783890Eric Laurent } 15503a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, "\n Available input devices:\n"); 15513a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, buffer, strlen(buffer)); 15523a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size(); i++) { 15531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableInputDevices[i]->dump(fd, 2, i); 15543a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 1557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 1559d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1); 1560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules[i]->dump(fd); 1562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nOutputs dump:\n"); 1565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 1568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.valueAt(i)->dump(fd); 1570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nInputs dump:\n"); 1573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 1575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 1576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputs.valueAt(i)->dump(fd); 1578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nStreams dump:\n"); 1581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, 1583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 1584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1585beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn for (size_t i = 0; i < AUDIO_STREAM_CNT; i++) { 1586d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " %02zu ", i); 1587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[i].dump(fd); 1589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 1592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 1593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "Registered effects:\n"); 1596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 1598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 1599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.valueAt(i)->dump(fd); 1601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This function checks for the parameters which can be offloaded. 1608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This can be enhanced depending on the capability of the DSP and policy 1609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// of the system. 1610e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo) 1611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d," 1613d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent " BitRate=%u, duration=%" PRId64 " us, has_video=%d", 1614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate, offloadInfo.channel_mask, 1615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format, 1616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us, 1617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.has_video); 1618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check if offload has been disabled 1620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char propValue[PROPERTY_VALUE_MAX]; 1621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (property_get("audio.offload.disable", propValue, "0")) { 1622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (atoi(propValue) != 0) { 1623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("offload disabled by audio.offload.disable=%s", propValue ); 1624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check if stream type is music, then only allow offload as of now. 1629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC) 1630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: stream_type != MUSIC, returning false"); 1632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //TODO: enable audio offloading with video when ready 1636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.has_video) 1637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: has_video == true, returning false"); 1639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //If duration is less than minimum value defined in property, return false 1643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (property_get("audio.offload.min.duration.secs", propValue, NULL)) { 1644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) { 1645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue); 1646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) { 1649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS); 1650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 1654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 1655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // detects there is an active non offloadable effect. 1656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 1657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 1658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the background. 1659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isNonOffloadableEffectEnabled()) { 1660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // See if there is a profile to support this. 1664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // AUDIO_DEVICE_NONE 16651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */, 1666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate, 1667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format, 1668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.channel_mask, 1669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD); 16701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT "); 16711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return (profile != 0); 1672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPorts(audio_port_role_t role, 16756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_type_t type, 16766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent unsigned int *num_ports, 16776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port *ports, 16786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent unsigned int *generation) 16796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 16806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (num_ports == NULL || (*num_ports != 0 && ports == NULL) || 16816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent generation == NULL) { 16826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 16836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 16846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports); 16856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (ports == NULL) { 16866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports = 0; 16876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 16886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 16896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t portsWritten = 0; 16906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t portsMax = *num_ports; 16916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports = 0; 16926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) { 16936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) { 16946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; 16956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i < mAvailableOutputDevices.size() && portsWritten < portsMax; i++) { 16966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]); 16976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 16986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports += mAvailableOutputDevices.size(); 16996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) { 17016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; 17026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i < mAvailableInputDevices.size() && portsWritten < portsMax; i++) { 17036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]); 17046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports += mAvailableInputDevices.size(); 17066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) { 17096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) { 17106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++) { 17116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mInputs[i]->toAudioPort(&ports[portsWritten++]); 17126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports += mInputs.size(); 17146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) { 171684c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent size_t numOutputs = 0; 171784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 171884c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent if (!mOutputs[i]->isDuplicated()) { 171984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent numOutputs++; 172084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent if (portsWritten < portsMax) { 172184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent mOutputs[i]->toAudioPort(&ports[portsWritten++]); 172284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent } 172384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent } 17246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 172584c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent *num_ports += numOutputs; 17266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *generation = curAudioPortGeneration(); 1729beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPorts() got %zu ports needed %d", portsWritten, *num_ports); 17306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 17316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 17326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 17336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused) 17346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 17356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 17366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 17376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 17381f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp<AudioPolicyManager::AudioOutputDescriptor> AudioPolicyManager::getOutputFromId( 17396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_handle_t id) const 17406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 17411f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = NULL; 17426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 17436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent outputDesc = mOutputs.valueAt(i); 17446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc->mId == id) { 17456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 17466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return outputDesc; 17496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 17506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 17511f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp<AudioPolicyManager::AudioInputDescriptor> AudioPolicyManager::getInputFromId( 17526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_handle_t id) const 17536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 17541f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = NULL; 17556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 17566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent inputDesc = mInputs.valueAt(i); 17576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (inputDesc->mId == id) { 17586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 17596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return inputDesc; 17626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 17636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 17641f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleForDevice( 17651f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent audio_devices_t device) const 17666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 17671f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp <HwModule> module; 17681f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 17696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 17706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (mHwModules[i]->mHandle == 0) { 17716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent continue; 17726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (audio_is_output_device(device)) { 17746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 17756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent { 17766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) { 17776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return mHwModules[i]; 17786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 17816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) { 17826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (mHwModules[i]->mInputProfiles[j]->mSupportedDevices.types() & 17836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent device & ~AUDIO_DEVICE_BIT_IN) { 17846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return mHwModules[i]; 17856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 17891f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent return module; 17906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 17916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 17921f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleFromName(const char *name) const 17931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 17941f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp <HwModule> module; 17951f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 17961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 17971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent { 17981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(mHwModules[i]->mName, name) == 0) { 17991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return mHwModules[i]; 18001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 18011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 18021f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent return module; 18031afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 18041afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 18051afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 18066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, 18076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *handle, 18086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent uid_t uid) 18096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 18106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch()"); 18116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 18126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (handle == NULL || patch == NULL) { 18136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 18146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 18156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks); 18166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 18176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->num_sources > 1 || patch->num_sinks > 1) { 18186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 18196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 18206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sources[0].role != AUDIO_PORT_ROLE_SOURCE || 18216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sinks[0].role != AUDIO_PORT_ROLE_SINK) { 18226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 18236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 18246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 18256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc; 18266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(*handle); 18276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 18286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch sink id %d role %d type %d", patch->sinks[0].id, patch->sinks[0].role, 18296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sinks[0].type); 18306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch source id %d role %d type %d", patch->sources[0].id, 18316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sources[0].role, 18326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sources[0].type); 18336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 18346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 18356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 18366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() mUidCached %d patchDesc->mUid %d uid %d", 18376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mUidCached, patchDesc->mUid, uid); 18386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) { 18396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 18406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 18416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 18426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *handle = 0; 18436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 18446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 18456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) { 18466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // TODO add support for mix to mix connection 18476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE) { 18486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() source mix sink not device"); 18496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 18506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 18516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // output mix to output device connection 18521f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id); 18536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc == NULL) { 18546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id); 18556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 18566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 185784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!outputDesc->isDuplicated(),"duplicated output %d in source in ports", 185884c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent outputDesc->mIoHandle); 18596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0) { 18606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) { 18616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() source id differs for patch current id %d new id %d", 18626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch.sources[0].id, patch->sources[0].id); 18636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 18646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 18656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 18666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<DeviceDescriptor> devDesc = 18676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableOutputDevices.getDeviceFromId(patch->sinks[0].id); 18686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (devDesc == 0) { 18696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() out device not found for id %d", patch->sinks[0].id); 18706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 18716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 18726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 187384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent if (!outputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType, 18746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sources[0].sample_rate, 18756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sources[0].format, 18766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sources[0].channel_mask, 18776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent AUDIO_OUTPUT_FLAG_NONE)) { 18786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 18796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 18806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // TODO: reconfigure output format and channels here 18816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() setting device %08x on output %d", 188284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent devDesc->mDeviceType, outputDesc->mIoHandle); 18836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent setOutputDevice(outputDesc->mIoHandle, 188484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent devDesc->mDeviceType, 18856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent true, 18866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 0, 18876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent handle); 18886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*handle); 18896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 18906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) { 18916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setOutputDevice() did not reuse the patch provided"); 18926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 18936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 18946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = uid; 18956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() success"); 18966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 18976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setOutputDevice() failed to create a patch"); 18986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 18996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) { 19016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { 19026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // input device to input mix connection 19031f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id); 19046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (inputDesc == NULL) { 19056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 19066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0) { 19086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) { 19096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 19106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<DeviceDescriptor> devDesc = 19136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices.getDeviceFromId(patch->sources[0].id); 19146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (devDesc == 0) { 19156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 19166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 191884c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent if (!inputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType, 19196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sinks[0].sample_rate, 19206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sinks[0].format, 19216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sinks[0].channel_mask, 19226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent AUDIO_OUTPUT_FLAG_NONE)) { 19236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 19246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // TODO: reconfigure output format and channels here 19266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() setting device %08x on output %d", 192784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent devDesc->mDeviceType, inputDesc->mIoHandle); 19286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent setInputDevice(inputDesc->mIoHandle, 192984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent devDesc->mDeviceType, 19306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent true, 19316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent handle); 19326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*handle); 19336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 19346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) { 19356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setInputDevice() did not reuse the patch provided"); 19366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 19386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = uid; 19396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() success"); 19406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 19416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setInputDevice() failed to create a patch"); 19426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 19436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) { 19456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // device to device connection 19466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0) { 19476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mPatch.sources[0].id != patch->sources[0].id && 19486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) { 19496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 19506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 19536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<DeviceDescriptor> srcDeviceDesc = 19546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices.getDeviceFromId(patch->sources[0].id); 19556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<DeviceDescriptor> sinkDeviceDesc = 19566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableOutputDevices.getDeviceFromId(patch->sinks[0].id); 19576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (srcDeviceDesc == 0 || sinkDeviceDesc == 0) { 19586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 19596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent //update source and sink with our own data as the data passed in the patch may 19616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // be incomplete. 19626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_patch newPatch = *patch; 19636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]); 19646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[0], &patch->sinks[0]); 19656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 19666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // TODO: add support for devices on different HW modules 19676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (srcDeviceDesc->mModule != sinkDeviceDesc->mModule) { 19686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 19696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // TODO: check from routing capabilities in config file and other conflicting patches 19716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 19726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 19736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 19746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent afPatchHandle = patchDesc->mAfPatchHandle; 19756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 19776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->createAudioPatch(&newPatch, 19786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &afPatchHandle, 19796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 0); 19806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() patch panel returned %d patchHandle %d", 19816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, afPatchHandle); 19826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (status == NO_ERROR) { 19836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 19846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 19856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &newPatch, uid); 19866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent addAudioPatch(patchDesc->mHandle, patchDesc); 19876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 19886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch = newPatch; 19896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mAfPatchHandle = afPatchHandle; 19916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *handle = patchDesc->mHandle; 19926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 1993b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 19946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 19956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() patch panel could not connect device patch, error %d", 19966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status); 19976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 19986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 20006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 20016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 20036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 20046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 20066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 20076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle, 20096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent uid_t uid) 20106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 20116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() patch %d", handle); 20126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(handle); 20146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 20166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 20176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 20196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() mUidCached %d patchDesc->mUid %d uid %d", 20206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mUidCached, patchDesc->mUid, uid); 20216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) { 20226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 20236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_patch *patch = &patchDesc->mPatch; 20266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = mUidCached; 20276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) { 20281f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id); 20296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc == NULL) { 20306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id); 20316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 20326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent setOutputDevice(outputDesc->mIoHandle, 20356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent getNewOutputDevice(outputDesc->mIoHandle, true /*fromCache*/), 20366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent true, 20376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 0, 20386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent NULL); 20396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) { 20406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { 20411f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id); 20426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (inputDesc == NULL) { 20436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id); 20446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 20456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent setInputDevice(inputDesc->mIoHandle, 20476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent getNewInputDevice(inputDesc->mIoHandle), 20486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent true, 20496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent NULL); 20506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) { 20516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = patchDesc->mAfPatchHandle; 20526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 20536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() patch panel returned %d patchHandle %d", 20546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, patchDesc->mAfPatchHandle); 20556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent removeAudioPatch(patchDesc->mHandle); 20566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 2057b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 20586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 20596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 20606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 20626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 20636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 20656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 20666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches, 20686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_patch *patches, 20696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent unsigned int *generation) 20706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 20716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (num_patches == NULL || (*num_patches != 0 && patches == NULL) || 20726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent generation == NULL) { 20736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 20746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 2075beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPatches() num_patches %d patches %p available patches %zu", 20766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_patches, patches, mAudioPatches.size()); 20776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patches == NULL) { 20786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_patches = 0; 20796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t patchesWritten = 0; 20826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t patchesMax = *num_patches; 20836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; 20846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i < mAudioPatches.size() && patchesWritten < patchesMax; i++) { 20856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patches[patchesWritten] = mAudioPatches[i]->mPatch; 20866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patches[patchesWritten++].id = mAudioPatches[i]->mHandle; 2087beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPatches() patch %zu num_sources %d num_sinks %d", 20886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i, mAudioPatches[i]->mPatch.num_sources, mAudioPatches[i]->mPatch.num_sinks); 20896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_patches = mAudioPatches.size(); 20916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *generation = curAudioPortGeneration(); 2093beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPatches() got %zu patches needed %d", patchesWritten, *num_patches); 20946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 20956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 20966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2097e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config) 20986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 2099e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("setAudioPortConfig()"); 2100e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2101e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config == NULL) { 2102e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2103e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2104e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("setAudioPortConfig() on port handle %d", config->id); 2105e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent // Only support gain configuration for now 2106a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask != AUDIO_PORT_CONFIG_GAIN) { 2107a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return INVALID_OPERATION; 2108e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2109e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2110a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent sp<AudioPortConfig> audioPortConfig; 2111e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config->type == AUDIO_PORT_TYPE_MIX) { 2112e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config->role == AUDIO_PORT_ROLE_SOURCE) { 21131f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = getOutputFromId(config->id); 2114e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (outputDesc == NULL) { 2115e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2116e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 211784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!outputDesc->isDuplicated(), 211884c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent "setAudioPortConfig() called on duplicated output %d", 211984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent outputDesc->mIoHandle); 2120a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig = outputDesc; 2121e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else if (config->role == AUDIO_PORT_ROLE_SINK) { 21221f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = getInputFromId(config->id); 2123e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (inputDesc == NULL) { 2124e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2125e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2126a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig = inputDesc; 2127e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 2128e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2129e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2130e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else if (config->type == AUDIO_PORT_TYPE_DEVICE) { 2131e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent sp<DeviceDescriptor> deviceDesc; 2132e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config->role == AUDIO_PORT_ROLE_SOURCE) { 2133e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id); 2134e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else if (config->role == AUDIO_PORT_ROLE_SINK) { 2135e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id); 2136e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 2137e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2138e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2139e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (deviceDesc == NULL) { 2140e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2141e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2142a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig = deviceDesc; 2143e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 2144e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2145e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2146e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2147a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config backupConfig; 2148a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig); 2149a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status == NO_ERROR) { 2150a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config newConfig; 2151a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig->toAudioPortConfig(&newConfig, config); 2152a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status = mpClientInterface->setAudioPortConfig(&newConfig, 0); 2153e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2154a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 2155a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig->applyAudioPortConfig(&backupConfig); 2156e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2157e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2158e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return status; 21596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 21606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 21616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentvoid AudioPolicyManager::clearAudioPatches(uid_t uid) 21626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 21636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (ssize_t i = 0; i < (ssize_t)mAudioPatches.size(); i++) { 21646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i); 21656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid == uid) { 21666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // releaseAudioPatch() removes the patch from mAudioPatches 21676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (releaseAudioPatch(mAudioPatches.keyAt(i), uid) == NO_ERROR) { 21686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i--; 21696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 21706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 21716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 21726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 21736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 21746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::addAudioPatch(audio_patch_handle_t handle, 21756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const sp<AudioPatch>& patch) 21766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 21776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(handle); 21786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 21796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 21806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("addAudioPatch() patch %d already in", handle); 21816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return ALREADY_EXISTS; 21826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 21836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAudioPatches.add(handle, patch); 21846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("addAudioPatch() handle %d af handle %d num_sources %d num_sinks %d source handle %d" 21856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent "sink handle %d", 21866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent handle, patch->mAfPatchHandle, patch->mPatch.num_sources, patch->mPatch.num_sinks, 21876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->mPatch.sources[0].id, patch->mPatch.sinks[0].id); 21886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 21896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 21906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 21916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::removeAudioPatch(audio_patch_handle_t handle) 21926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 21936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(handle); 21946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 21956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 21966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("removeAudioPatch() patch %d not in", handle); 21976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return ALREADY_EXISTS; 21986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 21996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("removeAudioPatch() handle %d af handle %d", handle, 22006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAudioPatches.valueAt(index)->mAfPatchHandle); 22016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAudioPatches.removeItemsAt(index); 22026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 22036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 22046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 2206e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent// AudioPolicyManager 2207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 2208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 22093a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::nextUniqueId() 22103a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 22113a4311c68348f728558e87b5db67d47605783890Eric Laurent return android_atomic_inc(&mNextUniqueId); 22123a4311c68348f728558e87b5db67d47605783890Eric Laurent} 22133a4311c68348f728558e87b5db67d47605783890Eric Laurent 22146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentuint32_t AudioPolicyManager::nextAudioPortGeneration() 22156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 22166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return android_atomic_inc(&mAudioPortGeneration); 22176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 22186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2219e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) 2220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : 2221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 2222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent Thread(false), 2223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 2224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput((audio_io_handle_t)0), 22253b73df74357b33869b39a1d69427673c780bd805Eric Laurent mPhoneState(AUDIO_MODE_NORMAL), 2226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 2227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 22283a4311c68348f728558e87b5db67d47605783890Eric Laurent mA2dpSuspended(false), 22296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mSpeakerDrcEnabled(false), mNextUniqueId(1), 22306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAudioPortGeneration(1) 2231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 22326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mUidCached = getuid(); 2233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface = clientInterface; 2234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 22353b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) { 22363b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[i] = AUDIO_POLICY_FORCE_NONE; 2237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 22391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDefaultOutputDevice = new DeviceDescriptor(String8(""), AUDIO_DEVICE_OUT_SPEAKER); 2240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { 2241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { 2242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("could not load audio policy configuration file, setting defaults"); 2243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent defaultAudioPolicyConfig(); 2244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 22463a4311c68348f728558e87b5db67d47605783890Eric Laurent // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices 2247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // must be done after reading the policy 2249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent initializeVolumeCurves(); 2250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open all output streams needed to access attached devices 22523a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types(); 22533a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN; 2254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 2255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 2256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 2257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("could not open HW module %s", mHwModules[i]->mName); 2258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open all output streams needed to access attached devices 2261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // except for direct output streams that are only opened when they are actually 2262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // required by an app. 22633a4311c68348f728558e87b5db67d47605783890Eric Laurent // This also validates mAvailableOutputDevices list 2264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 2265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 22661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j]; 2267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 22683a4311c68348f728558e87b5db67d47605783890Eric Laurent if (outProfile->mSupportedDevices.isEmpty()) { 22693a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName); 22703a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 22713a4311c68348f728558e87b5db67d47605783890Eric Laurent } 22723a4311c68348f728558e87b5db67d47605783890Eric Laurent 22733a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t profileTypes = outProfile->mSupportedDevices.types(); 22743a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((profileTypes & outputDeviceTypes) && 2275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) { 22761f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile); 22773a4311c68348f728558e87b5db67d47605783890Eric Laurent 22781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice->mDeviceType & profileTypes); 2279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput( 2280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outProfile->mModule->mHandle, 2281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mDevice, 2282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 2283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 2284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 2285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 2286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags); 2287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == 0) { 22883a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Cannot open output stream for device %08x on hw module %s", 22893a4311c68348f728558e87b5db67d47605783890Eric Laurent outputDesc->mDevice, 22903a4311c68348f728558e87b5db67d47605783890Eric Laurent mHwModules[i]->mName); 2291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 22925b61dddd0dba28922068da2487894761486aec6cEric Laurent for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { 22931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType; 22943a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = 22955b61dddd0dba28922068da2487894761486aec6cEric Laurent mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]); 22963a4311c68348f728558e87b5db67d47605783890Eric Laurent // give a valid ID to an attached device once confirmed it is reachable 22973a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((index >= 0) && (mAvailableOutputDevices[index]->mId == 0)) { 22983a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices[index]->mId = nextUniqueId(); 22996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableOutputDevices[index]->mModule = mHwModules[i]; 23003a4311c68348f728558e87b5db67d47605783890Eric Laurent } 23013a4311c68348f728558e87b5db67d47605783890Eric Laurent } 2302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput == 0 && 2303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 2304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput = output; 2305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, outputDesc); 23076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGI("CSTOR setOutputDevice %08x", outputDesc->mDevice); 2308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, 23093a4311c68348f728558e87b5db67d47605783890Eric Laurent outputDesc->mDevice, 2310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent true); 2311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 23143a4311c68348f728558e87b5db67d47605783890Eric Laurent // open input streams needed to access attached devices to validate 23153a4311c68348f728558e87b5db67d47605783890Eric Laurent // mAvailableInputDevices list 23163a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 23173a4311c68348f728558e87b5db67d47605783890Eric Laurent { 23181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j]; 23193a4311c68348f728558e87b5db67d47605783890Eric Laurent 23203a4311c68348f728558e87b5db67d47605783890Eric Laurent if (inProfile->mSupportedDevices.isEmpty()) { 23213a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName); 23223a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 23233a4311c68348f728558e87b5db67d47605783890Eric Laurent } 2324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 23253a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t profileTypes = inProfile->mSupportedDevices.types(); 23263a4311c68348f728558e87b5db67d47605783890Eric Laurent if (profileTypes & inputDeviceTypes) { 23271f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile); 23283a4311c68348f728558e87b5db67d47605783890Eric Laurent 23293a4311c68348f728558e87b5db67d47605783890Eric Laurent inputDesc->mInputSource = AUDIO_SOURCE_MIC; 23301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mDevice = inProfile->mSupportedDevices[0]->mDeviceType; 23313a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_io_handle_t input = mpClientInterface->openInput( 23323a4311c68348f728558e87b5db67d47605783890Eric Laurent inProfile->mModule->mHandle, 23333a4311c68348f728558e87b5db67d47605783890Eric Laurent &inputDesc->mDevice, 23343a4311c68348f728558e87b5db67d47605783890Eric Laurent &inputDesc->mSamplingRate, 23353a4311c68348f728558e87b5db67d47605783890Eric Laurent &inputDesc->mFormat, 2336ec40d284218466d8f0e832e7eb88e6ea6c479c88Glenn Kasten &inputDesc->mChannelMask, 2337ec40d284218466d8f0e832e7eb88e6ea6c479c88Glenn Kasten AUDIO_INPUT_FLAG_FAST /*FIXME*/); 23383a4311c68348f728558e87b5db67d47605783890Eric Laurent 23393a4311c68348f728558e87b5db67d47605783890Eric Laurent if (input != 0) { 23405b61dddd0dba28922068da2487894761486aec6cEric Laurent for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { 23411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType; 23423a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = 23435b61dddd0dba28922068da2487894761486aec6cEric Laurent mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]); 23443a4311c68348f728558e87b5db67d47605783890Eric Laurent // give a valid ID to an attached device once confirmed it is reachable 23453a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((index >= 0) && (mAvailableInputDevices[index]->mId == 0)) { 23463a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices[index]->mId = nextUniqueId(); 23476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices[index]->mModule = mHwModules[i]; 23483a4311c68348f728558e87b5db67d47605783890Eric Laurent } 23493a4311c68348f728558e87b5db67d47605783890Eric Laurent } 23503a4311c68348f728558e87b5db67d47605783890Eric Laurent mpClientInterface->closeInput(input); 23513a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 23523a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Cannot open input stream for device %08x on hw module %s", 23533a4311c68348f728558e87b5db67d47605783890Eric Laurent inputDesc->mDevice, 23543a4311c68348f728558e87b5db67d47605783890Eric Laurent mHwModules[i]->mName); 23553a4311c68348f728558e87b5db67d47605783890Eric Laurent } 23563a4311c68348f728558e87b5db67d47605783890Eric Laurent } 23573a4311c68348f728558e87b5db67d47605783890Eric Laurent } 23583a4311c68348f728558e87b5db67d47605783890Eric Laurent } 23593a4311c68348f728558e87b5db67d47605783890Eric Laurent // make sure all attached devices have been allocated a unique ID 23603a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableOutputDevices.size();) { 23613a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableOutputDevices[i]->mId == 0) { 23621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mDeviceType); 23633a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.remove(mAvailableOutputDevices[i]); 23643a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 23653a4311c68348f728558e87b5db67d47605783890Eric Laurent } 23663a4311c68348f728558e87b5db67d47605783890Eric Laurent i++; 23673a4311c68348f728558e87b5db67d47605783890Eric Laurent } 23683a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size();) { 23693a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableInputDevices[i]->mId == 0) { 23701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mDeviceType); 23713a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.remove(mAvailableInputDevices[i]); 23723a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 23733a4311c68348f728558e87b5db67d47605783890Eric Laurent } 23743a4311c68348f728558e87b5db67d47605783890Eric Laurent i++; 23753a4311c68348f728558e87b5db67d47605783890Eric Laurent } 23763a4311c68348f728558e87b5db67d47605783890Eric Laurent // make sure default device is reachable 23773a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) { 23781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mDeviceType); 23793a4311c68348f728558e87b5db67d47605783890Eric Laurent } 2380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 2382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 2384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 2386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput != 0) { 2387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 2388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"), 0); 2389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 2390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestDevice = AUDIO_DEVICE_OUT_SPEAKER; 2392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestSamplingRate = 44100; 23933b73df74357b33869b39a1d69427673c780bd805Eric Laurent mTestFormat = AUDIO_FORMAT_PCM_16_BIT; 23943b73df74357b33869b39a1d69427673c780bd805Eric Laurent mTestChannels = AUDIO_CHANNEL_OUT_STEREO; 2395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestLatencyMs = 0; 2396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput = 0; 2397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = false; 2398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 2399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[i] = 0; 2400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 2403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 2404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 2405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent run(buffer, ANDROID_PRIORITY_AUDIO); 2406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 2408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2410e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::~AudioPolicyManager() 2411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 2413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent exit(); 2414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 2415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(mOutputs.keyAt(i)); 2417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 2419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeInput(mInputs.keyAt(i)); 2420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 24213a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.clear(); 24223a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.clear(); 24231f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mOutputs.clear(); 24241f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mInputs.clear(); 24251f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mHwModules.clear(); 2426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2428e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::initCheck() 2429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; 2431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 2434e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::threadLoop() 2435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("entering threadLoop()"); 2437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (!exitPending()) 2438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 command; 2440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int valueInt; 2441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 value; 2442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent Mutex::Autolock _l(mLock); 2444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 2445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 2447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param = AudioParameter(command); 2448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 2450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent valueInt != 0) { 2451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Test command %s received", command.string()); 2452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 target; 2453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("target"), target) != NO_ERROR) { 2454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent target = "Manager"; 2455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 2457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_output")); 2458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput = valueInt; 2459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 2461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_direct")); 2462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "false") { 2463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = false; 2464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "true") { 2465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = true; 2466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 2469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_input")); 2470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestInput = valueInt; 2471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 2474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_format")); 24753b73df74357b33869b39a1d69427673c780bd805Eric Laurent int format = AUDIO_FORMAT_INVALID; 2476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "PCM 16 bits") { 24773b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_PCM_16_BIT; 2478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "PCM 8 bits") { 24793b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_PCM_8_BIT; 2480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "Compressed MP3") { 24813b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_MP3; 2482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 24833b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (format != AUDIO_FORMAT_INVALID) { 2484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 2485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestFormat = format; 2486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 2487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 2488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("format"), format); 2489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 2490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 2494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_channels")); 2495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int channels = 0; 2496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "Channels Stereo") { 24983b73df74357b33869b39a1d69427673c780bd805Eric Laurent channels = AUDIO_CHANNEL_OUT_STEREO; 2499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "Channels Mono") { 25003b73df74357b33869b39a1d69427673c780bd805Eric Laurent channels = AUDIO_CHANNEL_OUT_MONO; 2501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (channels != 0) { 2503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 2504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestChannels = channels; 2505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 2506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 2507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("channels"), channels); 2508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 2509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 2513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_sampleRate")); 2514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (valueInt >= 0 && valueInt <= 96000) { 2515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int samplingRate = valueInt; 2516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 2517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestSamplingRate = samplingRate; 2518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 2519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 2520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("sampling_rate"), samplingRate); 2521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 2522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 2527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_reopen")); 2528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 25291f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput); 2530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(mPrimaryOutput); 2531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; 2533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(mPrimaryOutput); 2535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 25361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL); 2537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; 2538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput = mpClientInterface->openOutput(moduleHandle, 2539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mDevice, 2540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mSamplingRate, 2541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mFormat, 2542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mChannelMask, 2543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &outputDesc->mLatency, 2544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags); 2545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput == 0) { 2546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d", 2547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); 2548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 2550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"), 0); 2551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 2552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(mPrimaryOutput, outputDesc); 2553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 2558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2563e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::exit() 2564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AutoMutex _l(mLock); 2567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent requestExit(); 2568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mWaitWorkCV.signal(); 2569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent requestExitAndWait(); 2571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2573e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::testOutputIndex(audio_io_handle_t output) 2574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 2576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == mTestOutputs[i]) return i; 2577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 2579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 2581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- 2583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 25841f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc) 2585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 25861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mIoHandle = output; 25871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mId = nextUniqueId(); 25881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mOutputs.add(output, outputDesc); 25896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 2590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 25921f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc) 2593d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 25941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mIoHandle = input; 25951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mId = nextUniqueId(); 25961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mInputs.add(input, inputDesc); 25976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 2598d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 2599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 26003a4311c68348f728558e87b5db67d47605783890Eric LaurentString8 AudioPolicyManager::addressToParameter(audio_devices_t device, const String8 address) 26013a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 26023a4311c68348f728558e87b5db67d47605783890Eric Laurent if (device & AUDIO_DEVICE_OUT_ALL_A2DP) { 26033a4311c68348f728558e87b5db67d47605783890Eric Laurent return String8("a2dp_sink_address=")+address; 26043a4311c68348f728558e87b5db67d47605783890Eric Laurent } 26053a4311c68348f728558e87b5db67d47605783890Eric Laurent return address; 26063a4311c68348f728558e87b5db67d47605783890Eric Laurent} 26073a4311c68348f728558e87b5db67d47605783890Eric Laurent 2608e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, 26093b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state, 2610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t>& outputs, 26113a4311c68348f728558e87b5db67d47605783890Eric Laurent const String8 address) 2612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 26131f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc; 2614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 26153b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { 2616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // first list already open outputs that can be routed to this device 2617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(i); 26193a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) { 2620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i)); 2621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(mOutputs.keyAt(i)); 2622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // then look for output profiles that can be routed to this device 26251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent SortedVector< sp<IOProfile> > profiles; 2626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 2627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 2629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 2632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 26333a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) { 2634d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i); 2635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profiles.add(mHwModules[i]->mOutputProfiles[j]); 2636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profiles.isEmpty() && outputs.isEmpty()) { 2641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 2642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 2643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open outputs for matching profiles if needed. Direct outputs are also opened to 2646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 2647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 26481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = profiles[profile_index]; 2649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // nothing to do if one output is already opened for this profile 2651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent size_t j; 2652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (j = 0; j < mOutputs.size(); j++) { 2653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(j); 2654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && desc->mProfile == profile) { 2655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 2656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (j != mOutputs.size()) { 2659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 26623a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("opening output for device %08x with params %s", device, address.string()); 2663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = new AudioOutputDescriptor(profile); 2664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mDevice = device; 2665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; 2666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate = desc->mSamplingRate; 2667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format = desc->mFormat; 2668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.channel_mask = desc->mChannelMask; 2669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle, 2671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mDevice, 2672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mSamplingRate, 2673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mFormat, 2674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mChannelMask, 2675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &desc->mLatency, 2676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mFlags, 2677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent &offloadInfo); 2678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output != 0) { 2679d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where the out_set_parameters() for card & device gets called 26803a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!address.isEmpty()) { 26813a4311c68348f728558e87b5db67d47605783890Eric Laurent mpClientInterface->setParameters(output, addressToParameter(device, address)); 2682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2684d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where we step through and resolve any "dynamic" fields 2685d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 reply; 2686d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char *value; 2687d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 2688d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 2689d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 2690d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice() direct output sup sampling rates %s", 2691d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2692d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2693d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 26941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadSamplingRates(value + 1); 2695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2696d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2697d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2698d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 2699d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 2700d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice() direct output sup formats %s", 2701d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2702d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2703d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 27041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadFormats(value + 1); 2705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2706d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2707d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 2708d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 2709d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 2710d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice() direct output sup channel masks %s", 2711d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2712d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2713d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 27141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadOutChannels(value + 1); 2715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2716d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2717d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (((profile->mSamplingRates[0] == 0) && 2718d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mSamplingRates.size() < 2)) || 2719d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) && 2720d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mFormats.size() < 2)) || 2721d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mChannelMasks[0] == 0) && 2722d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mChannelMasks.size() < 2))) { 2723d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkOutputsForDevice() direct output missing param"); 2724d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 2725d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent output = 0; 27261e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else if (profile->mSamplingRates[0] == 0 || profile->mFormats[0] == 0 || 27271e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent profile->mChannelMasks[0] == 0) { 2728d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 27291e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent desc->mSamplingRate = profile->pickSamplingRate(); 27301e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent desc->mFormat = profile->pickFormat(); 27311e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent desc->mChannelMask = profile->pickChannelMask(); 2732d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent offloadInfo.sample_rate = desc->mSamplingRate; 27331e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent offloadInfo.format = desc->mFormat; 27341e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent offloadInfo.channel_mask = desc->mChannelMask; 2735d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent output = mpClientInterface->openOutput( 2736d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mModule->mHandle, 2737d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mDevice, 2738d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mSamplingRate, 2739d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mFormat, 2740d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mChannelMask, 2741d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mLatency, 2742d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc->mFlags, 2743d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &offloadInfo); 2744d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2745d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2746d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (output != 0) { 2747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, desc); 2748d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { 2749d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent audio_io_handle_t duplicatedOutput = 0; 2750d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2751d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // set initial stream volume for device 2752d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent applyStreamVolumes(output, device, 0, true); 2753d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2754d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent //TODO: configure audio effect output stage here 2755d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2756d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // open a duplicating output thread for the new output and the primary output 2757d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent duplicatedOutput = mpClientInterface->openDuplicateOutput(output, 2758d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mPrimaryOutput); 2759d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (duplicatedOutput != 0) { 2760d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // add duplicated output descriptor 27611f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> dupOutputDesc = new AudioOutputDescriptor(NULL); 2762d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); 2763d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mOutput2 = mOutputs.valueFor(output); 2764d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mSamplingRate = desc->mSamplingRate; 2765d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mFormat = desc->mFormat; 2766d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mChannelMask = desc->mChannelMask; 2767d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mLatency = desc->mLatency; 2768d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addOutput(duplicatedOutput, dupOutputDesc); 2769d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent applyStreamVolumes(duplicatedOutput, device, 0, true); 2770d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 2771d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkOutputsForDevice() could not open dup output for %d and %d", 2772d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mPrimaryOutput, output); 2773d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 2774d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mOutputs.removeItem(output); 27756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 2776d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent output = 0; 2777d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == 0) { 2782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice() could not open output for device %x", device); 2783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profiles.removeAt(profile_index); 2784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile_index--; 2785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(output); 2787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputsForDevice(): adding output %d", output); 2788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profiles.isEmpty()) { 2792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 2793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 2794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2795d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { // Disconnect 2796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check if one opened output is not needed any more after disconnecting one device 2797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(i); 2799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && 28003a4311c68348f728558e87b5db67d47605783890Eric Laurent !(desc->mProfile->mSupportedDevices.types() & 28013a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.types())) { 2802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i)); 2803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(mOutputs.keyAt(i)); 2804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2806d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Clear any profiles associated with the disconnected device. 2807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 2808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 2810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 2813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 28141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j]; 2815d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSupportedDevices.types() & device) { 2816d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice(): " 2817d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent "clearing direct output profile %zu on module %zu", j, i); 2818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mSamplingRates[0] == 0) { 2819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.clear(); 2820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(0); 2821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.clear(); 2824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 2825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mChannelMasks[0] == 0) { 2827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.clear(); 2828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(0); 2829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 2835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2837d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentstatus_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, 2838d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent audio_policy_dev_state_t state, 2839d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector<audio_io_handle_t>& inputs, 2840d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent const String8 address) 2841d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 28421f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> desc; 2843d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { 2844d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // first list already open inputs that can be routed to this device 2845d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 2846d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 2847d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (desc->mProfile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) { 2848d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index)); 2849d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(mInputs.keyAt(input_index)); 2850d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2851d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2852d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2853d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // then look for input profiles that can be routed to this device 28541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent SortedVector< sp<IOProfile> > profiles; 2855d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++) 2856d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent { 2857d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_idx]->mHandle == 0) { 2858d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 2859d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2860d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t profile_index = 0; 2861d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index < mHwModules[module_idx]->mInputProfiles.size(); 2862d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index++) 2863d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent { 2864d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_idx]->mInputProfiles[profile_index]->mSupportedDevices.types() 2865d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent & (device & ~AUDIO_DEVICE_BIT_IN)) { 2866beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("checkInputsForDevice(): adding profile %zu from module %zu", 2867d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index, module_idx); 2868d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profiles.add(mHwModules[module_idx]->mInputProfiles[profile_index]); 2869d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2870d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2871d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2872d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2873d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profiles.isEmpty() && inputs.isEmpty()) { 2874d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 2875d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return BAD_VALUE; 2876d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2877d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2878d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // open inputs for matching profiles if needed. Direct inputs are also opened to 2879d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 2880d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 2881d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 28821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = profiles[profile_index]; 2883d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // nothing to do if one input is already opened for this profile 2884d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent size_t input_index; 2885d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (input_index = 0; input_index < mInputs.size(); input_index++) { 2886d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 2887d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (desc->mProfile == profile) { 2888d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent break; 2889d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2890d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2891d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input_index != mInputs.size()) { 2892d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 2893d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2894d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2895d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("opening input for device 0x%X with params %s", device, address.string()); 2896d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = new AudioInputDescriptor(profile); 2897d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc->mDevice = device; 2898d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2899d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle, 2900d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mDevice, 2901d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mSamplingRate, 2902d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent &desc->mFormat, 2903ec40d284218466d8f0e832e7eb88e6ea6c479c88Glenn Kasten &desc->mChannelMask, 2904ec40d284218466d8f0e832e7eb88e6ea6c479c88Glenn Kasten AUDIO_INPUT_FLAG_FAST /*FIXME*/); 2905d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2906d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input != 0) { 2907d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (!address.isEmpty()) { 2908d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->setParameters(input, addressToParameter(device, address)); 2909d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2910d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2911d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where we step through and resolve any "dynamic" fields 2912d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 reply; 2913d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char *value; 2914d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 2915d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 2916d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 2917d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup sampling rates %s", 2918d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2919d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2920d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 29211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadSamplingRates(value + 1); 2922d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2923d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2924d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2925d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 2926d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 2927d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string()); 2928d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2929d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 29301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadFormats(value + 1); 2931d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2932d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2933d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 2934d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 2935d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 2936d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup channel masks %s", 2937d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 2938d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 2939d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 29401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadInChannels(value + 1); 2941d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2942d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2943d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) || 2944d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) || 2945d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) { 2946d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice() direct input missing param"); 2947d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeInput(input); 2948d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent input = 0; 2949d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2950d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2951d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input != 0) { 2952d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addInput(input, desc); 2953d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2954d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // endif input != 0 2955d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2956d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input == 0) { 2957d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice() could not open input for device 0x%X", device); 2958d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profiles.removeAt(profile_index); 2959d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index--; 2960d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 2961d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(input); 2962d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding input %d", input); 2963d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2964d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end scan profiles 2965d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2966d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profiles.isEmpty()) { 2967d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 2968d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return BAD_VALUE; 2969d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2970d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 2971d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Disconnect 2972d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // check if one opened input is not needed any more after disconnecting one device 2973d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 2974d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 2975d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types())) { 2976d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): disconnecting adding input %d", 2977d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mInputs.keyAt(input_index)); 2978d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(mInputs.keyAt(input_index)); 2979d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2980d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2981d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Clear any profiles associated with the disconnected device. 2982d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) { 2983d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_index]->mHandle == 0) { 2984d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 2985d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2986d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t profile_index = 0; 2987d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index < mHwModules[module_index]->mInputProfiles.size(); 2988d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index++) { 29891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index]; 2990d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSupportedDevices.types() & device) { 2991beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu", 2992d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index, module_index); 2993d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 2994d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mSamplingRates.clear(); 2995d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mSamplingRates.add(0); 2996d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 2997d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 2998d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mFormats.clear(); 2999d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 3000d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3001d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 3002d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mChannelMasks.clear(); 3003d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mChannelMasks.add(0); 3004d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3005d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3006d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3007d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3008d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end disconnect 3009d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3010d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return NO_ERROR; 3011d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 3012d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3013d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3014e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::closeOutput(audio_io_handle_t output) 3015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("closeOutput(%d)", output); 3017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30181f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 3019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc == NULL) { 3020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("closeOutput() unknown output %d", output); 3021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 3022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // look for duplicated outputs connected to the output being removed. 3025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 30261f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i); 3027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dupOutputDesc->isDuplicated() && 3028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (dupOutputDesc->mOutput1 == outputDesc || 3029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent dupOutputDesc->mOutput2 == outputDesc)) { 30301f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc2; 3031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dupOutputDesc->mOutput1 == outputDesc) { 3032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc2 = dupOutputDesc->mOutput2; 3033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc2 = dupOutputDesc->mOutput1; 3035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // As all active tracks on duplicated output will be deleted, 3037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and as they were also referenced on the other output, the reference 3038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // count for their stream type must be adjusted accordingly on 3039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the other output. 30403b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int j = 0; j < AUDIO_STREAM_CNT; j++) { 3041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int refCount = dupOutputDesc->mRefCount[j]; 30423b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount); 3043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i); 3045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); 3046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(duplicatedOutput); 3048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(duplicatedOutput); 3049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param; 3053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.add(String8("closing"), String8("true")); 3054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(output, param.toString()); 3055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 3057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(output); 3058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 30596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 3060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3062e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device, 30631f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > openOutputs) 3064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> outputs; 3066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getOutputsForDevice() device %04x", device); 3068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < openOutputs.size(); i++) { 3069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("output %d isDuplicated=%d device=%04x", 3070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices()); 3071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) { 3072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i)); 3073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(openOutputs.keyAt(i)); 3074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs; 3077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3079e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, 3080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t>& outputs2) 3081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs1.size() != outputs2.size()) { 3083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs1.size(); i++) { 3086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs1[i] != outputs2[i]) { 3087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3093e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy) 3094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); 3096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); 3097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs); 3098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); 3099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!vectorsEqual(srcOutputs,dstOutputs)) { 3101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", 3102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent strategy, srcOutputs[0], dstOutputs[0]); 3103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute strategy while moving tracks from one output to another 3104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < srcOutputs.size(); i++) { 31051f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]); 3106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->isStrategyActive(strategy)) { 3107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(strategy, true, srcOutputs[i]); 3108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); 3109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Move effects associated to this strategy from previous output to new output 3113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strategy == STRATEGY_MEDIA) { 3114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs); 3115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> moved; 3116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 31171f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = mEffects.valueAt(i); 31181f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (effectDesc->mSession == AUDIO_SESSION_OUTPUT_MIX && 31191f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mIo != fxOutput) { 31201f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (moved.indexOf(effectDesc->mIo) < 0) { 3121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputForStrategy() moving effect %d to output %d", 3122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.keyAt(i), fxOutput); 31231f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo, 3124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent fxOutput); 31251f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent moved.add(effectDesc->mIo); 3126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 31271f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mIo = fxOutput; 3128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Move tracks associated to this strategy from previous output to new output 31323b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 31333b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (getStrategy((audio_stream_type_t)i) == strategy) { 31343b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->invalidateStream((audio_stream_type_t)i); 3135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3140e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForAllStrategies() 3141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 3143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_PHONE); 3144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION); 3145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 3146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_MEDIA); 3147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_DTMF); 3148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3150e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getA2dpOutput() 3151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 31531f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); 3154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 3155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutputs.keyAt(i); 3156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 3160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3162e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkA2dpSuspend() 3163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t a2dpOutput = getA2dpOutput(); 3165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (a2dpOutput == 0) { 31663a4311c68348f728558e87b5db67d47605783890Eric Laurent mA2dpSuspended = false; 3167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 3168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 31703a4311c68348f728558e87b5db67d47605783890Eric Laurent bool isScoConnected = 31713a4311c68348f728558e87b5db67d47605783890Eric Laurent (mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) != 0; 3172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // suspend A2DP output if: 3173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (NOT already suspended) && 3174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ((SCO device is connected && 3175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (forced usage for communication || for record is SCO))) || 3176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (phone state is ringing || in call) 3177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // restore A2DP output if: 3179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (Already suspended) && 3180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ((SCO device is NOT connected || 3181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (forced usage NOT for communication && NOT for record is SCO))) && 3182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (phone state is NOT ringing && NOT in call) 3183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mA2dpSuspended) { 31853a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((!isScoConnected || 31863b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO) && 31873b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] != AUDIO_POLICY_FORCE_BT_SCO))) && 31883b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mPhoneState != AUDIO_MODE_IN_CALL) && 31893b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mPhoneState != AUDIO_MODE_RINGTONE))) { 3190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->restoreOutput(a2dpOutput); 3192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mA2dpSuspended = false; 3193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 31953a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((isScoConnected && 31963b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) || 31973b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO))) || 31983b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mPhoneState == AUDIO_MODE_IN_CALL) || 31993b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mPhoneState == AUDIO_MODE_RINGTONE))) { 3200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->suspendOutput(a2dpOutput); 3202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mA2dpSuspended = true; 3203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 32071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentaudio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, bool fromCache) 3208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = AUDIO_DEVICE_NONE; 3210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 32111f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 32126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 32136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); 32146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 32156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 32166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached) { 32176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("getNewOutputDevice() device %08x forced by patch %d", 32186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent outputDesc->device(), outputDesc->mPatchHandle); 32196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return outputDesc->device(); 32206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 32216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 32226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 3223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check the following by order of priority to request a routing change if necessary: 3224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: the strategy enforced audible is active on the output: 3225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy enforced audible 3226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: we are in call or the strategy phone is active on the output: 3227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy phone 3228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the strategy sonification is active on the output: 3229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy sonification 3230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 4: the strategy "respectful" sonification is active on the output: 3231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy "respectful" sonification 3232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 5: the strategy media is active on the output: 3233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy media 3234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 6: the strategy DTMF is active on the output: 3235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy DTMF 3236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { 3237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 3238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isInCall() || 3239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->isStrategyActive(STRATEGY_PHONE)) { 3240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 3241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) { 3242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 3243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { 3244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); 3245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { 3246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 3247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { 3248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 3249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 32511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("getNewOutputDevice() selected device %x", device); 32521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return device; 32531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 32541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 32551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentaudio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input) 32561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 32571f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); 32586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 32596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 32606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 32616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 32626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached) { 32636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("getNewInputDevice() device %08x forced by patch %d", 32646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent inputDesc->mDevice, inputDesc->mPatchHandle); 32656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return inputDesc->mDevice; 32666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 32676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 32686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 32691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t device = getDeviceForInputSource(inputDesc->mInputSource); 32701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 32711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("getNewInputDevice() selected device %x", device); 3272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 3273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3275e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) { 3276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (uint32_t)getStrategy(stream); 3277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3279e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) { 3280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // By checking the range of stream before calling getStrategy, we avoid 3281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 3282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and then return STRATEGY_MEDIA, but we want to return the empty set. 32833b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_CNT) { 32846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return AUDIO_DEVICE_NONE; 32856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 32866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_devices_t devices; 32876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent AudioPolicyManager::routing_strategy strategy = getStrategy(stream); 32886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent devices = getDeviceForStrategy(strategy, true /*fromCache*/); 32896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs); 32906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 32911f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); 32926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc->isStrategyActive(strategy)) { 32936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent devices = outputDesc->device(); 32946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 32956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 3296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return devices; 3298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3300e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy( 33013b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream) { 3302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // stream to strategy mapping 3303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (stream) { 33043b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_VOICE_CALL: 33053b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_BLUETOOTH_SCO: 3306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_PHONE; 33073b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_RING: 33083b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_ALARM: 3309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_SONIFICATION; 33103b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_NOTIFICATION: 3311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_SONIFICATION_RESPECTFUL; 33123b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_DTMF: 3313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_DTMF; 3314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 3315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("unknown stream type"); 33163b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_SYSTEM: 3317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 3318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while key clicks are played produces a poor result 33193b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_TTS: 33203b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_MUSIC: 3321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_MEDIA; 33223b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_ENFORCED_AUDIBLE: 3323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 3324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 33275bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviuint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) { 33285bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // flags to strategy mapping 33295bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { 33305bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_ENFORCED_AUDIBLE; 33315bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 33325bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 33335bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // usage to strategy mapping 33345bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi switch (attr->usage) { 33355bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_MEDIA: 33365bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_GAME: 33375bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: 33385bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 33395bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_SONIFICATION: 33405bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_MEDIA; 33415bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 33425bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION: 33435bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_PHONE; 33445bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 33455bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: 33465bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_DTMF; 33475bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 33485bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ALARM: 33495bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: 33505bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_SONIFICATION; 33515bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 33525bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION: 33535bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: 33545bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: 33555bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: 33565bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_EVENT: 33575bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_SONIFICATION_RESPECTFUL; 33585bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 33595bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_UNKNOWN: 33605bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi default: 33615bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_MEDIA; 33625bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 33635bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi} 33645bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 3365e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) { 3366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(stream) { 33673b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_MUSIC: 3368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 3369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 3370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 3372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3376e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, 3377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool fromCache) 3378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 3380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (fromCache) { 3382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x", 3383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent strategy, mDeviceForStrategy[strategy]); 3384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mDeviceForStrategy[strategy]; 3385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 33863a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types(); 3387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (strategy) { 3388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_SONIFICATION_RESPECTFUL: 3390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 3391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 33923b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC, 3393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 3394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while media is playing on a remote device, use the the sonification behavior. 3395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Note that we test this usecase before testing if media is playing because 3396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the isStreamActive() method only informs about the activity of a stream, not 3397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if it's for local playback. Note also that we use the same delay between both tests 3398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 33993b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 3400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while media is playing (or has recently played), use the same device 3401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 3402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when media is not playing anymore, fall back on the sonification behavior 3404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 3405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_DTMF: 3410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isInCall()) { 3411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when off call, DTMF strategy follows the same rules as MEDIA strategy 3412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 3413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when in call, DTMF and PHONE strategies follow the same rules 3416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 3417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_PHONE: 3419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // for phone strategy, we first consider the forced use and then the available devices by order 3420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // of priority 34213b73df74357b33869b39a1d69427673c780bd805Eric Laurent switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) { 34223b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_BT_SCO: 3423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isInCall() || strategy != STRATEGY_DTMF) { 34243a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 3425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 3426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 34273a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 3428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34293a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; 3430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 3431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if SCO device is requested but no SCO device is available, fall back to default case 3432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 3433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: // FORCE_NONE 3435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 34363a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!isInCall() && 34373b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 3438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 34393a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 3440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34413a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 3442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 3443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 34443a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 3445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34463a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET; 3447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34483b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mPhoneState != AUDIO_MODE_IN_CALL) { 34493a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 3450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34513a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 3452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34533a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 3454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34553a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 3456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34573a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 3458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 3459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 34603a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE; 3461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 3463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); 3465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 34683b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_SPEAKER: 3469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 3470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // A2DP speaker when forcing to speaker output 34713a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!isInCall() && 34723b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 3473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 34743a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 3475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 3476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 34773b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mPhoneState != AUDIO_MODE_IN_CALL) { 34783a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 3479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34803a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 3481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34823a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 3483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34843a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 3485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34863a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 3487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 3488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 34893a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 3490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 34911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 3492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); 3494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_SONIFICATION: 3500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 3502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handleIncallSonification(). 3503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 3504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); 3505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 3508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 3510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 3511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // except: 3512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - when in call where it doesn't default to STRATEGY_PHONE behavior 3513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - in countries where not enforced in which case it follows STRATEGY_MEDIA 3514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((strategy == STRATEGY_SONIFICATION) || 35163b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) { 35173a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 3518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); 3520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The second device used for sonification is the same as the device used by media strategy 3523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 3524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_MEDIA: { 3526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device2 = AUDIO_DEVICE_NONE; 3527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strategy != STRATEGY_SONIFICATION) { 3528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no sonification on remote submix (e.g. WFD) 35293a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; 3530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 35323b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 3533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 35343a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 3535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 35363a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 3537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 35393a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 3540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 35433a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 3544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 35463a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET; 3547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 35493a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 3550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 35523a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 3553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 35553a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 3556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { 3558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no sonification on aux digital (e.g. HDMI) 35593a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 3560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 35623b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) { 35633a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 3564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 35663a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 3567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3568839e4f33906b650140b578d42d6a51300f26703cJungshik Jang int device3 = AUDIO_DEVICE_NONE; 3569839e4f33906b650140b578d42d6a51300f26703cJungshik Jang if (strategy == STRATEGY_MEDIA) { 35707b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang // ARC, SPDIF and AUX_LINE can co-exist with others. 35710c94309d3c6db555b57f2e2e2dc3a0a2676ac6b7Jungshik Jang device3 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_HDMI_ARC; 35720c94309d3c6db555b57f2e2e2dc3a0a2676ac6b7Jungshik Jang device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPDIF); 35737b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_LINE); 3574839e4f33906b650140b578d42d6a51300f26703cJungshik Jang } 3575839e4f33906b650140b578d42d6a51300f26703cJungshik Jang 3576839e4f33906b650140b578d42d6a51300f26703cJungshik Jang device2 |= device3; 3577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 3578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise 3579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device |= device2; 3580839e4f33906b650140b578d42d6a51300f26703cJungshik Jang 35817b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang // If hdmi system audio mode is on, remove speaker out of output list. 35827b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang if ((strategy == STRATEGY_MEDIA) && 35837b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] == 35847b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) { 35857b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang device &= ~AUDIO_DEVICE_OUT_SPEAKER; 35867b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang } 35877b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang 3588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 35891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 3590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 3591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); 3592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } break; 3594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 3596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 3597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 3601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 3602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3604e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::updateDevicesAndOutputs() 3605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_STRATEGIES; i++) { 3607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 3608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 3610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 36121f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentuint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc, 3613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t prevDevice, 3614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t delayMs) 3615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute/unmute strategies using an incompatible device combination 3617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if muting, wait for the audio in pcm buffer to be drained before proceeding 3618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if unmuting, unmute only after the specified delay 3619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isDuplicated()) { 3620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 3621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs = 0; 3624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = outputDesc->device(); 36253b73df74357b33869b39a1d69427673c780bd805Eric Laurent bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2); 3626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 3628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 3629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool mute = shouldMute && (curDevice & device) && (curDevice != device); 3630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool doMute = false; 3631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mute && !outputDesc->mStrategyMutedByDevice[i]) { 3633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent doMute = true; 3634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = true; 3635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){ 3636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent doMute = true; 3637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = false; 3638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 363999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (doMute) { 3640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mOutputs.size(); j++) { 36411f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j); 3642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // skip output if it does not share any device with current output 3643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->supportedDevices() & outputDesc->supportedDevices()) 3644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent == AUDIO_DEVICE_NONE) { 3645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 3646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(j); 3648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", 3649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mute ? "muting" : "unmuting", i, curDevice, curOutput); 3650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); 3651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->isStrategyActive((routing_strategy)i)) { 365299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (mute) { 365399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // FIXME: should not need to double latency if volume could be applied 365499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // immediately by the audioflinger mixer. We must account for the delay 365599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // between now and the next time the audioflinger thread for this output 365699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // will process a buffer (which corresponds to one buffer size, 365799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // usually 1/2 or 1/4 of the latency). 365899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (muteWaitMs < desc->latency() * 2) { 365999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs = desc->latency() * 2; 3660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 366799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // temporary mute output if device selection changes to avoid volume bursts due to 366899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // different per device volumes 366999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (outputDesc->isActive() && (device != prevDevice)) { 367099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (muteWaitMs < outputDesc->latency() * 2) { 367199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs = outputDesc->latency() * 2; 367299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 367399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 367499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (outputDesc->isStrategyActive((routing_strategy)i)) { 36751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setStrategyMute((routing_strategy)i, true, outputDesc->mIoHandle); 367699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // do tempMute unmute after twice the mute wait time 36771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setStrategyMute((routing_strategy)i, false, outputDesc->mIoHandle, 367899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs *2, device); 367999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 368099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 368199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 368299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent 3683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // wait for the PCM output buffers to empty before proceeding with the rest of the command 3684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (muteWaitMs > delayMs) { 3685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs -= delayMs; 3686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent usleep(muteWaitMs * 1000); 3687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 3688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 3690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3692e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output, 3693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 3694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force, 36956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent int delayMs, 36966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *patchHandle) 3697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); 36991f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 3700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param; 3701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs; 3702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isDuplicated()) { 37041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent muteWaitMs = setOutputDevice(outputDesc->mOutput1->mIoHandle, device, force, delayMs); 37051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent muteWaitMs += setOutputDevice(outputDesc->mOutput2->mIoHandle, device, force, delayMs); 3706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 3707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current 3709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // output profile 3710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device != AUDIO_DEVICE_NONE) && 37113a4311c68348f728558e87b5db67d47605783890Eric Laurent ((device & outputDesc->mProfile->mSupportedDevices.types()) == 0)) { 3712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 3713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // filter devices according to output selected 37163a4311c68348f728558e87b5db67d47605783890Eric Laurent device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices.types()); 3717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t prevDevice = outputDesc->mDevice; 3719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() prevDevice %04x", prevDevice); 3721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device != AUDIO_DEVICE_NONE) { 3723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = device; 3724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); 3726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not change the routing if: 3728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the requested device is AUDIO_DEVICE_NONE 3729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the requested device is the same as current device and force is not specified. 3730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Doing this check here allows the caller to call setOutputDevice() without conditions 3731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) { 3732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); 3733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 3734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() changing device"); 37371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 3738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do the routing 37391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (device == AUDIO_DEVICE_NONE) { 37406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent resetOutputDevice(output, delayMs, NULL); 37411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 37421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent DeviceVector deviceList = mAvailableOutputDevices.getDevicesFromType(device); 37431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (!deviceList.isEmpty()) { 37441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_patch patch; 37451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->toAudioPortConfig(&patch.sources[0]); 37461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sources = 1; 37471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks = 0; 37481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) { 37491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]); 37501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks++; 37511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 37526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 37536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) { 37546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 37556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 37566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); 37576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 37586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc; 37596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 37606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 37616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 37626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent afPatchHandle = patchDesc->mAfPatchHandle; 37636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 37646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 37651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = mpClientInterface->createAudioPatch(&patch, 37666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &afPatchHandle, 37676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent delayMs); 37681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d" 37691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent "num_sources %d num_sinks %d", 37706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, afPatchHandle, patch.num_sources, patch.num_sinks); 37711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (status == NO_ERROR) { 37726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 37736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 37746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &patch, mUidCached); 37756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent addAudioPatch(patchDesc->mHandle, patchDesc); 37766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 37776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch = patch; 37786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 37796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mAfPatchHandle = afPatchHandle; 37806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = mUidCached; 37816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 37826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *patchHandle = patchDesc->mHandle; 37836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 37846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent outputDesc->mPatchHandle = patchDesc->mHandle; 37856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 3786b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 37871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 37881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 37891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 3790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update stream volumes according to new device 3792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent applyStreamVolumes(output, device, delayMs); 3793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 3795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 37971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output, 37986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent int delayMs, 37996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *patchHandle) 38001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 38011f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 38026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 38036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 38046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 38056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 38066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); 38076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 38086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 38091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return INVALID_OPERATION; 38101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 38116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index); 38126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, delayMs); 38131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status); 38141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mPatchHandle = 0; 38156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent removeAudioPatch(patchDesc->mHandle); 38166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 3817b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 38181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 38191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 38201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 38211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::setInputDevice(audio_io_handle_t input, 38221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t device, 38236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent bool force, 38246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *patchHandle) 38251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 38261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 38271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 38281f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); 38291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) { 38301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mDevice = device; 38311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 38321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device); 38331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (!deviceList.isEmpty()) { 38341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_patch patch; 38351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->toAudioPortConfig(&patch.sinks[0]); 38361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks = 1; 38371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent //only one input device for now 38381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]); 38391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sources = 1; 38406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 38416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) { 38426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 38436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 38446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 38456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 38466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc; 38476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 38486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 38496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 38506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent afPatchHandle = patchDesc->mAfPatchHandle; 38516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 38526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 38531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = mpClientInterface->createAudioPatch(&patch, 38546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &afPatchHandle, 38551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 0); 38561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d", 38576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, afPatchHandle); 38581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (status == NO_ERROR) { 38596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 38606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 38616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &patch, mUidCached); 38626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent addAudioPatch(patchDesc->mHandle, patchDesc); 38636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 38646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch = patch; 38656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 38666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mAfPatchHandle = afPatchHandle; 38676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = mUidCached; 38686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 38696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *patchHandle = patchDesc->mHandle; 38706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 38716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent inputDesc->mPatchHandle = patchDesc->mHandle; 38726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 3873b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 38741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 38751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 38761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 38771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 38781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 38791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 38806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input, 38816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *patchHandle) 38821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 38831f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); 38846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 38856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 38866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 38876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 38886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 38896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 38906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 38911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return INVALID_OPERATION; 38921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 38936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index); 38946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 38951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("resetInputDevice() releaseAudioPatch returned %d", status); 38961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mPatchHandle = 0; 38976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent removeAudioPatch(patchDesc->mHandle); 38986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 3899b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 39001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 39011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 39021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 39031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device, 3904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 3905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 3906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask) 3907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Choose an input profile based on the requested capture parameters: select the first available 3909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // profile supporting all requested parameters. 3910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 3912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 3914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 3915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 3917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 39181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j]; 3919d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // profile->log(); 3920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->isCompatibleProfile(device, samplingRate, format, 3921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, AUDIO_OUTPUT_FLAG_NONE)) { 3922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return profile; 3923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NULL; 3927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3929e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource) 3930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 39323a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & 39333a4311c68348f728558e87b5db67d47605783890Eric Laurent ~AUDIO_DEVICE_BIT_IN; 3934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (inputSource) { 3935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 39363a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { 3937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 3938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 3941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_DEFAULT: 3943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_MIC: 394441b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) { 394541b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP; 394641b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood break; 394741b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood } 394841b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood // FALL THROUGH 394941b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood 3950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_RECOGNITION: 3951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_HOTWORD: 3952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_COMMUNICATION: 39533b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO && 39543a4311c68348f728558e87b5db67d47605783890Eric Laurent availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 3955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 39563a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { 3957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_WIRED_HEADSET; 3958d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { 3959d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent device = AUDIO_DEVICE_IN_USB_DEVICE; 39603a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 3961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 3962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_CAMCORDER: 39653a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) { 3966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BACK_MIC; 39673a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 3968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 3969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_DOWNLINK: 3972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_CALL: 39733a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { 3974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 3975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_REMOTE_SUBMIX: 39783a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { 3979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; 3980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 3983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 3984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 3987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 3988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3990e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device) 3991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & AUDIO_DEVICE_BIT_IN) != 0) { 3993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device &= ~AUDIO_DEVICE_BIT_IN; 3994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) 3995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4000e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs) 4001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 40031f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioInputDescriptor> input_descriptor = mInputs.valueAt(i); 4004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((input_descriptor->mRefCount > 0) 4005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) { 4006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mInputs.keyAt(i); 4007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 4010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4013e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device) 4014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this happens when forcing a route update and no track is active on an output. 4017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // In this case the returned category is not important. 4018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 40193b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (popcount(device) > 1) { 4020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Multiple device selection is either: 4021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - speaker + one other device: give priority to speaker in this case. 4022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 4023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 4024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // selection if not the speaker. 4025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 4026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 4027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 4029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 40323b73df74357b33869b39a1d69427673c780bd805Eric Laurent ALOGW_IF(popcount(device) != 1, 4033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 4034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device); 4035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 4037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4039e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device) 4040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(getDeviceForVolume(device)) { 4042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 4043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_EARPIECE; 4044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 4045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 4046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 4047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 4048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 4049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 4050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_HEADSET; 4051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 4052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 4053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 4054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_AUX_DIGITAL: 4055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_USB_ACCESSORY: 4056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_USB_DEVICE: 4057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_REMOTE_SUBMIX: 4058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 4059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_SPEAKER; 4060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4063e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, 4064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexInUi) 4065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device_category deviceCategory = getDeviceCategory(device); 4067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 4068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the volume index in the UI is relative to the min and max volume indices for this stream type 4070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 4071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[VOLMIN].mIndex; 4072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 4073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (streamDesc.mIndexMax - streamDesc.mIndexMin); 4074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // find what part of the curve this index volume belongs to, or if it's out of bounds 4076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int segment = 0; 4077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 4078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0.0f; 4079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 4080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 0; 4081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 4082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 1; 4083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 4084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 2; 4085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { // out of bounds 4086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 1.0f; 4087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // linear interpolation in the attenuation table in dB 4090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float decibels = curve[segment].mDBAttenuation + 4091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 4092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ( (curve[segment+1].mDBAttenuation - 4093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mDBAttenuation) / 4094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((float)(curve[segment+1].mIndex - 4095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mIndex)) ); 4096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 4098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 4100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mIndex, volIdx, 4101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment+1].mIndex, 4102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mDBAttenuation, 4103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent decibels, 4104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment+1].mDBAttenuation, 4105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent amplification); 4106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return amplification; 4108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4110e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4111e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultVolumeCurve[AudioPolicyManager::VOLCNT] = { 4112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 4113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4115e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4116e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { 4117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 4118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4120e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4121e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { 4122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 4123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4125e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4126ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi AudioPolicyManager::sSpeakerMediaVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 412798c6043e089743355bb6686176877f2ba5125213Jean-Michel Trivi {1, -55.0f}, {20, -43.0f}, {86, -12.0f}, {100, 0.0f} 4128ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi}; 4129ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi 4130ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Triviconst AudioPolicyManager::VolumeCurvePoint 4131e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = { 4132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 4133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4135e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4136e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 4137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f} 4138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks 4141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets. 4142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java). 4143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset. 4144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4145e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4146e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 4147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f} 4148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4150e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4151e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 4152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f} 4153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4155e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4156e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 4157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f} 4158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4160e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4161e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { 4162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f} 4163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4165e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4166e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { 4167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f} 4168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4170e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4171e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT] 4172e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent [AudioPolicyManager::DEVICE_CATEGORY_CNT] = { 4173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_VOICE_CALL 4174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 4175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 4177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_SYSTEM 4179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 4180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 4182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_RING 4184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 4185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 4187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_MUSIC 4189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 4190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 4192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_ALARM 4194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 4195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 4197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_NOTIFICATION 4199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 4200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE 4202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_BLUETOOTH_SCO 4204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 4205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE 4207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_ENFORCED_AUDIBLE 4209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 4210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 4212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_DTMF 4214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 4215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE 4217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_TTS 4219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 4220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE 4222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4225e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initializeVolumeCurves() 4226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 4228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 4229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[i].mVolumeCurve[j] = 4230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[i][j]; 4231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check availability of DRC on speaker path: if available, override some of the speaker curves 4235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mSpeakerDrcEnabled) { 4236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 4237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurveDrc; 4238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 4239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 4240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 4241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 4242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 4243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 4244ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi mStreams[AUDIO_STREAM_MUSIC].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 4245ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi sSpeakerMediaVolumeCurveDrc; 4246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4249e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::computeVolume(audio_stream_type_t stream, 4250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 4251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 4252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 4253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float volume = 1.0; 42551f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 4256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent StreamDescriptor &streamDesc = mStreams[stream]; 4257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = outputDesc->device(); 4260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if volume is not 0 (not muted), force media volume to max on digital output 42633b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_MUSIC && 4264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent index != mStreams[stream].mIndexMin && 4265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (device == AUDIO_DEVICE_OUT_AUX_DIGITAL || 4266b919dd3334fed73e16ebac7b7e10cf2add34c338Paul McLean device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) { 4267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 1.0; 4268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume = volIndexToAmpl(device, streamDesc, index); 4271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if a headset is connected, apply the following rules to ring tones and notifications 4273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // to avoid sound level bursts in user's ears: 4274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - always attenuate ring tones and notifications volume by 6dB 4275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - if music is playing, always limit the volume to current music volume, 4276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // with a minimum threshold at -36dB so that notification is always perceived. 42773b73df74357b33869b39a1d69427673c780bd805Eric Laurent const routing_strategy stream_strategy = getStrategy(stream); 4278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | 4279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 4280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADSET | 4281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) && 4282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((stream_strategy == STRATEGY_SONIFICATION) 4283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) 42843b73df74357b33869b39a1d69427673c780bd805Eric Laurent || (stream == AUDIO_STREAM_SYSTEM) 4285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) && 42863b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) && 4287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent streamDesc.mCanBeMuted) { 4288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 4289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when the phone is ringing we must consider that music could have been paused just before 4290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by the music application and behave as if music was active if the last music track was 4291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // just stopped 42923b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || 4293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume) { 4294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/); 42953b73df74357b33869b39a1d69427673c780bd805Eric Laurent float musicVol = computeVolume(AUDIO_STREAM_MUSIC, 42963b73df74357b33869b39a1d69427673c780bd805Eric Laurent mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice), 4297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 4298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent musicDevice); 4299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 4300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 4301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volume > minVol) { 4302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume = minVol; 4303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 4304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return volume; 4309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4311e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream, 4312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 4313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 4314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 4315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 4316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force) 4317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not change actual stream volume if the stream is muted 4320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 4321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkAndSetVolume() stream %d muted count %d", 4322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, mOutputs.valueFor(output)->mMuteCount[stream]); 4323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not change in call volume if bluetooth is connected and vice versa 43273b73df74357b33869b39a1d69427673c780bd805Eric Laurent if ((stream == AUDIO_STREAM_VOICE_CALL && 43283b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) || 43293b73df74357b33869b39a1d69427673c780bd805Eric Laurent (stream == AUDIO_STREAM_BLUETOOTH_SCO && 43303b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO)) { 4331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 43323b73df74357b33869b39a1d69427673c780bd805Eric Laurent stream, mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]); 4333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 4334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float volume = computeVolume(stream, index, output, device); 4337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // We actually change the volume if: 4338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the float value returned by computeVolume() changed 4339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the force flag is set 4340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 4341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force) { 4342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.valueFor(output)->mCurVolume[stream] = volume; 4343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 4344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 4345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // enabled 43463b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_BLUETOOTH_SCO) { 43473b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs); 4348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 43493b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->setStreamVolume(stream, volume, output, delayMs); 4350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43523b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_VOICE_CALL || 43533b73df74357b33869b39a1d69427673c780bd805Eric Laurent stream == AUDIO_STREAM_BLUETOOTH_SCO) { 4354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float voiceVolume; 4355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force voice volume to max for bluetooth SCO as volume is managed by the headset 43563b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_VOICE_CALL) { 4357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 4358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent voiceVolume = 1.0; 4360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { 4363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 4364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLastVoiceVolume = voiceVolume; 4365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4371e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output, 4372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 4373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 4374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force) 4375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("applyStreamVolumes() for output %d and device %x", output, device); 4377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43783b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 43793b73df74357b33869b39a1d69427673c780bd805Eric Laurent checkAndSetVolume((audio_stream_type_t)stream, 4380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].getVolumeIndex(device), 4381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 4382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, 4383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs, 4384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force); 4385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4388e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStrategyMute(routing_strategy strategy, 4389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool on, 4390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 4391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 4392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 4393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 43953b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 43963b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (getStrategy((audio_stream_type_t)stream) == strategy) { 43973b73df74357b33869b39a1d69427673c780bd805Eric Laurent setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device); 4398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4402e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStreamMute(audio_stream_type_t stream, 4403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool on, 4404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 4405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 4406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 4407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent StreamDescriptor &streamDesc = mStreams[stream]; 44091f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 4410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = outputDesc->device(); 4412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x", 4415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, on, output, outputDesc->mMuteCount[stream], device); 4416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (on) { 4418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mMuteCount[stream] == 0) { 4419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (streamDesc.mCanBeMuted && 44203b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) || 44213b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) { 4422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 4423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 4426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mMuteCount[stream]++; 4427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mMuteCount[stream] == 0) { 4429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setStreamMute() unmuting non muted stream!"); 4430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (--outputDesc->mMuteCount[stream] == 0) { 4433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 4434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent streamDesc.getVolumeIndex(device), 4435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 4436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, 4437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs); 4438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4442e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream, 44433b73df74357b33869b39a1d69427673c780bd805Eric Laurent bool starting, bool stateChange) 4444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if the stream pertains to sonification strategy and we are in call we must 4446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute the stream if it is low visibility. If it is high visibility, we must play a tone 4447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the device used for phone strategy and play the tone if the selected device does not 4448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // interfere with the device used for phone strategy 4449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 4450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // many times as there are active tracks on the output 44513b73df74357b33869b39a1d69427673c780bd805Eric Laurent const routing_strategy stream_strategy = getStrategy(stream); 4452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((stream_strategy == STRATEGY_SONIFICATION) || 4453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { 44541f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput); 4455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 4456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, starting, outputDesc->mDevice, stateChange); 4457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream]) { 4458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int muteCount = 1; 4459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (stateChange) { 4460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteCount = outputDesc->mRefCount[stream]; 4461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 44623b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (audio_is_low_visibility(stream)) { 4463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 4464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < muteCount; i++) { 4465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 4466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() high visibility"); 4469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->device() & 4470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) { 4471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 4472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < muteCount; i++) { 4473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 4474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (starting) { 44773b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION, 44783b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_STREAM_VOICE_CALL); 4479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->stopTone(); 4481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4487e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isInCall() 4488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return isStateInCall(mPhoneState); 4490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4492e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStateInCall(int state) { 44933b73df74357b33869b39a1d69427673c780bd805Eric Laurent return ((state == AUDIO_MODE_IN_CALL) || 44943b73df74357b33869b39a1d69427673c780bd805Eric Laurent (state == AUDIO_MODE_IN_COMMUNICATION)); 4495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4497e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsCpuLoad() 4498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return MAX_EFFECTS_CPU_LOAD; 4500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4502e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsMemory() 4503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return MAX_EFFECTS_MEMORY; 4505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 45076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 4508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioOutputDescriptor class implementation 4509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4510e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor( 45111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile>& profile) 45121f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent : mId(0), mIoHandle(0), mLatency(0), 45131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), 4514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0) 4515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // clear usage count for all stream types 45173b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 4518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[i] = 0; 4519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurVolume[i] = -1.0; 4520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mMuteCount[i] = 0; 4521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStopTime[i] = 0; 4522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_STRATEGIES; i++) { 4524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStrategyMutedByDevice[i] = false; 4525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile != NULL) { 45271f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mAudioPort = profile; 45281e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mSamplingRate = profile->pickSamplingRate(); 45291e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mFormat = profile->pickFormat(); 45301e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mChannelMask = profile->pickChannelMask(); 4531a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (profile->mGains.size() > 0) { 4532a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent profile->mGains[0]->getDefaultConfig(&mGain); 4533a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 4534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mFlags = profile->mFlags; 4535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4538e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::device() const 4539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 4541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 4542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mDevice; 4544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4547e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::AudioOutputDescriptor::latency() 4548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 4550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 4551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mLatency; 4553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4556e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith( 45571f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioOutputDescriptor> outputDesc) 4558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 4560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 4561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isDuplicated()){ 4562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2); 4563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mProfile->mModule == outputDesc->mProfile->mModule); 4565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4568e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 45693b73df74357b33869b39a1d69427673c780bd805Eric Laurent int delta) 4570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // forward usage count change to attached outputs 4572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 4573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput1->changeRefCount(stream, delta); 4574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput2->changeRefCount(stream, delta); 4575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((delta + (int)mRefCount[stream]) < 0) { 45773b73df74357b33869b39a1d69427673c780bd805Eric Laurent ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", 45783b73df74357b33869b39a1d69427673c780bd805Eric Laurent delta, stream, mRefCount[stream]); 4579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[stream] = 0; 4580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[stream] += delta; 4583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 4584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4586e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::supportedDevices() 4587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 4589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 4590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 45913a4311c68348f728558e87b5db67d47605783890Eric Laurent return mProfile->mSupportedDevices.types() ; 4592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4595e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isActive(uint32_t inPastMs) const 4596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return isStrategyActive(NUM_STRATEGIES, inPastMs); 4598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4600e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy, 4601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t inPastMs, 4602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime) const 4603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((sysTime == 0) && (inPastMs != 0)) { 4605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime = systemTime(); 4606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 46073b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 46083b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (((getStrategy((audio_stream_type_t)i) == strategy) || 4609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (NUM_STRATEGIES == strategy)) && 46103b73df74357b33869b39a1d69427673c780bd805Eric Laurent isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) { 4611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 4612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4617e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, 4618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t inPastMs, 4619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime) const 4620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mRefCount[stream] != 0) { 4622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 4623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (inPastMs == 0) { 4625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (sysTime == 0) { 4628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime = systemTime(); 4629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 4631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 4632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 46361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::toAudioPortConfig( 46376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port_config *dstConfig, 46386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const struct audio_port_config *srcConfig) const 46396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 464084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle); 464184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent 46426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 46431f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 46446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (srcConfig != NULL) { 464584c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent dstConfig->config_mask |= srcConfig->config_mask; 46466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 46471f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 46481f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 46491f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->id = mId; 46501f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->role = AUDIO_PORT_ROLE_SOURCE; 46511f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->type = AUDIO_PORT_TYPE_MIX; 46526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle; 46536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.mix.handle = mIoHandle; 46546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 46551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 46561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 46571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::toAudioPort( 46581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_port *port) const 46591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 466084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle); 46611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mProfile->toAudioPort(port); 46621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 46636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent toAudioPortConfig(&port->active_config); 46646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent port->ext.mix.hw_module = mProfile->mModule->mHandle; 46651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.handle = mIoHandle; 46661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.latency_class = 46671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL; 46681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 4669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4670e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd) 4671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 4673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 4674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 4675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 4677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 4679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 4681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 4683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 4685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Devices %08x\n", device()); 4687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 4689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 46903b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 46913b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", 46923b73df74357b33869b39a1d69427673c780bd805Eric Laurent i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 4693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 4696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioInputDescriptor class implementation 4701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 47021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile) 47031f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent : mId(0), mIoHandle(0), 47041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mRefCount(0), 47053b73df74357b33869b39a1d69427673c780bd805Eric Laurent mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile) 4706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 47073a4311c68348f728558e87b5db67d47605783890Eric Laurent if (profile != NULL) { 47081f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mAudioPort = profile; 47091e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mSamplingRate = profile->pickSamplingRate(); 47101e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mFormat = profile->pickFormat(); 47111e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mChannelMask = profile->pickChannelMask(); 4712a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (profile->mGains.size() > 0) { 4713a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent profile->mGains[0]->getDefaultConfig(&mGain); 4714a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 47153a4311c68348f728558e87b5db67d47605783890Eric Laurent } 4716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 47181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioInputDescriptor::toAudioPortConfig( 47196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port_config *dstConfig, 47206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const struct audio_port_config *srcConfig) const 47216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 472284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(mProfile != 0, 472384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent "toAudioPortConfig() called on input with null profile %d", mIoHandle); 47246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 47251f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 47266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (srcConfig != NULL) { 472784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent dstConfig->config_mask |= srcConfig->config_mask; 47286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 47291f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 47301f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 47311f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 47321f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->id = mId; 47331f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->role = AUDIO_PORT_ROLE_SINK; 47341f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->type = AUDIO_PORT_TYPE_MIX; 473562aaabb3905c61bb7acd6037414c206240a31c32Eric Laurent dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle; 473662aaabb3905c61bb7acd6037414c206240a31c32Eric Laurent dstConfig->ext.mix.handle = mIoHandle; 473762aaabb3905c61bb7acd6037414c206240a31c32Eric Laurent dstConfig->ext.mix.usecase.source = mInputSource; 47381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 47391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 47401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioInputDescriptor::toAudioPort( 47411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_port *port) const 47421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 474384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle); 474484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent 47451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mProfile->toAudioPort(port); 47461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 47476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent toAudioPortConfig(&port->active_config); 47486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent port->ext.mix.hw_module = mProfile->mModule->mHandle; 47491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.handle = mIoHandle; 47501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL; 47511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 47521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 4753e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioInputDescriptor::dump(int fd) 4754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 4756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 4757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 4758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 4760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Format: %d\n", mFormat); 4762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 4764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 4766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 4768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 4770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- StreamDescriptor class implementation 4775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4776e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::StreamDescriptor::StreamDescriptor() 4777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 4778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 4780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4782e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::StreamDescriptor::getVolumeIndex(audio_devices_t device) 4783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4784e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent device = AudioPolicyManager::getDeviceForVolume(device); 4785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 4786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 4787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 4788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mIndexCur.valueFor(device); 4790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4792e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::StreamDescriptor::dump(int fd) 4793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 4795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 4796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 4797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 4799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 4800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 4802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 4803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.keyAt(i), 4804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.valueAt(i)); 4805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append("\n"); 4808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 4810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- EffectDescriptor class implementation 4813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4814e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::EffectDescriptor::dump(int fd) 4815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 4817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 4818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 4819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 4821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 4823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Session: %d\n", mSession); 4825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 4827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 4829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 4831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 48351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- HwModule class implementation 4836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4837e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::HwModule(const char *name) 4838eb108a4622825688b02d7afc981014d149913cd8Eric Laurent : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), 4839eb108a4622825688b02d7afc981014d149913cd8Eric Laurent mHalVersion(AUDIO_DEVICE_API_VERSION_MIN), mHandle(0) 4840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4843e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::~HwModule() 4844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 48463a4311c68348f728558e87b5db67d47605783890Eric Laurent mOutputProfiles[i]->mSupportedDevices.clear(); 4847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 48493a4311c68348f728558e87b5db67d47605783890Eric Laurent mInputProfiles[i]->mSupportedDevices.clear(); 4850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free((void *)mName); 4852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 48541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::HwModule::loadInput(cnode *root) 48551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 48561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 48571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 48581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SINK, this); 48591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 48601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 48611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 48621afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadSamplingRates((char *)node->value); 48631afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 48641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadFormats((char *)node->value); 48651afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 48661afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadInChannels((char *)node->value); 48671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 48681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.loadDevicesFromName((char *)node->value, 48691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices); 48701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAINS_TAG) == 0) { 48711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadGains(node); 48721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 48731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 48741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 48751afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSupportedDevices.isEmpty(), 48761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported devices"); 48771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 48781afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported channel masks"); 48791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 48801afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported sampling rates"); 48811afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mFormats.size() == 0, 48821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported formats"); 48831afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (!profile->mSupportedDevices.isEmpty() && 48841afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mChannelMasks.size() != 0) && 48851afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mSamplingRates.size() != 0) && 48861afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mFormats.size() != 0)) { 48871afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 48881afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadInput() adding input Supported Devices %04x", 48891afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.types()); 48901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 48911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mInputProfiles.add(profile); 48921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return NO_ERROR; 48931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 48941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return BAD_VALUE; 48951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 48961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 48971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 48981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::HwModule::loadOutput(cnode *root) 48991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 49001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 49011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 49021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SOURCE, this); 49031afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 49041afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 49051afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 49061afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadSamplingRates((char *)node->value); 49071afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 49081afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadFormats((char *)node->value); 49091afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 49101afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadOutChannels((char *)node->value); 49111afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 49121afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.loadDevicesFromName((char *)node->value, 49131afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices); 49141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, FLAGS_TAG) == 0) { 49151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mFlags = parseFlagNames((char *)node->value); 49161afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAINS_TAG) == 0) { 49171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadGains(node); 49181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 49191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 49201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 49211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSupportedDevices.isEmpty(), 49221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported devices"); 49231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 49241afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported channel masks"); 49251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 49261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported sampling rates"); 49271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mFormats.size() == 0, 49281afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported formats"); 49291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (!profile->mSupportedDevices.isEmpty() && 49301afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mChannelMasks.size() != 0) && 49311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mSamplingRates.size() != 0) && 49321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mFormats.size() != 0)) { 49331afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 49341afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x", 49351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.types(), profile->mFlags); 49361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 49371afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mOutputProfiles.add(profile); 49381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return NO_ERROR; 49391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 49401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return BAD_VALUE; 49411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 49421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 49431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 49441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::HwModule::loadDevice(cnode *root) 49451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 49461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 49471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 49481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent audio_devices_t type = AUDIO_DEVICE_NONE; 49491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 49501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, DEVICE_TYPE) == 0) { 49511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent type = parseDeviceNames((char *)node->value); 49521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent break; 49531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 49541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 49551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 49561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (type == AUDIO_DEVICE_NONE || 49571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (!audio_is_input_device(type) && !audio_is_output_device(type))) { 49581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW("loadDevice() bad type %08x", type); 49591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return BAD_VALUE; 49601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 49611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> deviceDesc = new DeviceDescriptor(String8(root->name), type); 49621afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->mModule = this; 49631afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 49641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = root->first_child; 49651afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 49661afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, DEVICE_ADDRESS) == 0) { 49671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->mAddress = String8((char *)node->value); 49681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 49691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (audio_is_input_device(type)) { 49701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->loadInChannels((char *)node->value); 49711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 49721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->loadOutChannels((char *)node->value); 49731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 49741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAINS_TAG) == 0) { 49751afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->loadGains(node); 49761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 49771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 49781afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 49791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 49801afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadDevice() adding device name %s type %08x address %s", 49811afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->mName.string(), type, deviceDesc->mAddress.string()); 49821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 49831afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices.add(deviceDesc); 49841afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 49851afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return NO_ERROR; 49861afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 49871afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 4988e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::HwModule::dump(int fd) 4989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 4991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 4992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 4993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - name: %s\n", mName); 4995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 4997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 4998eb108a4622825688b02d7afc981014d149913cd8Eric Laurent snprintf(buffer, SIZE, " - version: %u.%u\n", mHalVersion >> 8, mHalVersion & 0xFF); 4999eb108a4622825688b02d7afc981014d149913cd8Eric Laurent result.append(buffer); 5000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 5001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mOutputProfiles.size()) { 5002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, " - outputs:\n", strlen(" - outputs:\n")); 5003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 5004d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " output %zu:\n", i); 5005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 5006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputProfiles[i]->dump(fd); 5007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mInputProfiles.size()) { 5010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, " - inputs:\n", strlen(" - inputs:\n")); 5011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 5012d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " input %zu:\n", i); 5013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 5014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputProfiles[i]->dump(fd); 5015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 50171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mDeclaredDevices.size()) { 50181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, " - devices:\n", strlen(" - devices:\n")); 50191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mDeclaredDevices.size(); i++) { 50201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices[i]->dump(fd, 4, i); 50211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 50221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 5023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 50251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- AudioPort class implementation 50261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 5027a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 5028a121f90f388343dc48793cbc7eb899aba42e7664Eric LaurentAudioPolicyManager::AudioPort::AudioPort(const String8& name, audio_port_type_t type, 5029a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audio_port_role_t role, const sp<HwModule>& module) : 50301e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mName(name), mType(type), mRole(role), mModule(module), mFlags((audio_output_flags_t)0) 5031a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 5032a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mUseInChannelMask = ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) || 5033a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK)); 5034a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 5035a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 50361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const 50371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 50381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->role = mRole; 50391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->type = mType; 50401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent unsigned int i; 50411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) { 50421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->sample_rates[i] = mSamplingRates[i]; 50431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 50441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_sample_rates = i; 50451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) { 50461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->channel_masks[i] = mChannelMasks[i]; 50471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 50481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_channel_masks = i; 50491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) { 50501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->formats[i] = mFormats[i]; 50511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 50521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_formats = i; 5053e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 5054beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size()); 5055e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 5056e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) { 5057e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent port->gains[i] = mGains[i]->mGain; 5058e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 5059e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent port->num_gains = i; 50601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 50611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 50621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 50631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadSamplingRates(char *name) 50641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 50651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent char *str = strtok(name, "|"); 50661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 50671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling 50681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // rates should be read from the output stream after it is opened for the first time 50691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 50701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mSamplingRates.add(0); 50711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 50721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 50731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 50741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 50751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent uint32_t rate = atoi(str); 50761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (rate != 0) { 50771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadSamplingRates() adding rate %d", rate); 50781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mSamplingRates.add(rate); 50791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 50801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 50811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 50821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 50831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 50841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadFormats(char *name) 50851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 50861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent char *str = strtok(name, "|"); 50871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 50881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mFormats indicates the supported formats 50891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // should be read from the output stream after it is opened for the first time 50901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 50911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFormats.add(AUDIO_FORMAT_DEFAULT); 50921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 50931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 50941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 50951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 50961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable, 50971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 50981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 50991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (format != AUDIO_FORMAT_DEFAULT) { 51001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFormats.add(format); 51011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 51031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 51051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 51061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadInChannels(char *name) 51071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 51081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const char *str = strtok(name, "|"); 51091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 51101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadInChannels() %s", name); 51111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 51121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 51131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(0); 51141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 51151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 51171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 51181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_channel_mask_t channelMask = 51191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 51201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 51211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 51221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (channelMask != 0) { 51231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadInChannels() adding channelMask %04x", channelMask); 51241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(channelMask); 51251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 51271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 51291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 51301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadOutChannels(char *name) 51311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 51321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const char *str = strtok(name, "|"); 51331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 51341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadOutChannels() %s", name); 51351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 51361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mChannelMasks indicates the supported channel 51371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // masks should be read from the output stream after it is opened for the first time 51381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 51391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(0); 51401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 51411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 51431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 51441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_channel_mask_t channelMask = 51451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 51461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 51471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 51481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (channelMask != 0) { 51491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(channelMask); 51501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 51521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 51541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 51551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 51561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentaudio_gain_mode_t AudioPolicyManager::AudioPort::loadGainMode(char *name) 51571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 51581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const char *str = strtok(name, "|"); 51591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 51601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadGainMode() %s", name); 51611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent audio_gain_mode_t mode = 0; 51621afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (str != NULL) { 51631afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mode |= (audio_gain_mode_t)stringToEnum(sGainModeNameToEnumTable, 51641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sGainModeNameToEnumTable), 51651afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent str); 51661afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent str = strtok(NULL, "|"); 51671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 51681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return mode; 51691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 51701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 5171a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentvoid AudioPolicyManager::AudioPort::loadGain(cnode *root, int index) 51721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 51731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 51741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 5175a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent sp<AudioGain> gain = new AudioGain(index, mUseInChannelMask); 51761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 51771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 51781afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, GAIN_MODE) == 0) { 51791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.mode = loadGainMode((char *)node->value); 51801afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_CHANNELS) == 0) { 5181a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mUseInChannelMask) { 51821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.channel_mask = 51831afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 51841afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 51851afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (char *)node->value); 51861afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 51871afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.channel_mask = 51881afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 51891afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 51901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (char *)node->value); 51911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 51921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MIN_VALUE) == 0) { 51931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.min_value = atoi((char *)node->value); 51941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MAX_VALUE) == 0) { 51951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.max_value = atoi((char *)node->value); 51961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_DEFAULT_VALUE) == 0) { 51971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.default_value = atoi((char *)node->value); 51981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_STEP_VALUE) == 0) { 51991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.step_value = atoi((char *)node->value); 52001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MIN_RAMP_MS) == 0) { 52011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.min_ramp_ms = atoi((char *)node->value); 52021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MAX_RAMP_MS) == 0) { 52031afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.max_ramp_ms = atoi((char *)node->value); 52041afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 52051afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 52061afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 52071afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 52081afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadGain() adding new gain mode %08x channel mask %08x min mB %d max mB %d", 52091afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.mode, gain->mGain.channel_mask, gain->mGain.min_value, gain->mGain.max_value); 52101afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 52111afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (gain->mGain.mode == 0) { 52121afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return; 52131afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 52141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mGains.add(gain); 52151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 52161afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 52171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::AudioPort::loadGains(cnode *root) 52181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 52191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 5220a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent int index = 0; 52211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 52221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadGains() loading gain %s", node->name); 5223a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent loadGain(node, index++); 52241afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 52251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 52261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 52271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 5228a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioPort::checkSamplingRate(uint32_t samplingRate) const 5229a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 5230a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i ++) { 5231a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mSamplingRates[i] == samplingRate) { 5232a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 5233a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5234a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5235a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 5236a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 5237a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 5238a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioPort::checkChannelMask(audio_channel_mask_t channelMask) const 5239a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 5240a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < mChannelMasks.size(); i ++) { 5241a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mChannelMasks[i] == channelMask) { 5242a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 5243a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5244a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5245a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 5246a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 5247a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 5248a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioPort::checkFormat(audio_format_t format) const 5249a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 5250a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < mFormats.size(); i ++) { 5251a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mFormats[i] == format) { 5252a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 5253a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5254a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5255a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 5256a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 5257a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 52581e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 52591e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentuint32_t AudioPolicyManager::AudioPort::pickSamplingRate() const 52601e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 52611e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // special case for uninitialized dynamic profile 52621e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mSamplingRates.size() == 1 && mSamplingRates[0] == 0) { 52631e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return 0; 52641e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 52651e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 52661e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t samplingRate = 0; 52671e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t maxRate = MAX_MIXER_SAMPLING_RATE; 52681e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 52691e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // For mixed output and inputs, use max mixer sampling rates. Do not 52701e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // limit sampling rate otherwise 52711e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((mType != AUDIO_PORT_TYPE_MIX) || 52721e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ((mRole == AUDIO_PORT_ROLE_SOURCE) && 52731e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)))) { 52741e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent maxRate = UINT_MAX; 52751e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 52761e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i ++) { 52771e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((mSamplingRates[i] > samplingRate) && (mSamplingRates[i] <= maxRate)) { 52781e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent samplingRate = mSamplingRates[i]; 52791e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 52801e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 52811e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return samplingRate; 52821e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 52831e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 52841e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentaudio_channel_mask_t AudioPolicyManager::AudioPort::pickChannelMask() const 52851e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 52861e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // special case for uninitialized dynamic profile 52871e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mChannelMasks.size() == 1 && mChannelMasks[0] == 0) { 52881e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return AUDIO_CHANNEL_NONE; 52891e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 52901e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 52911e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent audio_channel_mask_t channelMask = AUDIO_CHANNEL_NONE; 52921e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t channelCount = 0; 52931e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t maxCount = MAX_MIXER_CHANNEL_COUNT; 52941e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 52951e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // For mixed output and inputs, use max mixer channel count. Do not 52961e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // limit channel count otherwise 52971e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((mType != AUDIO_PORT_TYPE_MIX) || 52981e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ((mRole == AUDIO_PORT_ROLE_SOURCE) && 52991e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)))) { 53001e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent maxCount = UINT_MAX; 53011e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53021e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; i < mChannelMasks.size(); i ++) { 53031e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t cnlCount; 53041e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mUseInChannelMask) { 53051e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]); 53061e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 53071e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]); 53081e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53091e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((cnlCount > channelCount) && (cnlCount <= maxCount)) { 53101e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent channelMask = mChannelMasks[i]; 53111e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53121e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53131e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return channelMask; 53141e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 53151e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 53161e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentconst audio_format_t AudioPolicyManager::AudioPort::sPcmFormatCompareTable[] = { 53171e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent AUDIO_FORMAT_DEFAULT, 53181e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent AUDIO_FORMAT_PCM_16_BIT, 5319a204994e7dd7dab931297176c66b5d3b82e2c90bEric Laurent AUDIO_FORMAT_PCM_8_24_BIT, 53201e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent AUDIO_FORMAT_PCM_24_BIT_PACKED, 5321a204994e7dd7dab931297176c66b5d3b82e2c90bEric Laurent AUDIO_FORMAT_PCM_32_BIT, 53221e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent}; 53231e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 53241e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentint AudioPolicyManager::AudioPort::compareFormats(audio_format_t format1, 53251e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent audio_format_t format2) 53261e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 53271e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // NOTE: AUDIO_FORMAT_INVALID is also considered not PCM and will be compared equal to any 53281e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // compressed format and better than any PCM format. This is by design of pickFormat() 53291e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (!audio_is_linear_pcm(format1)) { 53301e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (!audio_is_linear_pcm(format2)) { 53311e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return 0; 53321e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53331e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return 1; 53341e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53351e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (!audio_is_linear_pcm(format2)) { 53361e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return -1; 53371e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53381e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 53391e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent int index1 = -1, index2 = -1; 53401e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; 53411e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent (i < ARRAY_SIZE(sPcmFormatCompareTable)) && ((index1 == -1) || (index2 == -1)); 53421e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent i ++) { 53431e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (sPcmFormatCompareTable[i] == format1) { 53441e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent index1 = i; 53451e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53461e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (sPcmFormatCompareTable[i] == format2) { 53471e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent index2 = i; 53481e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53491e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53501e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // format1 not found => index1 < 0 => format2 > format1 53511e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // format2 not found => index2 < 0 => format2 < format1 53521e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return index1 - index2; 53531e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 53541e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 53551e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentaudio_format_t AudioPolicyManager::AudioPort::pickFormat() const 53561e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 53571e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // special case for uninitialized dynamic profile 53581e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mFormats.size() == 1 && mFormats[0] == 0) { 53591e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return AUDIO_FORMAT_DEFAULT; 53601e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53611e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 53621e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent audio_format_t format = AUDIO_FORMAT_DEFAULT; 53631e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent audio_format_t bestFormat = BEST_MIXER_FORMAT; 53641e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // For mixed output and inputs, use best mixer output format. Do not 53651e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // limit format otherwise 53661e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((mType != AUDIO_PORT_TYPE_MIX) || 53671e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ((mRole == AUDIO_PORT_ROLE_SOURCE) && 53681e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent (((mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) == 0)))) { 53691e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent bestFormat = AUDIO_FORMAT_INVALID; 53701e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53711e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 53721e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; i < mFormats.size(); i ++) { 53731e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((compareFormats(mFormats[i], format) > 0) && 53741e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent (compareFormats(mFormats[i], bestFormat) <= 0)) { 53751e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent format = mFormats[i]; 53761e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53771e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 53781e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return format; 53791e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 53801e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 5381a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioPort::checkGain(const struct audio_gain_config *gainConfig, 5382a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent int index) const 5383a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 5384a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (index < 0 || (size_t)index >= mGains.size()) { 5385a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 5386a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5387a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return mGains[index]->checkConfig(gainConfig); 5388a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 5389a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 53901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::AudioPort::dump(int fd, int spaces) const 53911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 53921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const size_t SIZE = 256; 53931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent char buffer[SIZE]; 53941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent String8 result; 53951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 53961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mName.size() != 0) { 53971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string()); 53981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 53991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 54001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 54011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mSamplingRates.size() != 0) { 54021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- sampling rates: ", spaces, ""); 54031afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 54041afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 54051e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (i == 0 && mSamplingRates[i] == 0) { 54061e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "Dynamic"); 54071e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 54081e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "%d", mSamplingRates[i]); 54091e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 54101afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 54111afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(i == (mSamplingRates.size() - 1) ? "" : ", "); 54121afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 54131afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append("\n"); 54141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 54151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 54161afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mChannelMasks.size() != 0) { 54171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- channel masks: ", spaces, ""); 54181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 54191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 54201e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ALOGV("AudioPort::dump mChannelMasks %zu %08x", i, mChannelMasks[i]); 54211e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 54221e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (i == 0 && mChannelMasks[i] == 0) { 54231e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "Dynamic"); 54241e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 54251e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]); 54261e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 54271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 54281afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(i == (mChannelMasks.size() - 1) ? "" : ", "); 54291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 54301afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append("\n"); 54311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 54321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 54331afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mFormats.size() != 0) { 54341afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- formats: ", spaces, ""); 54351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 54361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 54371e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent const char *formatStr = enumToString(sFormatNameToEnumTable, 54381e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 54391e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mFormats[i]); 54401e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (i == 0 && strcmp(formatStr, "") == 0) { 54411e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "Dynamic"); 54421e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 54431e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "%-48s", formatStr); 54441e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 54451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 54461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(i == (mFormats.size() - 1) ? "" : ", "); 54471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 54481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append("\n"); 54491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 54501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, result.string(), result.size()); 54511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mGains.size() != 0) { 54521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- gains:\n", spaces, ""); 54531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, buffer, strlen(buffer) + 1); 54541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 54551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mGains.size(); i++) { 54561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mGains[i]->dump(fd, spaces + 2, i); 54571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 54581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 54591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 54601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 54611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent// --- AudioGain class implementation 54621afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 5463a121f90f388343dc48793cbc7eb899aba42e7664Eric LaurentAudioPolicyManager::AudioGain::AudioGain(int index, bool useInChannelMask) 54641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 5465a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mIndex = index; 5466a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mUseInChannelMask = useInChannelMask; 54671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent memset(&mGain, 0, sizeof(struct audio_gain)); 54681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 54691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 5470a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentvoid AudioPolicyManager::AudioGain::getDefaultConfig(struct audio_gain_config *config) 5471a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 5472a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->index = mIndex; 5473a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->mode = mGain.mode; 5474a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->channel_mask = mGain.channel_mask; 5475a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((mGain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { 5476a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->values[0] = mGain.default_value; 5477a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 5478a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent uint32_t numValues; 5479a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mUseInChannelMask) { 5480a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_in_mask(mGain.channel_mask); 5481a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 5482a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_out_mask(mGain.channel_mask); 5483a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5484a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < numValues; i++) { 5485a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->values[i] = mGain.default_value; 5486a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5487a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5488a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((mGain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { 5489a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->ramp_duration_ms = mGain.min_ramp_ms; 5490a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5491a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 5492a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 5493a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioGain::checkConfig(const struct audio_gain_config *config) 5494a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 5495a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->mode & ~mGain.mode) != 0) { 5496a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 5497a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5498a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { 5499a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->values[0] < mGain.min_value) || 5500a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent (config->values[0] > mGain.max_value)) { 5501a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 5502a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5503a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 5504a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->channel_mask & ~mGain.channel_mask) != 0) { 5505a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 5506a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5507a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent uint32_t numValues; 5508a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mUseInChannelMask) { 5509a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_in_mask(config->channel_mask); 5510a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 5511a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_out_mask(config->channel_mask); 5512a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5513a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < numValues; i++) { 5514a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->values[i] < mGain.min_value) || 5515a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent (config->values[i] > mGain.max_value)) { 5516a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 5517a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5518a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5519a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5520a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { 5521a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->ramp_duration_ms < mGain.min_ramp_ms) || 5522a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent (config->ramp_duration_ms > mGain.max_ramp_ms)) { 5523a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 5524a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5525a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5526a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 5527a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 5528a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 55291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::AudioGain::dump(int fd, int spaces, int index) const 55301afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 55311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const size_t SIZE = 256; 55321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent char buffer[SIZE]; 55331afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent String8 result; 55341afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 55351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*sGain %d:\n", spaces, "", index+1); 55361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 55371afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- mode: %08x\n", spaces, "", mGain.mode); 55381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 55391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask); 55401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 55411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- min_value: %d mB\n", spaces, "", mGain.min_value); 55421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 55431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- max_value: %d mB\n", spaces, "", mGain.max_value); 55441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 55451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- default_value: %d mB\n", spaces, "", mGain.default_value); 55461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 55471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- step_value: %d mB\n", spaces, "", mGain.step_value); 55481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 55491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms); 55501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 55511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms); 55521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 55531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 55541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, result.string(), result.size()); 55551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 55561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 55571f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent// --- AudioPortConfig class implementation 55581f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 55591f2f2230900581e5de9cf01a883e5d9338f0df94Eric LaurentAudioPolicyManager::AudioPortConfig::AudioPortConfig() 55601f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent{ 55611f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mSamplingRate = 0; 55621f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mChannelMask = AUDIO_CHANNEL_NONE; 55631f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mFormat = AUDIO_FORMAT_INVALID; 55641f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mGain.index = -1; 55651f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent} 55661f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 5567a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioPortConfig::applyAudioPortConfig( 5568a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent const struct audio_port_config *config, 5569a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config *backupConfig) 5570a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 5571a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config localBackupConfig; 5572a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status_t status = NO_ERROR; 5573a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 5574a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent localBackupConfig.config_mask = config->config_mask; 5575a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent toAudioPortConfig(&localBackupConfig); 5576a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 5577a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mAudioPort == 0) { 5578a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status = NO_INIT; 5579a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 5580a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5581a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { 5582a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status = mAudioPort->checkSamplingRate(config->sample_rate); 5583a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 5584a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 5585a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5586a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mSamplingRate = config->sample_rate; 5587a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5588a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { 5589a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status = mAudioPort->checkChannelMask(config->channel_mask); 5590a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 5591a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 5592a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5593a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mChannelMask = config->channel_mask; 5594a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5595a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) { 5596a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status = mAudioPort->checkFormat(config->format); 5597a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 5598a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 5599a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5600a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mFormat = config->format; 5601a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5602a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) { 5603a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status = mAudioPort->checkGain(&config->gain, config->gain.index); 5604a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 5605a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 5606a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5607a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mGain = config->gain; 5608a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5609a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 5610a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentexit: 5611a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 5612a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent applyAudioPortConfig(&localBackupConfig); 5613a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5614a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (backupConfig != NULL) { 5615a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent *backupConfig = localBackupConfig; 5616a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5617a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return status; 5618a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 5619a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 56201f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::AudioPortConfig::toAudioPortConfig( 56211f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent struct audio_port_config *dstConfig, 56221f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const struct audio_port_config *srcConfig) const 56231f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent{ 56241f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { 56251f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->sample_rate = mSamplingRate; 56261f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)) { 56271f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->sample_rate = srcConfig->sample_rate; 56281f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 56291f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 56301f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->sample_rate = 0; 56311f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 56321f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { 56331f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->channel_mask = mChannelMask; 56341f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)) { 56351f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->channel_mask = srcConfig->channel_mask; 56361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 56371f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 56381f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->channel_mask = AUDIO_CHANNEL_NONE; 56391f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 56401f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) { 56411f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->format = mFormat; 56421f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)) { 56431f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->format = srcConfig->format; 56441f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 56451f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 56461f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->format = AUDIO_FORMAT_INVALID; 56471f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 56481f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) { 56491f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->gain = mGain; 56501f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)) { 56511f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->gain = srcConfig->gain; 56521f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 56531f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 56541f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->gain.index = -1; 56551f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 56561f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->gain.index != -1) { 56571f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN; 56581f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 56591f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN; 56601f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 56611f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent} 56621f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 56631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- IOProfile class implementation 56641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 56651afeecb88bea660b2c10b2096be0fd02433303ceEric LaurentAudioPolicyManager::IOProfile::IOProfile(const String8& name, audio_port_role_t role, 56661f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<HwModule>& module) 56671e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent : AudioPort(name, AUDIO_PORT_TYPE_MIX, role, module) 5668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5671e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile::~IOProfile() 5672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// checks if the IO profile is compatible with specified parameters. 5676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Sampling rate, format and channel mask must be specified in order to 5677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// get a valid a match 5678e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device, 5679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 5680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 5681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 5682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_output_flags_t flags) const 5683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (samplingRate == 0 || !audio_is_valid_format(format) || channelMask == 0) { 5685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 5686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 56883a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((mSupportedDevices.types() & device) != device) { 5689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 5690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((mFlags & flags) != flags) { 5692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 5693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5694a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (checkSamplingRate(samplingRate) != NO_ERROR) { 5695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 5696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5697a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (checkChannelMask(channelMask) != NO_ERROR) { 5698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 5699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5700a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (checkFormat(format) != NO_ERROR) { 5701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 5702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 5704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5706e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::IOProfile::dump(int fd) 5707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 5709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 5710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 5711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 57121afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent AudioPort::dump(fd, 4); 5713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 57141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, " - flags: 0x%04x\n", mFlags); 5715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 57163a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, " - devices:\n"); 5717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 57183a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, result.string(), result.size()); 57193a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mSupportedDevices.size(); i++) { 57201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mSupportedDevices[i]->dump(fd, 6, i); 57213a4311c68348f728558e87b5db67d47605783890Eric Laurent } 5722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5724d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::IOProfile::log() 5725d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 5726d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent const size_t SIZE = 256; 5727d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char buffer[SIZE]; 5728d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 result; 5729d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 5730d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - sampling rates: "); 5731d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 5732d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" %d", mSamplingRates[i]); 5733d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 5734d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 5735d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - channel masks: "); 5736d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 5737d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" 0x%04x", mChannelMasks[i]); 5738d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 5739d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 5740d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - formats: "); 5741d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 5742d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" 0x%08x", mFormats[i]); 5743d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 5744d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 5745d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - devices: 0x%04x\n", mSupportedDevices.types()); 5746d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - flags: 0x%04x\n", mFlags); 5747d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 5748d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 5749d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 57503a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- DeviceDescriptor implementation 5751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 57521f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 57531f2f2230900581e5de9cf01a883e5d9338f0df94Eric LaurentAudioPolicyManager::DeviceDescriptor::DeviceDescriptor(const String8& name, audio_devices_t type) : 57541f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPort(name, AUDIO_PORT_TYPE_DEVICE, 57551f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK : 57561f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_PORT_ROLE_SOURCE, 57571f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent NULL), 57581e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mDeviceType(type), mAddress(""), mId(0) 57591f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent{ 57601f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mAudioPort = this; 5761a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mGains.size() > 0) { 5762a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mGains[0]->getDefaultConfig(&mGain); 5763a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 57641f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent} 57651f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 57663a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const 57673a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 57683a4311c68348f728558e87b5db67d47605783890Eric Laurent // Devices are considered equal if they: 57693a4311c68348f728558e87b5db67d47605783890Eric Laurent // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE) 57703a4311c68348f728558e87b5db67d47605783890Eric Laurent // - have the same address or one device does not specify the address 57713a4311c68348f728558e87b5db67d47605783890Eric Laurent // - have the same channel mask or one device does not specify the channel mask 57721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return (mDeviceType == other->mDeviceType) && 57733a4311c68348f728558e87b5db67d47605783890Eric Laurent (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) && 57742f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent (mChannelMask == 0 || other->mChannelMask == 0 || 57753a4311c68348f728558e87b5db67d47605783890Eric Laurent mChannelMask == other->mChannelMask); 57763a4311c68348f728558e87b5db67d47605783890Eric Laurent} 5777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 57783a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::refreshTypes() 57793a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 57801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDeviceTypes = AUDIO_DEVICE_NONE; 57813a4311c68348f728558e87b5db67d47605783890Eric Laurent for(size_t i = 0; i < size(); i++) { 57821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDeviceTypes |= itemAt(i)->mDeviceType; 57833a4311c68348f728558e87b5db67d47605783890Eric Laurent } 57841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes); 57853a4311c68348f728558e87b5db67d47605783890Eric Laurent} 5786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 57873a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const 57883a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 57893a4311c68348f728558e87b5db67d47605783890Eric Laurent for(size_t i = 0; i < size(); i++) { 57903a4311c68348f728558e87b5db67d47605783890Eric Laurent if (item->equals(itemAt(i))) { 57913a4311c68348f728558e87b5db67d47605783890Eric Laurent return i; 57923a4311c68348f728558e87b5db67d47605783890Eric Laurent } 57933a4311c68348f728558e87b5db67d47605783890Eric Laurent } 57943a4311c68348f728558e87b5db67d47605783890Eric Laurent return -1; 57953a4311c68348f728558e87b5db67d47605783890Eric Laurent} 5796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 57973a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::add(const sp<DeviceDescriptor>& item) 57983a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 57993a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t ret = indexOf(item); 5800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 58013a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret < 0) { 58023a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = SortedVector::add(item); 58033a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret >= 0) { 58043a4311c68348f728558e87b5db67d47605783890Eric Laurent refreshTypes(); 58053a4311c68348f728558e87b5db67d47605783890Eric Laurent } 58063a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 58071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("DeviceVector::add device %08x already in", item->mDeviceType); 58083a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = -1; 58093a4311c68348f728558e87b5db67d47605783890Eric Laurent } 58103a4311c68348f728558e87b5db67d47605783890Eric Laurent return ret; 58113a4311c68348f728558e87b5db67d47605783890Eric Laurent} 5812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 58133a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::remove(const sp<DeviceDescriptor>& item) 58143a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 58153a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t i; 58163a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t ret = indexOf(item); 5817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 58183a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret < 0) { 58191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("DeviceVector::remove device %08x not in", item->mDeviceType); 58203a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 58213a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = SortedVector::removeAt(ret); 58223a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret >= 0) { 58233a4311c68348f728558e87b5db67d47605783890Eric Laurent refreshTypes(); 58243a4311c68348f728558e87b5db67d47605783890Eric Laurent } 58253a4311c68348f728558e87b5db67d47605783890Eric Laurent } 58263a4311c68348f728558e87b5db67d47605783890Eric Laurent return ret; 58273a4311c68348f728558e87b5db67d47605783890Eric Laurent} 5828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 58293a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::loadDevicesFromType(audio_devices_t types) 5830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 58313a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceVector deviceList; 58323a4311c68348f728558e87b5db67d47605783890Eric Laurent 58333a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t role_bit = AUDIO_DEVICE_BIT_IN & types; 58343a4311c68348f728558e87b5db67d47605783890Eric Laurent types &= ~role_bit; 58353a4311c68348f728558e87b5db67d47605783890Eric Laurent 58363a4311c68348f728558e87b5db67d47605783890Eric Laurent while (types) { 58373a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t i = 31 - __builtin_clz(types); 58383a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t type = 1 << i; 58393a4311c68348f728558e87b5db67d47605783890Eric Laurent types &= ~type; 58401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent add(new DeviceDescriptor(String8(""), type | role_bit)); 5841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 58441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::DeviceVector::loadDevicesFromName(char *name, 58451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const DeviceVector& declaredDevices) 58461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 58471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent char *devName = strtok(name, "|"); 58481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (devName != NULL) { 58491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strlen(devName) != 0) { 58501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent audio_devices_t type = stringToEnum(sDeviceNameToEnumTable, 58511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 58521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent devName); 58531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (type != AUDIO_DEVICE_NONE) { 58541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent add(new DeviceDescriptor(String8(""), type)); 58551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 58561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> deviceDesc = 58571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices.getDeviceFromName(String8(devName)); 58581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (deviceDesc != 0) { 58591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent add(deviceDesc); 58601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 58611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 58621afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 58631afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent devName = strtok(NULL, "|"); 58641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 58651afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 58661afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 58671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDevice( 58681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type, String8 address) const 58691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 58701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<DeviceDescriptor> device; 58711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; i < size(); i++) { 58721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (itemAt(i)->mDeviceType == type) { 58731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = itemAt(i); 58741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (itemAt(i)->mAddress = address) { 58751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent break; 58761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("DeviceVector::getDevice() for type %d address %s found %p", 58801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent type, address.string(), device.get()); 58811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return device; 58821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 58831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromId( 58856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_handle_t id) const 58866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 58876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<DeviceDescriptor> device; 58886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < size(); i++) { 5889beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("DeviceVector::getDeviceFromId(%d) itemAt(%zu)->mId %d", id, i, itemAt(i)->mId); 58906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (itemAt(i)->mId == id) { 58916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent device = itemAt(i); 58926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 58936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 58946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 58956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return device; 58966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 58976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 58981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromType( 58991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type) const 59001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 59011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent DeviceVector devices; 59021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) { 59031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (itemAt(i)->mDeviceType & type & ~AUDIO_DEVICE_BIT_IN) { 59041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent devices.add(itemAt(i)); 59051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent type &= ~itemAt(i)->mDeviceType; 59061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("DeviceVector::getDevicesFromType() for type %x found %p", 59071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent itemAt(i)->mDeviceType, itemAt(i).get()); 59081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 59091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 59101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return devices; 59111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 59121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 59131afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromName( 59141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const String8& name) const 59151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 59161afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> device; 59171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < size(); i++) { 59181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (itemAt(i)->mName == name) { 59191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent device = itemAt(i); 59201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent break; 59211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 59221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 59231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return device; 59241afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 59251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 59266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentvoid AudioPolicyManager::DeviceDescriptor::toAudioPortConfig( 59276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port_config *dstConfig, 59286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const struct audio_port_config *srcConfig) const 59291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 59301f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK|AUDIO_PORT_CONFIG_GAIN; 59311f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (srcConfig != NULL) { 593284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent dstConfig->config_mask |= srcConfig->config_mask; 59331f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 59341f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 59351f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 59361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 59376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->id = mId; 59386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->role = audio_is_output_device(mDeviceType) ? 59391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE; 59406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->type = AUDIO_PORT_TYPE_DEVICE; 59416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.device.type = mDeviceType; 59426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.device.hw_module = mModule->mHandle; 59436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN); 59441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 59451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 59461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::DeviceDescriptor::toAudioPort(struct audio_port *port) const 59471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 5948e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("DeviceVector::toAudioPort() handle %d type %x", mId, mDeviceType); 59491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AudioPort::toAudioPort(port); 59501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 59516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent toAudioPortConfig(&port->active_config); 59521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.device.type = mDeviceType; 59536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent port->ext.device.hw_module = mModule->mHandle; 59541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN); 59551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 59561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 59571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::DeviceDescriptor::dump(int fd, int spaces, int index) const 59583a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 59593a4311c68348f728558e87b5db67d47605783890Eric Laurent const size_t SIZE = 256; 59603a4311c68348f728558e87b5db67d47605783890Eric Laurent char buffer[SIZE]; 59611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent String8 result; 59623a4311c68348f728558e87b5db67d47605783890Eric Laurent 59631afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1); 59641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 59651afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mId != 0) { 59661afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId); 59671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 59681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 59691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "", 59701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent enumToString(sDeviceNameToEnumTable, 59711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 59721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeviceType)); 59731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 59741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mAddress.size() != 0) { 59751afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string()); 59761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 59771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 59781afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, result.string(), result.size()); 59791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent AudioPort::dump(fd, spaces); 59803a4311c68348f728558e87b5db67d47605783890Eric Laurent 59813a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_ERROR; 59823a4311c68348f728558e87b5db67d47605783890Eric Laurent} 59833a4311c68348f728558e87b5db67d47605783890Eric Laurent 59843a4311c68348f728558e87b5db67d47605783890Eric Laurent 59853a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- audio_policy.conf file parsing 59863a4311c68348f728558e87b5db67d47605783890Eric Laurent 5987e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_output_flags_t AudioPolicyManager::parseFlagNames(char *name) 5988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t flag = 0; 5990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // it is OK to cast name to non const here as we are not going to use it after 5992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // strtok() modifies it 5993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *flagName = strtok(name, "|"); 5994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (flagName != NULL) { 5995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strlen(flagName) != 0) { 5996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flag |= stringToEnum(sFlagNameToEnumTable, 5997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sFlagNameToEnumTable), 5998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flagName); 5999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flagName = strtok(NULL, "|"); 6001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //force direct flag if offload flag is set: offloading implies a direct output stream 6003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and all common behaviors are driven by checking only the direct flag 6004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this should normally be set appropriately in the policy configuration file 6005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 6006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flag |= AUDIO_OUTPUT_FLAG_DIRECT; 6007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_output_flags_t)flag; 6010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6012e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::parseDeviceNames(char *name) 6013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = 0; 6015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *devName = strtok(name, "|"); 6017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (devName != NULL) { 6018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strlen(devName) != 0) { 6019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device |= stringToEnum(sDeviceNameToEnumTable, 6020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 6021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devName); 60223a4311c68348f728558e87b5db67d47605783890Eric Laurent } 6023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devName = strtok(NULL, "|"); 60243a4311c68348f728558e87b5db67d47605783890Eric Laurent } 6025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 6026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6028e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModule(cnode *root) 6029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t status = NAME_NOT_FOUND; 60311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node; 60321f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module = new HwModule(root->name); 6033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 60341afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = config_find(root, DEVICES_TAG); 60351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (node != NULL) { 60361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->first_child; 60371afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 60381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadHwModule() loading device %s", node->name); 60391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status_t tmpStatus = module->loadDevice(node); 60401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 60411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status = tmpStatus; 60421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 60431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 60441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 60451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 60461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = config_find(root, OUTPUTS_TAG); 6047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node != NULL) { 6048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 6049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 6050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModule() loading output %s", node->name); 60511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status_t tmpStatus = module->loadOutput(node); 6052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 6053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = tmpStatus; 6054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 6056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = config_find(root, INPUTS_TAG); 6059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node != NULL) { 6060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 6061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 6062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModule() loading input %s", node->name); 60631afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status_t tmpStatus = module->loadInput(node); 6064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 6065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = tmpStatus; 6066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 6068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 60701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent loadGlobalConfig(root, module); 60711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 6072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NO_ERROR) { 6073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules.add(module); 6074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6077e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModules(cnode *root) 6078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); 6080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node == NULL) { 6081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 6082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 6085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 6086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModules() loading module %s", node->name); 6087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadHwModule(node); 6088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 6089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 60921f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::loadGlobalConfig(cnode *root, const sp<HwModule>& module) 6093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, GLOBAL_CONFIG_TAG); 6095eb108a4622825688b02d7afc981014d149913cd8Eric Laurent 6096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node == NULL) { 6097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 6098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 60991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent DeviceVector declaredDevices; 61001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (module != NULL) { 61011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices = module->mDeclaredDevices; 61021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 61031afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 6104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 6105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 6106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { 61071afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableOutputDevices.loadDevicesFromName((char *)node->value, 61081afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices); 61093a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadGlobalConfig() Attached Output Devices %08x", 61103a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.types()); 6111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { 61123a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t device = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable, 6113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 6114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (char *)node->value); 61153a4311c68348f728558e87b5db67d47605783890Eric Laurent if (device != AUDIO_DEVICE_NONE) { 61161afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDefaultOutputDevice = new DeviceDescriptor(String8(""), device); 61173a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 61183a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("loadGlobalConfig() default device not specified"); 61193a4311c68348f728558e87b5db67d47605783890Eric Laurent } 61201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", mDefaultOutputDevice->mDeviceType); 6121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { 61221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableInputDevices.loadDevicesFromName((char *)node->value, 61231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices); 61243a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadGlobalConfig() Available InputDevices %08x", mAvailableInputDevices.types()); 6125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) { 6126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mSpeakerDrcEnabled = stringToBool((char *)node->value); 6127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled); 6128eb108a4622825688b02d7afc981014d149913cd8Eric Laurent } else if (strcmp(AUDIO_HAL_VERSION_TAG, node->name) == 0) { 6129eb108a4622825688b02d7afc981014d149913cd8Eric Laurent uint32_t major, minor; 6130eb108a4622825688b02d7afc981014d149913cd8Eric Laurent sscanf((char *)node->value, "%u.%u", &major, &minor); 6131eb108a4622825688b02d7afc981014d149913cd8Eric Laurent module->mHalVersion = HARDWARE_DEVICE_API_VERSION(major, minor); 6132eb108a4622825688b02d7afc981014d149913cd8Eric Laurent ALOGV("loadGlobalConfig() mHalVersion = %04x major %u minor %u", 6133eb108a4622825688b02d7afc981014d149913cd8Eric Laurent module->mHalVersion, major, minor); 6134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 6136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6139e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadAudioPolicyConfig(const char *path) 6140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *root; 6142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *data; 6143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent data = (char *)load_file(path, NULL); 6145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (data == NULL) { 6146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return -ENODEV; 6147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent root = config_node("", ""); 6149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent config_load(root, data); 6150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadHwModules(root); 61521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent // legacy audio_policy.conf files have one global_configuration section 61531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent loadGlobalConfig(root, getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)); 6154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent config_free(root); 6155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free(root); 6156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free(data); 6157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGI("loadAudioPolicyConfig() loaded %s\n", path); 6159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 6161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6163e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::defaultAudioPolicyConfig(void) 6164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 61651f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module; 61661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile; 61671f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(String8(""), 61681f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_DEVICE_IN_BUILTIN_MIC); 61693a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.add(mDefaultOutputDevice); 61703a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.add(defaultInputDevice); 6171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module = new HwModule("primary"); 6173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 61741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SOURCE, module); 6175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(44100); 6176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 6177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO); 61783a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.add(mDefaultOutputDevice); 6179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY; 6180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mOutputProfiles.add(profile); 6181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 61821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SINK, module); 6183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(8000); 6184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 6185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO); 61863a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.add(defaultInputDevice); 6187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mInputProfiles.add(profile); 6188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules.add(module); 6190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 61925bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr) 61935bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{ 61945bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // flags to stream type mapping 61955bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { 61965bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_ENFORCED_AUDIBLE; 61975bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 61985bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) { 61995bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_BLUETOOTH_SCO; 62005bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 62015bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 62025bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // usage to stream type mapping 62035bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi switch (attr->usage) { 62045bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_MEDIA: 62055bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_GAME: 62065bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: 62075bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 62085bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_MUSIC; 62095bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_SONIFICATION: 62105bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_SYSTEM; 62115bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION: 62125bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_VOICE_CALL; 62135bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 62145bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: 62155bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_DTMF; 62165bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 62175bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ALARM: 62185bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_ALARM; 62195bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: 62205bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_RING; 62215bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 62225bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION: 62235bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: 62245bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: 62255bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: 62265bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_EVENT: 62275bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_NOTIFICATION; 62285bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 62295bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_UNKNOWN: 62305bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi default: 62315bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_MUSIC; 62325bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 62335bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi} 6234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; // namespace android 6235