AudioPolicyManager.cpp revision 11c9fb1f90cc786485a53aeb1d31ec1ad1dbf840
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 330fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi// A device mask for all audio input and output devices where matching inputs/outputs on device 340fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi// type alone is not enough: the address must match too 350fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi#define APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX | \ 360fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi AUDIO_DEVICE_OUT_REMOTE_SUBMIX) 37e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 38d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <inttypes.h> 39d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <math.h> 40d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 41d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <cutils/properties.h> 42e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#include <utils/Log.h> 43e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#include <hardware/audio.h> 44d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <hardware/audio_effect.h> 453b73df74357b33869b39a1d69427673c780bd805Eric Laurent#include <media/AudioParameter.h> 46df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent#include <soundtrigger/SoundTrigger.h> 47d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include "AudioPolicyManager.h" 481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent#include "audio_policy_conf.h" 49e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 503b73df74357b33869b39a1d69427673c780bd805Eric Laurentnamespace android { 51e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 52e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 533a4311c68348f728558e87b5db67d47605783890Eric Laurent// Definitions for audio_policy.conf file parsing 543a4311c68348f728558e87b5db67d47605783890Eric Laurent// ---------------------------------------------------------------------------- 553a4311c68348f728558e87b5db67d47605783890Eric Laurent 563a4311c68348f728558e87b5db67d47605783890Eric Laurentstruct StringToEnum { 573a4311c68348f728558e87b5db67d47605783890Eric Laurent const char *name; 583a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t value; 593a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 603a4311c68348f728558e87b5db67d47605783890Eric Laurent 613a4311c68348f728558e87b5db67d47605783890Eric Laurent#define STRING_TO_ENUM(string) { #string, string } 623a4311c68348f728558e87b5db67d47605783890Eric Laurent#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 633a4311c68348f728558e87b5db67d47605783890Eric Laurent 643a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sDeviceNameToEnumTable[] = { 653a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE), 663a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER), 6711c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER_SAFE), 683a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET), 693a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE), 703a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO), 713a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET), 723a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT), 733a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO), 743a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP), 753a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES), 763a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER), 773a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP), 783a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL), 791b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI), 803a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET), 813a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET), 823a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY), 833a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE), 843a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB), 853a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX), 861b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_TELEPHONY_TX), 871b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_LINE), 881b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC), 891b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPDIF), 901b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM), 91e1d37b784f3970e44a7331c189cbfdca15404648Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_LINE), 92a57ab8da6fe56fdb91dfc95ebd0282eb879dde53Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_AMBIENT), 933a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), 943a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), 953a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO), 963a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET), 973a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL), 981b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_HDMI), 991b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX), 100c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL), 1013a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC), 1023a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX), 1033a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET), 1043a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET), 1053a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY), 106d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE), 1071b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_FM_TUNER), 1081b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_TV_TUNER), 1091b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_LINE), 1101b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_SPDIF), 11141b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP), 1127999a2236cb641dc1d7bf7bd8d2499d40d0a806dTerry Heo STRING_TO_ENUM(AUDIO_DEVICE_IN_LOOPBACK), 1133a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1143a4311c68348f728558e87b5db67d47605783890Eric Laurent 1153a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFlagNameToEnumTable[] = { 1163a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT), 1173a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), 1183a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), 1193a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), 1203a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD), 1213a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING), 12293c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_HW_AV_SYNC), 1233a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1243a4311c68348f728558e87b5db67d47605783890Eric Laurent 1253a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFormatNameToEnumTable[] = { 1263a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT), 1273a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT), 1283a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT), 1293a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT), 1303a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT), 1313a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED), 1323a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_MP3), 1333a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AAC), 1342829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_MAIN), 1352829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_LC), 1362829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_SSR), 1372829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_LTP), 1382829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V1), 1392829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_SCALABLE), 1402829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_ERLC), 1412829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_LD), 1422829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V2), 1432829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_ELD), 1443a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_VORBIS), 145ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V1), 146ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V2), 147ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_OPUS), 148ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AC3), 149ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_E_AC3), 1503a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1513a4311c68348f728558e87b5db67d47605783890Eric Laurent 1523a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sOutChannelsNameToEnumTable[] = { 1533a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO), 1543a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 1553a0fe12fbd08b13e9f57d79b0391186be05072f5Andy Hung STRING_TO_ENUM(AUDIO_CHANNEL_OUT_QUAD), 1563a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 1573a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 1583a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1593a4311c68348f728558e87b5db67d47605783890Eric Laurent 1603a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sInChannelsNameToEnumTable[] = { 1613a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), 1623a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), 1633a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK), 1643a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1653a4311c68348f728558e87b5db67d47605783890Eric Laurent 1661afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentconst StringToEnum sGainModeNameToEnumTable[] = { 1671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent STRING_TO_ENUM(AUDIO_GAIN_MODE_JOINT), 1681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent STRING_TO_ENUM(AUDIO_GAIN_MODE_CHANNELS), 1691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent STRING_TO_ENUM(AUDIO_GAIN_MODE_RAMP), 1701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent}; 1711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 1723a4311c68348f728558e87b5db67d47605783890Eric Laurent 1733a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::stringToEnum(const struct StringToEnum *table, 1743a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t size, 1753a4311c68348f728558e87b5db67d47605783890Eric Laurent const char *name) 1763a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1773a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < size; i++) { 1783a4311c68348f728558e87b5db67d47605783890Eric Laurent if (strcmp(table[i].name, name) == 0) { 1793a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("stringToEnum() found %s", table[i].name); 1803a4311c68348f728558e87b5db67d47605783890Eric Laurent return table[i].value; 1813a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1823a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1833a4311c68348f728558e87b5db67d47605783890Eric Laurent return 0; 1843a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1853a4311c68348f728558e87b5db67d47605783890Eric Laurent 1863a4311c68348f728558e87b5db67d47605783890Eric Laurentconst char *AudioPolicyManager::enumToString(const struct StringToEnum *table, 1873a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t size, 1883a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t value) 1893a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1903a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < size; i++) { 1913a4311c68348f728558e87b5db67d47605783890Eric Laurent if (table[i].value == value) { 1923a4311c68348f728558e87b5db67d47605783890Eric Laurent return table[i].name; 1933a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1943a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1953a4311c68348f728558e87b5db67d47605783890Eric Laurent return ""; 1963a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1973a4311c68348f728558e87b5db67d47605783890Eric Laurent 1983a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::stringToBool(const char *value) 1993a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 2003a4311c68348f728558e87b5db67d47605783890Eric Laurent return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0)); 2013a4311c68348f728558e87b5db67d47605783890Eric Laurent} 2023a4311c68348f728558e87b5db67d47605783890Eric Laurent 2033a4311c68348f728558e87b5db67d47605783890Eric Laurent 2043a4311c68348f728558e87b5db67d47605783890Eric Laurent// ---------------------------------------------------------------------------- 205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AudioPolicyInterface implementation 206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 209e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, 2103b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state, 211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *device_address) 212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 213222260168c144cca5a4e8f1c79df8c8baa22b591Eric Laurent String8 address = (device_address == NULL) ? String8("") : String8(device_address); 214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 215222260168c144cca5a4e8f1c79df8c8baa22b591Eric Laurent ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", 216222260168c144cca5a4e8f1c79df8c8baa22b591Eric Laurent device, state, address.string()); 217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // connect/disconnect only 1 device at a time 219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; 220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output devices 222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_output_device(device)) { 223d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector <audio_io_handle_t> outputs; 224d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); 2261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent devDesc->mAddress = address; 2273a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = mAvailableOutputDevices.indexOf(devDesc); 2283a4311c68348f728558e87b5db67d47605783890Eric Laurent 229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // save a copy of the opened output descriptors before any output is opened or closed 230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() 231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (state) 233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output device connection 2353b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: 2363a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device already connected: %x", device); 238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setDeviceConnectionState() connecting device %x", device); 241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // register new device as available 2433a4311c68348f728558e87b5db67d47605783890Eric Laurent index = mAvailableOutputDevices.add(devDesc); 2443a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 2451f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module = getModuleForDevice(device); 246cf817a2330936947df94c11859f48771f5596a59Eric Laurent if (module == 0) { 247cf817a2330936947df94c11859f48771f5596a59Eric Laurent ALOGD("setDeviceConnectionState() could not find HW module for device %08x", 248cf817a2330936947df94c11859f48771f5596a59Eric Laurent device); 249cf817a2330936947df94c11859f48771f5596a59Eric Laurent mAvailableOutputDevices.remove(devDesc); 250cf817a2330936947df94c11859f48771f5596a59Eric Laurent return INVALID_OPERATION; 251cf817a2330936947df94c11859f48771f5596a59Eric Laurent } 252cf817a2330936947df94c11859f48771f5596a59Eric Laurent mAvailableOutputDevices[index]->mId = nextUniqueId(); 2536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableOutputDevices[index]->mModule = module; 2543a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 2553a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_MEMORY; 256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 258f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (checkOutputsForDevice(devDesc, state, outputs, address) != NO_ERROR) { 2590fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi mAvailableOutputDevices.remove(devDesc); 2600fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi return INVALID_OPERATION; 2610fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 2620fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi // outputs should never be empty here 2630fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():" 2640fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi "checkOutputsForDevice() returned no outputs but status OK"); 2650fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs", 2660fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi outputs.size()); 267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output device disconnection 2693b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: { 2703a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index < 0) { 271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device not connected: %x", device); 272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2755c477aa6205e2ebafec237411900d89a510cc105Paul McLean ALOGV("setDeviceConnectionState() disconnecting output device %x", device); 2765c477aa6205e2ebafec237411900d89a510cc105Paul McLean 2775c477aa6205e2ebafec237411900d89a510cc105Paul McLean // Set Disconnect to HALs 2785c477aa6205e2ebafec237411900d89a510cc105Paul McLean AudioParameter param = AudioParameter(address); 2795c477aa6205e2ebafec237411900d89a510cc105Paul McLean param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device); 2805c477aa6205e2ebafec237411900d89a510cc105Paul McLean mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString()); 2815c477aa6205e2ebafec237411900d89a510cc105Paul McLean 282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // remove device from available output devices 2833a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.remove(devDesc); 2843a4311c68348f728558e87b5db67d47605783890Eric Laurent 285f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi checkOutputsForDevice(devDesc, state, outputs, address); 286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } break; 287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("setDeviceConnectionState() invalid state: %x", state); 290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2933a4311c68348f728558e87b5db67d47605783890Eric Laurent // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP 2943a4311c68348f728558e87b5db67d47605783890Eric Laurent // output is suspended before any tracks are moved to it 295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // outputs must be closed after checkOutputForAllStrategies() is executed 298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputs.isEmpty()) { 299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 3001f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]); 301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // close unused outputs after device disconnection or direct outputs that have been 302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // opened by checkOutputsForDevice() to query dynamic parameters 3033b73df74357b33869b39a1d69427673c780bd805Eric Laurent if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) || 304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) && 305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (desc->mDirectOpenCount == 0))) { 306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent closeOutput(outputs[i]); 307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3093a4311c68348f728558e87b5db67d47605783890Eric Laurent // check again after closing A2DP output to reset mA2dpSuspended if needed 3103a4311c68348f728558e87b5db67d47605783890Eric Laurent checkA2dpSuspend(); 311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 314c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mPhoneState == AUDIO_MODE_IN_CALL) { 315c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/); 316c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent updateCallRouting(newDevice); 317c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 319c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 320c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if ((mPhoneState != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) { 321c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t newDevice = getNewOutputDevice(mOutputs.keyAt(i), 322c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent true /*fromCache*/); 323c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // do not force device change on duplicated output because if device is 0, it will 324c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // also force a device 0 for the two outputs it is duplicated to which may override 325c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // a valid device selection on those outputs. 326c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent bool force = !mOutputs.valueAt(i)->isDuplicated() 327c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent && (!deviceDistinguishesOnAddress(device) 328c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // always force when disconnecting (a non-duplicated device) 329c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE)); 330c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent setOutputDevice(output, newDevice, force, 0); 331c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 33472aa32f7dbbfb658097930b57659d8e50f24a953Eric Laurent mpClientInterface->onAudioPortListUpdate(); 335b71e58b64cd4992355cf6afaf3f3530f723bc72cEric Laurent return NO_ERROR; 336d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end if is output device 337d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input devices 339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_input_device(device)) { 340d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector <audio_io_handle_t> inputs; 341d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); 3431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent devDesc->mAddress = address; 3443a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = mAvailableInputDevices.indexOf(devDesc); 345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (state) 346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input device connection 3483b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: { 3493a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device already connected: %d", device); 351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3531f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module = getModuleForDevice(device); 3546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (module == NULL) { 3556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("setDeviceConnectionState(): could not find HW module for device %08x", 3566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent device); 3576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 3586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 359d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (checkInputsForDevice(device, state, inputs, address) != NO_ERROR) { 360d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return INVALID_OPERATION; 361d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 362d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3633a4311c68348f728558e87b5db67d47605783890Eric Laurent index = mAvailableInputDevices.add(devDesc); 3643a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 3653a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices[index]->mId = nextUniqueId(); 3666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices[index]->mModule = module; 3673a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 3683a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_MEMORY; 3693a4311c68348f728558e87b5db67d47605783890Eric Laurent } 370d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } break; 371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input device disconnection 3733b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: { 3743a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index < 0) { 375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device not connected: %d", device); 376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3785c477aa6205e2ebafec237411900d89a510cc105Paul McLean 3795c477aa6205e2ebafec237411900d89a510cc105Paul McLean ALOGV("setDeviceConnectionState() disconnecting input device %x", device); 3805c477aa6205e2ebafec237411900d89a510cc105Paul McLean 3815c477aa6205e2ebafec237411900d89a510cc105Paul McLean // Set Disconnect to HALs 3825c477aa6205e2ebafec237411900d89a510cc105Paul McLean AudioParameter param = AudioParameter(address); 3835c477aa6205e2ebafec237411900d89a510cc105Paul McLean param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device); 3845c477aa6205e2ebafec237411900d89a510cc105Paul McLean mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString()); 3855c477aa6205e2ebafec237411900d89a510cc105Paul McLean 386d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent checkInputsForDevice(device, state, inputs, address); 3873a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.remove(devDesc); 3885c477aa6205e2ebafec237411900d89a510cc105Paul McLean 389d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } break; 390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("setDeviceConnectionState() invalid state: %x", state); 393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 396d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent closeAllInputs(); 397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 398c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mPhoneState == AUDIO_MODE_IN_CALL) { 399c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/); 400c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent updateCallRouting(newDevice); 401c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 402c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 403b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 405d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end if is input device 406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() invalid device: %x", device); 408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 411e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device, 412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *device_address) 413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4143b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 4151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); 416222260168c144cca5a4e8f1c79df8c8baa22b591Eric Laurent devDesc->mAddress = (device_address == NULL) ? String8("") : String8(device_address); 4173a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index; 4183a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceVector *deviceVector; 4193a4311c68348f728558e87b5db67d47605783890Eric Laurent 420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_output_device(device)) { 4213a4311c68348f728558e87b5db67d47605783890Eric Laurent deviceVector = &mAvailableOutputDevices; 422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (audio_is_input_device(device)) { 4233a4311c68348f728558e87b5db67d47605783890Eric Laurent deviceVector = &mAvailableInputDevices; 4243a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 4253a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("getDeviceConnectionState() invalid device type %08x", device); 4263a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4293a4311c68348f728558e87b5db67d47605783890Eric Laurent index = deviceVector->indexOf(devDesc); 4303a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 4313a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_AVAILABLE; 4323a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 4333a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 4343a4311c68348f728558e87b5db67d47605783890Eric Laurent } 435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 437c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurentvoid AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs) 438c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent{ 439c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent bool createTxPatch = false; 440c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent struct audio_patch patch; 441c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sources = 1; 442c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sinks = 1; 443c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent status_t status; 444c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_patch_handle_t afPatchHandle; 445c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent DeviceVector deviceList; 446c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 447c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION); 448c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice); 449c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 450c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // release existing RX patch if any 451c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mCallRxPatch != 0) { 452c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0); 453c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallRxPatch.clear(); 454c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 455c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // release TX patch if any 456c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mCallTxPatch != 0) { 457c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0); 458c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallTxPatch.clear(); 459c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 460c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 461c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // If the RX device is on the primary HW module, then use legacy routing method for voice calls 462c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // via setOutputDevice() on primary output. 463c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // Otherwise, create two audio patches for TX and RX path. 464c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (availablePrimaryOutputDevices() & rxDevice) { 465c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent setOutputDevice(mPrimaryOutput, rxDevice, true, delayMs); 466c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // If the TX device is also on the primary HW module, setOutputDevice() will take care 467c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // of it due to legacy implementation. If not, create a patch. 468c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if ((availablePrimaryInputDevices() & txDevice & ~AUDIO_DEVICE_BIT_IN) 469c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent == AUDIO_DEVICE_NONE) { 470c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent createTxPatch = true; 471c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 472c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else { 473c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // create RX path audio patch 474c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent deviceList = mAvailableOutputDevices.getDevicesFromType(rxDevice); 475c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!deviceList.isEmpty(), 476c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() selected device not in output device list"); 477c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<DeviceDescriptor> rxSinkDeviceDesc = deviceList.itemAt(0); 478c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent deviceList = mAvailableInputDevices.getDevicesFromType(AUDIO_DEVICE_IN_TELEPHONY_RX); 479c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!deviceList.isEmpty(), 480c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() no telephony RX device"); 481c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<DeviceDescriptor> rxSourceDeviceDesc = deviceList.itemAt(0); 482c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 483c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent rxSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]); 484c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent rxSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]); 485c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 486c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // request to reuse existing output stream if one is already opened to reach the RX device 487c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent SortedVector<audio_io_handle_t> outputs = 488c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent getOutputsForDevice(rxDevice, mOutputs); 4898838a3895c365d443ee22e169ccf45956780c081Eric Laurent audio_io_handle_t output = selectOutput(outputs, 4908838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_OUTPUT_FLAG_NONE, 4918838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_FORMAT_INVALID); 492c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (output != AUDIO_IO_HANDLE_NONE) { 493c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 494c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!outputDesc->isDuplicated(), 495c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() RX device output is duplicated"); 496c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent outputDesc->toAudioPortConfig(&patch.sources[1]); 497c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sources = 2; 498c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 499c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 500c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 501c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, 0); 502c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOGW_IF(status != NO_ERROR, "updateCallRouting() error %d creating RX audio patch", 503c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent status); 504c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (status == NO_ERROR) { 505c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallRxPatch = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 506c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent &patch, mUidCached); 507c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallRxPatch->mAfPatchHandle = afPatchHandle; 508c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallRxPatch->mUid = mUidCached; 509c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 510c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent createTxPatch = true; 511c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 512c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (createTxPatch) { 513c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 514c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent struct audio_patch patch; 515c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sources = 1; 516c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sinks = 1; 517c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent deviceList = mAvailableInputDevices.getDevicesFromType(txDevice); 518c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!deviceList.isEmpty(), 519c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() selected device not in input device list"); 520c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<DeviceDescriptor> txSourceDeviceDesc = deviceList.itemAt(0); 521c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent txSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]); 522c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent deviceList = mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX); 523c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!deviceList.isEmpty(), 524c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() no telephony TX device"); 525c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<DeviceDescriptor> txSinkDeviceDesc = deviceList.itemAt(0); 526c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent txSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]); 527c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 528c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent SortedVector<audio_io_handle_t> outputs = 529c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent getOutputsForDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX, mOutputs); 5308838a3895c365d443ee22e169ccf45956780c081Eric Laurent audio_io_handle_t output = selectOutput(outputs, 5318838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_OUTPUT_FLAG_NONE, 5328838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_FORMAT_INVALID); 533c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // request to reuse existing output stream if one is already opened to reach the TX 534c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // path output device 535c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (output != AUDIO_IO_HANDLE_NONE) { 536c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 537c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!outputDesc->isDuplicated(), 538c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() RX device output is duplicated"); 539c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent outputDesc->toAudioPortConfig(&patch.sources[1]); 540c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sources = 2; 541c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 542c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 543c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 544c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, 0); 545c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOGW_IF(status != NO_ERROR, "setPhoneState() error %d creating TX audio patch", 546c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent status); 547c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (status == NO_ERROR) { 548c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallTxPatch = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 549c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent &patch, mUidCached); 550c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallTxPatch->mAfPatchHandle = afPatchHandle; 551c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallTxPatch->mUid = mUidCached; 552c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 553c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 554c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent} 555c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 556e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setPhoneState(audio_mode_t state) 557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() state %d", state); 5593b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state < 0 || state >= AUDIO_MODE_CNT) { 560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setPhoneState() invalid state %d", state); 561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (state == mPhoneState ) { 565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setPhoneState() setting same state %d", state); 566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if leaving call state, handle special case of active streams 570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // pertaining to sonification strategy see handleIncallSonification() 571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() in call state management: new state is %d", state); 5733b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 5743b73df74357b33869b39a1d69427673c780bd805Eric Laurent handleIncallSonification((audio_stream_type_t)stream, false, true); 575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // store previous phone state for management of sonification strategy below 579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int oldState = mPhoneState; 580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPhoneState = state; 581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force = false; 582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // are we entering or starting a call 584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isStateInCall(oldState) && isStateInCall(state)) { 585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Entering call in setPhoneState()"); 586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when starting a call 587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j]; 592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isStateInCall(oldState) && !isStateInCall(state)) { 594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Exiting call in setPhoneState()"); 595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when exiting a call 596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[AUDIO_STREAM_DTMF][j]; 601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isStateInCall(state) && (state != oldState)) { 603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when switching between telephony and VoIP 605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check for device and output changes triggered by new phone state 610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6141f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs = 0; 617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(state)) { 618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 6201f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute media and sonification strategies and delay device switch by the largest 622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // latency of any output where either strategy is active. 623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This avoid sending the ring tone or music tail into the earpiece or headset. 624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->isStrategyActive(STRATEGY_MEDIA, 625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime) || 627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->isStrategyActive(STRATEGY_SONIFICATION, 628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime)) && 630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (delayMs < (int)desc->mLatency*2)) { 631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs = desc->mLatency*2; 632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); 634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, 635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); 636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i)); 637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS, 638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/)); 639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 642c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // Note that despite the fact that getNewOutputDevice() is called on the primary output, 643c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // the device returned is not necessarily reachable via this output 644c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/); 645c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // force routing command to audio hardware when ending call 646c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // even if no device change is needed 647c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) { 648c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent rxDevice = hwOutputDesc->device(); 649c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 651c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (state == AUDIO_MODE_IN_CALL) { 652c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent updateCallRouting(rxDevice, delayMs); 653c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (oldState == AUDIO_MODE_IN_CALL) { 654c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mCallRxPatch != 0) { 655c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0); 656c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallRxPatch.clear(); 657c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 658c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mCallTxPatch != 0) { 659c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0); 660c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallTxPatch.clear(); 661c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 662c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent setOutputDevice(mPrimaryOutput, rxDevice, force, 0); 663c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else { 664c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent setOutputDevice(mPrimaryOutput, rxDevice, force, 0); 665c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if entering in call state, handle special case of active streams 667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // pertaining to sonification strategy see handleIncallSonification() 668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(state)) { 669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() in call state management: new state is %d", state); 6703b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 6713b73df74357b33869b39a1d69427673c780bd805Eric Laurent handleIncallSonification((audio_stream_type_t)stream, true, true); 672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 6763b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state == AUDIO_MODE_RINGTONE && 6773b73df74357b33869b39a1d69427673c780bd805Eric Laurent isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume = true; 679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume = false; 681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 684e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setForceUse(audio_policy_force_use_t usage, 6853b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_forced_cfg_t config) 686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool forceVolumeReeval = false; 690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(usage) { 6913b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_COMMUNICATION: 6923b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO && 6933b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NONE) { 694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 7003b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_MEDIA: 7013b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP && 7023b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 7033b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_ANALOG_DOCK && 7043b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE && 7050c94309d3c6db555b57f2e2e2dc3a0a2676ac6b7Jungshik Jang config != AUDIO_POLICY_FORCE_NO_BT_A2DP) { 706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 7113b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_RECORD: 7123b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 7133b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NONE) { 714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 7193b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_DOCK: 7203b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK && 7213b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_BT_DESK_DOCK && 7223b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 7233b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_ANALOG_DOCK && 7243b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) { 725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 7303b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_SYSTEM: 7313b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_NONE && 7323b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { 733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config); 734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 7387b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO: 7397b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang if (config != AUDIO_POLICY_FORCE_NONE && 7407b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) { 7417b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang ALOGW("setForceUse() invalid config %d forHDMI_SYSTEM_AUDIO", config); 7427b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang } 7437b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang mForceUse[usage] = config; 7447b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang break; 745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid usage %d", usage); 747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check for device and output changes triggered by new force usage 751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 754c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mPhoneState == AUDIO_MODE_IN_CALL) { 755c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/); 756c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent updateCallRouting(newDevice); 757c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 7601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t newDevice = getNewOutputDevice(output, true /*fromCache*/); 761c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if ((mPhoneState != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) { 762c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE)); 763c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) { 765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent applyStreamVolumes(output, newDevice, 0, true); 766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t activeInput = getActiveInput(); 770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (activeInput != 0) { 7711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setInputDevice(activeInput, getNewInputDevice(activeInput)); 772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 776e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage) 777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mForceUse[usage]; 779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 781e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setSystemProperty(const char* property, const char* value) 782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setSystemProperty() property %s, value %s", property, value); 784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Find a direct output profile compatible with the parameters passed, even if the input flags do 787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// not explicitly request a direct output 7881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::IOProfile> AudioPolicyManager::getProfileForDirectOutput( 789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_output_flags_t flags) 794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { 8001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j]; 801cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten bool found = profile->isCompatibleProfile(device, samplingRate, 802cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten NULL /*updatedSamplingRate*/, format, channelMask, 803cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD ? 804cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD : AUDIO_OUTPUT_FLAG_DIRECT); 8053a4311c68348f728558e87b5db67d47605783890Eric Laurent if (found && (mAvailableOutputDevices.types() & profile->mSupportedDevices.types())) { 8063a4311c68348f728558e87b5db67d47605783890Eric Laurent return profile; 8073a4311c68348f728558e87b5db67d47605783890Eric Laurent } 808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 813e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream, 814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 8173b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_output_flags_t flags, 818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const audio_offload_info_t *offloadInfo) 819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 8205bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 8213b73df74357b33869b39a1d69427673c780bd805Eric Laurent routing_strategy strategy = getStrategy(stream); 822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x", 824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, stream, samplingRate, format, channelMask, flags); 825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 8265bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return getOutputForDevice(device, stream, samplingRate,format, channelMask, flags, 8275bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi offloadInfo); 8285bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi} 8295bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 8305bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_io_handle_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr, 8315bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi uint32_t samplingRate, 8325bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_format_t format, 8335bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_channel_mask_t channelMask, 8345bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_output_flags_t flags, 8355bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi const audio_offload_info_t *offloadInfo) 8365bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{ 8375bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi if (attr == NULL) { 8385bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi ALOGE("getOutputForAttr() called with NULL audio attributes"); 8395bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return 0; 8405bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 84193c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x", 84293c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent attr->usage, attr->content_type, attr->tags, attr->flags); 8435bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 8445bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // TODO this is where filtering for custom policies (rerouting, dynamic sources) will go 8455bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi routing_strategy strategy = (routing_strategy) getStrategyForAttr(attr); 8465bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 84793c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent 84893c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent if ((attr->flags & AUDIO_FLAG_HW_AV_SYNC) != 0) { 84993c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC); 85093c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent } 85193c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent 8525bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi ALOGV("getOutputForAttr() device %d, samplingRate %d, format %x, channelMask %x, flags %x", 8535bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi device, samplingRate, format, channelMask, flags); 8545bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 8555bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_stream_type_t stream = streamTypefromAttributesInt(attr); 8565bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return getOutputForDevice(device, stream, samplingRate, format, channelMask, flags, 8575bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi offloadInfo); 8585bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi} 8595bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 8605bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_io_handle_t AudioPolicyManager::getOutputForDevice( 8615bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_devices_t device, 8625bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_stream_type_t stream, 8635bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi uint32_t samplingRate, 8645bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_format_t format, 8655bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_channel_mask_t channelMask, 8665bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_output_flags_t flags, 8675bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi const audio_offload_info_t *offloadInfo) 8685bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{ 869cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; 8705bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi uint32_t latency = 0; 871cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status; 8725bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mCurOutput != 0) { 875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", 876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTestOutputs[mCurOutput] == 0) { 879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() opening test output"); 8801f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL); 881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = mTestDevice; 882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency = mTestLatencyMs; 8833b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc->mFlags = 8843b73df74357b33869b39a1d69427673c780bd805Eric Laurent (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0); 885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mRefCount[stream] = 0; 886cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 887cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = mTestSamplingRate; 888cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = mTestChannels; 889cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = mTestFormat; 89077cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk if (offloadInfo != NULL) { 89177cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk config.offload_info = *offloadInfo; 89277cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk } 893cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status = mpClientInterface->openOutput(0, 894cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &mTestOutputs[mCurOutput], 895cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 896cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mDevice, 897cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent String8(""), 898cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mLatency, 899cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFlags); 900cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status == NO_ERROR) { 901cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mSamplingRate = config.sample_rate; 902cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFormat = config.format; 903cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mChannelMask = config.channel_mask; 904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"),mCurOutput); 906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(mTestOutputs[mCurOutput], outputDesc); 908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mTestOutputs[mCurOutput]; 911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open a direct output if required by specified parameters 915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //force direct flag if offload flag is set: offloading implies a direct output stream 916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and all common behaviors are driven by checking only the direct flag 917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this should normally be set appropriately in the policy configuration file 918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 9193b73df74357b33869b39a1d69427673c780bd805Eric Laurent flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT); 920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 92193c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) { 92293c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT); 92393c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent } 924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // detects there is an active non offloadable effect. 928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the background. 9311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile; 932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) || 933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent !isNonOffloadableEffectEnabled()) { 934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile = getProfileForDirectOutput(device, 935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, 936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent format, 937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, 938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (audio_output_flags_t)flags); 939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 9411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (profile != 0) { 9421f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = NULL; 943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 9451f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && (profile == desc->mProfile)) { 947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc = desc; 948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // reuse direct output if currently open and configured with same parameters 949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((samplingRate == outputDesc->mSamplingRate) && 950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (format == outputDesc->mFormat) && 951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (channelMask == outputDesc->mChannelMask)) { 952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDirectOpenCount++; 953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i)); 954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutputs.keyAt(i); 955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // close direct output if currently open and configured with different parameters 959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc != NULL) { 9601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent closeOutput(outputDesc->mIoHandle); 961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc = new AudioOutputDescriptor(profile); 963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = device; 964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency = 0; 965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags); 966cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 967cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = samplingRate; 968cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = channelMask; 969cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = format; 97077cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk if (offloadInfo != NULL) { 97177cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk config.offload_info = *offloadInfo; 97277cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk } 973cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status = mpClientInterface->openOutput(profile->mModule->mHandle, 974cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &output, 975cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 976cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mDevice, 977cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent String8(""), 978cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mLatency, 979cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFlags); 980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // only accept an output with the requested parameters 982cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status != NO_ERROR || 983cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (samplingRate != 0 && samplingRate != config.sample_rate) || 984cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (format != AUDIO_FORMAT_DEFAULT && format != config.format) || 985cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (channelMask != 0 && channelMask != config.channel_mask)) { 986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," 987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "format %d %d, channelMask %04x %04x", output, samplingRate, 988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, 989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mChannelMask); 990cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (output != AUDIO_IO_HANDLE_NONE) { 991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 993cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent return AUDIO_IO_HANDLE_NONE; 994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 995cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mSamplingRate = config.sample_rate; 996cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mChannelMask = config.channel_mask; 997cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFormat = config.format; 998cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mRefCount[stream] = 0; 999cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mStopTime[stream] = 0; 1000cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mDirectOpenCount = 1; 1001cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent 1002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t srcOutput = getOutputForEffect(); 1003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, outputDesc); 1004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 1005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dstOutput == output) { 1006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput); 1007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 1009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() returns new direct output %d", output); 1010b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 1011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 1012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ignoring channel mask due to downmix capability in mixer 1015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open a non direct output 1017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // for non direct outputs, only PCM is supported 1019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_linear_pcm(format)) { 1020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // get which output is suitable for the specified stream. The actual 1021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // routing change will happen when startOutput() will be called 1022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs); 1023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 10248838a3895c365d443ee22e169ccf45956780c081Eric Laurent // at this stage we should ignore the DIRECT flag as no direct output could be found earlier 10258838a3895c365d443ee22e169ccf45956780c081Eric Laurent flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT); 10268838a3895c365d443ee22e169ccf45956780c081Eric Laurent output = selectOutput(outputs, flags, format); 1027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d," 1029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); 1030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() returns output %d", output); 1032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 1034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1036e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs, 10378838a3895c365d443ee22e169ccf45956780c081Eric Laurent audio_output_flags_t flags, 10388838a3895c365d443ee22e169ccf45956780c081Eric Laurent audio_format_t format) 1039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // select one output among several that provide a path to a particular device or set of 1041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // devices (the list was previously build by getOutputsForDevice()). 1042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The priority is as follows: 1043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: the output with the highest number of requested policy flags 1044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: the primary output 1045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the first output in the list 1046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 0) { 1048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 1) { 1051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 1052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int maxCommonFlags = 0; 1055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputFlags = 0; 1056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputPrimary = 0; 1057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 10591f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); 1060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputDesc->isDuplicated()) { 10618838a3895c365d443ee22e169ccf45956780c081Eric Laurent // if a valid format is specified, skip output if not compatible 10628838a3895c365d443ee22e169ccf45956780c081Eric Laurent if (format != AUDIO_FORMAT_INVALID) { 10638838a3895c365d443ee22e169ccf45956780c081Eric Laurent if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { 10648838a3895c365d443ee22e169ccf45956780c081Eric Laurent if (format != outputDesc->mFormat) { 10658838a3895c365d443ee22e169ccf45956780c081Eric Laurent continue; 10668838a3895c365d443ee22e169ccf45956780c081Eric Laurent } 10678838a3895c365d443ee22e169ccf45956780c081Eric Laurent } else if (!audio_is_linear_pcm(format)) { 10688838a3895c365d443ee22e169ccf45956780c081Eric Laurent continue; 10698838a3895c365d443ee22e169ccf45956780c081Eric Laurent } 10708838a3895c365d443ee22e169ccf45956780c081Eric Laurent } 10718838a3895c365d443ee22e169ccf45956780c081Eric Laurent 10723b73df74357b33869b39a1d69427673c780bd805Eric Laurent int commonFlags = popcount(outputDesc->mProfile->mFlags & flags); 1073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (commonFlags > maxCommonFlags) { 1074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputFlags = outputs[i]; 1075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent maxCommonFlags = commonFlags; 1076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); 1077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 1079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputPrimary = outputs[i]; 1080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputFlags != 0) { 1085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputFlags; 1086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputPrimary != 0) { 1088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputPrimary; 1089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 1092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1094e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startOutput(audio_io_handle_t output, 10953b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream, 1096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session) 1097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 1099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 1100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startOutput() unknown output %d", output); 1102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 11051f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); 1106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // increment usage count for this stream on the requested output: 1108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // NOTE that the usage count is the same for duplicated output and hardware output which is 1109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // necessary for a correct control of hardware output routing by startOutput() and stopOutput() 1110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->changeRefCount(stream, 1); 1111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] == 1) { 11131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); 1114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent routing_strategy strategy = getStrategy(stream); 1115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool shouldWait = (strategy == STRATEGY_SONIFICATION) || 1116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (strategy == STRATEGY_SONIFICATION_RESPECTFUL); 1117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t waitMs = 0; 1118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force = false; 1119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 11201f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 1121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc != outputDesc) { 1122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force a device change if any other output is managed by the same hw 1123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // module and has a current device selection that differs from selected device. 1124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // In this case, the audio HAL must receive the new device selection so that it can 1125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // change the device currently selected by the other active output. 1126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->sharesHwModuleWith(desc) && 1127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->device() != newDevice) { 1128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 1129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // wait for audio on other active outputs to be presented when starting 1131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // a notification so that audio focus effect can propagate. 1132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t latency = desc->latency(); 1133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { 1134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent waitMs = latency; 1135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); 1139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle special case for sonification while in call 1141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 1142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleIncallSonification(stream, true, false); 1143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // apply volume rules for current stream and device if necessary 1146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 1147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].getVolumeIndex(newDevice), 1148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 1149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent newDevice); 1150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update the outputs if starting an output with a stream that can affect notification 1152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // routing 1153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleNotificationRoutingForStream(stream); 1154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (waitMs > muteWaitMs) { 1155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent usleep((waitMs - muteWaitMs) * 2 * 1000); 1156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1162e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopOutput(audio_io_handle_t output, 11633b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream, 1164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session) 1165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 1167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 1168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopOutput() unknown output %d", output); 1170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 11731f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); 1174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle special case for sonification while in call 1176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 1177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleIncallSonification(stream, false, false); 1178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] > 0) { 1181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // decrement usage count of this stream on the output 1182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->changeRefCount(stream, -1); 1183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // store time at which the stream was stopped - see isStreamActive() 1184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] == 0) { 1185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStopTime[stream] = systemTime(); 11861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); 1187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // delay the device switch by twice the latency because stopOutput() is executed when 1188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the track stop() command is received and at that time the audio track buffer can 1189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // still contain data that needs to be drained. The latency only covers the audio HAL 1190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and kernel buffers. Also the latency does not always include additional delay in the 1191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // audio path (audio DSP, CODEC ...) 1192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); 1193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force restoring the device selection on other active outputs if it differs from the 1195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // one being selected for this output 1196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(i); 11981f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 1199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (curOutput != output && 1200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->isActive() && 1201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->sharesHwModuleWith(desc) && 1202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (newDevice != desc->device())) { 1203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(curOutput, 12041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent getNewOutputDevice(curOutput, false /*fromCache*/), 1205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent true, 1206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency*2); 1207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update the outputs if stopping one with a stream that can affect notification routing 1210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleNotificationRoutingForStream(stream); 1211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopOutput() refcount is already 0 for output %d", output); 1215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1219e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::releaseOutput(audio_io_handle_t output) 1220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseOutput() %d", output); 1222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 1223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseOutput() releasing unknown output %d", output); 1225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int testIndex = testOutputIndex(output); 1230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (testIndex != 0) { 12311f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); 1232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isActive()) { 1233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 1234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(output); 1235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[testIndex] = 0; 1236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 12411f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(index); 12423b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { 1243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->mDirectOpenCount <= 0) { 1244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseOutput() invalid open count %d for output %d", 1245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mDirectOpenCount, output); 1246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (--desc->mDirectOpenCount == 0) { 1249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent closeOutput(output); 1250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // If effects where present on the output, audioflinger moved them to the primary 1251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // output by default: move them back to the appropriate output. 1252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 1253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dstOutput != mPrimaryOutput) { 1254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput); 1255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1256b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 1257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1262e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, 1263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 1264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 1265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 12664dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent audio_session_t session, 12676a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten audio_input_flags_t flags) 1268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 12694dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, session %d, " 12706a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten "flags %#x", 12714dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent inputSource, samplingRate, format, channelMask, session, flags); 1272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 12736a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten audio_devices_t device = getDeviceForInputSource(inputSource); 1274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 1276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getInput() could not find device for inputSource %d", inputSource); 1277cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent return AUDIO_IO_HANDLE_NONE; 1278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // adapt channel selection to input source 12816a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten switch (inputSource) { 1282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 1283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK; 1284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_DOWNLINK: 1286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK; 1287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_CALL: 1289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK; 1290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 1292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 1293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 12951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = getInputProfile(device, 1296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, 1297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent format, 12986a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten channelMask, 12996a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten flags); 13001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (profile == 0) { 13016a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten ALOGW("getInput() could not find profile for device 0x%X, samplingRate %u, format %#x, " 13026a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten "channelMask 0x%X, flags %#x", 13036a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten device, samplingRate, format, channelMask, flags); 1304cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent return AUDIO_IO_HANDLE_NONE; 1305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mModule->mHandle == 0) { 1308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); 1309cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent return AUDIO_IO_HANDLE_NONE; 1310cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent } 1311cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent 1312cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 1313cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = samplingRate; 1314cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = channelMask; 1315cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = format; 1316cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; 1317df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 1318df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent bool isSoundTrigger = false; 13191c9c2cc4b170b79a83433749808e286eb0fcc449Eric Laurent audio_source_t halInputSource = inputSource; 1320df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (inputSource == AUDIO_SOURCE_HOTWORD) { 1321df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ssize_t index = mSoundTriggerSessions.indexOfKey(session); 1322df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (index >= 0) { 1323df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent input = mSoundTriggerSessions.valueFor(session); 1324df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent isSoundTrigger = true; 1325df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGV("SoundTrigger capture on session %d input %d", session, input); 13261c9c2cc4b170b79a83433749808e286eb0fcc449Eric Laurent } else { 13271c9c2cc4b170b79a83433749808e286eb0fcc449Eric Laurent halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION; 1328df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 1329df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 1330cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status = mpClientInterface->openInput(profile->mModule->mHandle, 1331cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &input, 1332cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 1333cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &device, 1334cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent String8(""), 13351c9c2cc4b170b79a83433749808e286eb0fcc449Eric Laurent halInputSource, 1336cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent flags); 1337cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent 1338cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent // only accept input with the exact requested set of parameters 1339cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status != NO_ERROR || 1340cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (samplingRate != config.sample_rate) || 1341cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (format != config.format) || 1342cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (channelMask != config.channel_mask)) { 1343cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent ALOGW("getInput() failed opening input: samplingRate %d, format %d, channelMask %x", 1344cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent samplingRate, format, channelMask); 1345cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (input != AUDIO_IO_HANDLE_NONE) { 1346cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent mpClientInterface->closeInput(input); 1347cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent } 1348cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent return AUDIO_IO_HANDLE_NONE; 1349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 13511f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile); 1352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mInputSource = inputSource; 1353cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent inputDesc->mRefCount = 0; 1354cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent inputDesc->mOpenRefCount = 1; 1355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mSamplingRate = samplingRate; 1356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mFormat = format; 1357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mChannelMask = channelMask; 1358cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent inputDesc->mDevice = device; 13594dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent inputDesc->mSessions.add(session); 1360df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent inputDesc->mIsSoundTrigger = isSoundTrigger; 1361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1362d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addInput(input, inputDesc); 1363b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 1364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return input; 1365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 13674dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentstatus_t AudioPolicyManager::startInput(audio_io_handle_t input, 13684dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent audio_session_t session) 1369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("startInput() input %d", input); 1371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startInput() unknown input %d", input); 1374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 13761f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); 1377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 13784dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent index = inputDesc->mSessions.indexOf(session); 13794dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent if (index < 0) { 13804dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent ALOGW("startInput() unknown session %d on input %d", session, input); 13814dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent return BAD_VALUE; 13824dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent } 13834dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent 138474a8e2533561f04029873446206ab407cd2e033bGlenn Kasten // virtual input devices are compatible with other input devices 138574a8e2533561f04029873446206ab407cd2e033bGlenn Kasten if (!isVirtualInputDevice(inputDesc->mDevice)) { 138674a8e2533561f04029873446206ab407cd2e033bGlenn Kasten 138774a8e2533561f04029873446206ab407cd2e033bGlenn Kasten // for a non-virtual input device, check if there is another (non-virtual) active input 1388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t activeInput = getActiveInput(); 138974a8e2533561f04029873446206ab407cd2e033bGlenn Kasten if (activeInput != 0 && activeInput != input) { 139074a8e2533561f04029873446206ab407cd2e033bGlenn Kasten 139174a8e2533561f04029873446206ab407cd2e033bGlenn Kasten // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed, 139274a8e2533561f04029873446206ab407cd2e033bGlenn Kasten // otherwise the active input continues and the new input cannot be started. 13931f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput); 1394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) { 139574a8e2533561f04029873446206ab407cd2e033bGlenn Kasten ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput); 13964dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent stopInput(activeInput, activeDesc->mSessions.itemAt(0)); 13974dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent releaseInput(activeInput, activeDesc->mSessions.itemAt(0)); 1398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 139974a8e2533561f04029873446206ab407cd2e033bGlenn Kasten ALOGE("startInput(%d) failed: other input %d already started", input, activeInput); 1400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 140574a8e2533561f04029873446206ab407cd2e033bGlenn Kasten if (inputDesc->mRefCount == 0) { 1406df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (activeInputsCount() == 0) { 1407df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent SoundTrigger::setCaptureState(true); 1408df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 140974a8e2533561f04029873446206ab407cd2e033bGlenn Kasten setInputDevice(input, getNewInputDevice(input), true /* force */); 1410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 141174a8e2533561f04029873446206ab407cd2e033bGlenn Kasten // Automatically enable the remote submix output when input is started. 141274a8e2533561f04029873446206ab407cd2e033bGlenn Kasten // For remote submix (a virtual device), we open only one input per capture request. 141374a8e2533561f04029873446206ab407cd2e033bGlenn Kasten if (audio_is_remote_submix_device(inputDesc->mDevice)) { 141474a8e2533561f04029873446206ab407cd2e033bGlenn Kasten setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 141574a8e2533561f04029873446206ab407cd2e033bGlenn Kasten AUDIO_POLICY_DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 141674a8e2533561f04029873446206ab407cd2e033bGlenn Kasten } 1417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 1420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14216a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten inputDesc->mRefCount++; 1422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14254dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentstatus_t AudioPolicyManager::stopInput(audio_io_handle_t input, 14264dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent audio_session_t session) 1427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("stopInput() input %d", input); 1429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopInput() unknown input %d", input); 1432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 14341f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); 1435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14364dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent index = inputDesc->mSessions.indexOf(session); 14374dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent if (index < 0) { 14384dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent ALOGW("stopInput() unknown session %d on input %d", session, input); 14394dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent return BAD_VALUE; 14404dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent } 14414dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent 1442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (inputDesc->mRefCount == 0) { 1443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopInput() input %d already stopped", input); 1444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 14456a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten } 14466a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten 14476a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten inputDesc->mRefCount--; 14486a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten if (inputDesc->mRefCount == 0) { 14496a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten 1450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // automatically disable the remote submix output when input is stopped 1451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 14533b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); 1454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent resetInputDevice(input); 1457df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 1458df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (activeInputsCount() == 0) { 1459df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent SoundTrigger::setCaptureState(false); 1460df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 1461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 14626a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten return NO_ERROR; 1463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14654dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentvoid AudioPolicyManager::releaseInput(audio_io_handle_t input, 14664dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent audio_session_t session) 1467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseInput() %d", input); 1469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseInput() releasing unknown input %d", input); 1472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 14746a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); 14756a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten ALOG_ASSERT(inputDesc != 0); 14764dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent 14774dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent index = inputDesc->mSessions.indexOf(session); 14784dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent if (index < 0) { 14794dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent ALOGW("releaseInput() unknown session %d on input %d", session, input); 14804dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent return; 14814dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent } 14824dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent inputDesc->mSessions.remove(session); 14836a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten if (inputDesc->mOpenRefCount == 0) { 14846a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten ALOGW("releaseInput() invalid open ref count %d", inputDesc->mOpenRefCount); 14856a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten return; 14866a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten } 14876a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten inputDesc->mOpenRefCount--; 14886a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten if (inputDesc->mOpenRefCount > 0) { 14896a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten ALOGV("releaseInput() exit > 0"); 14906a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten return; 14916a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten } 14926a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten 149305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent closeInput(input); 1494b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 1495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseInput() exit"); 1496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1498d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::closeAllInputs() { 149905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent bool patchRemoved = false; 150005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 1501d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for(size_t input_index = 0; input_index < mInputs.size(); input_index++) { 150205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index); 150305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 150405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent if (patch_index >= 0) { 150505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index); 150605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 150705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mAudioPatches.removeItemsAt(patch_index); 150805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent patchRemoved = true; 150905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent } 1510d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeInput(mInputs.keyAt(input_index)); 1511d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 1512d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mInputs.clear(); 15136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 151405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 151505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent if (patchRemoved) { 151605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 151705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent } 1518d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 1519d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 1520e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initStreamVolume(audio_stream_type_t stream, 1521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexMin, 1522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexMax) 1523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 1525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (indexMin < 0 || indexMin >= indexMax) { 1526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 1527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexMin = indexMin; 1530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexMax = indexMax; 1531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1533e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream, 1534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 1535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 1536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 1539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device)) { 1542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force max volume if stream cannot be muted 1546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 1547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", 1549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, device, index); 1550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 1552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // clear all device specific values 1553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexCur.clear(); 1555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 1557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // compute and apply stream volume on all outputs according to connected device 1559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t status = NO_ERROR; 1560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t curDevice = 1562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForVolume(mOutputs.valueAt(i)->device()); 1563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) { 1564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); 1565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volStatus != NO_ERROR) { 1566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = volStatus; 1567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return status; 1571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1573e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream, 1574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int *index, 1575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 1576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index == NULL) { 1578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device)) { 1581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 1584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the strategy the stream belongs to. 1585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); 1587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForVolume(device); 1589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 1591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 1592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1595e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutputForEffects( 1596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const SortedVector<audio_io_handle_t>& outputs) 1597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // select one output among several suitable for global effects. 1599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The priority is as follows: 1600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: An offloaded output. If the effect ends up not being offloadable, 1601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // AudioFlinger will invalidate the track and the offloaded output 1602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // will be closed causing the effect to be moved to a PCM output. 1603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: A deep buffer output 1604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the first output in the list 1605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 0) { 1607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputOffloaded = 0; 1611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputDeepBuffer = 0; 1612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 16141f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]); 1615d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags); 1616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 1617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputOffloaded = outputs[i]; 1618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) { 1620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDeepBuffer = outputs[i]; 1621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d", 1625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputOffloaded, outputDeepBuffer); 1626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputOffloaded != 0) { 1627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputOffloaded; 1628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDeepBuffer != 0) { 1630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputDeepBuffer; 1631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 1634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1636e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc) 1637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // apply simple rule where global effects are attached to the same output as MUSIC streams 1639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16403b73df74357b33869b39a1d69427673c780bd805Eric Laurent routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC); 1641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 1642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs); 1643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = selectOutputForEffects(dstOutputs); 1645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutputForEffect() got output %d for fx %s flags %x", 1646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, (desc == NULL) ? "unspecified" : desc->name, (desc == NULL) ? 0 : desc->flags); 1647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 1649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1651e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc, 1652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t io, 1653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t strategy, 1654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session, 1655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int id) 1656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 1658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent index = mInputs.indexOfKey(io); 1660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("registerEffect() unknown io %d", io); 1662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 1667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 1668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->name, desc->memoryUsage); 1669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsMemory += desc->memoryUsage; 1672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 1673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->name, io, strategy, session, id); 1674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 1675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16761f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = new EffectDescriptor(); 16771f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t)); 16781f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mIo = io; 16791f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mStrategy = (routing_strategy)strategy; 16801f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mSession = session; 16811f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mEnabled = false; 1682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16831f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mEffects.add(id, effectDesc); 1684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1688e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::unregisterEffect(int id) 1689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() unknown effect ID %d", id); 1693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16961f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = mEffects.valueAt(index); 1697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16981f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent setEffectEnabled(effectDesc, false); 1699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 17001f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (mTotalEffectsMemory < effectDesc->mDesc.memoryUsage) { 1701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() memory %d too big for total %d", 17021f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.memoryUsage, mTotalEffectsMemory); 17031f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.memoryUsage = mTotalEffectsMemory; 1704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 17051f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mTotalEffectsMemory -= effectDesc->mDesc.memoryUsage; 1706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 17071f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.name, id, effectDesc->mDesc.memoryUsage, mTotalEffectsMemory); 1708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.removeItem(id); 1710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1714e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(int id, bool enabled) 1715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() unknown effect ID %d", id); 1719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 1723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 17251f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(const sp<EffectDescriptor>& effectDesc, bool enabled) 1726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 17271f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (enabled == effectDesc->mEnabled) { 1728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(%s) effect already %s", 1729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 1730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (enabled) { 17341f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (mTotalEffectsCpuLoad + effectDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 1735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 17361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.name, (float)effectDesc->mDesc.cpuLoad/10); 1737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 17391f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mTotalEffectsCpuLoad += effectDesc->mDesc.cpuLoad; 1740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 1741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 17421f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (mTotalEffectsCpuLoad < effectDesc->mDesc.cpuLoad) { 1743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 17441f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 17451f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 1746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 17471f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mTotalEffectsCpuLoad -= effectDesc->mDesc.cpuLoad; 1748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 1749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 17501f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mEnabled = enabled; 1751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1754e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isNonOffloadableEffectEnabled() 1755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 17571f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = mEffects.valueAt(i); 17581f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) && 17591f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) { 1760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d", 17611f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.name, effectDesc->mSession); 1762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1768e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 1769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 1771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 17721f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); 17733b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 1774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1780e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, 17813b73df74357b33869b39a1d69427673c780bd805Eric Laurent uint32_t inPastMs) const 1782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 1784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 17851f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); 1786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 17873b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 1788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1794e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isSourceActive(audio_source_t source) const 1795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 17971f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i); 1798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((inputDescriptor->mInputSource == (int)source || 17993b73df74357b33869b39a1d69427673c780bd805Eric Laurent (source == AUDIO_SOURCE_VOICE_RECOGNITION && 1800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) 1801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent && (inputDescriptor->mRefCount > 0)) { 1802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 1803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1809e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::dump(int fd) 1810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 1812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 1813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 1814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 1816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 1817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput); 1819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 1820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 1821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 18223b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for communications %d\n", 18233b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]); 1824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 18253b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA]); 1826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 18273b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD]); 1828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 18293b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK]); 1830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 18313b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM]); 1832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 18337b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n", 18347b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO]); 18357b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang result.append(buffer); 1836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 18373a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, " Available output devices:\n"); 18383a4311c68348f728558e87b5db67d47605783890Eric Laurent result.append(buffer); 18393a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, result.string(), result.size()); 18403a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) { 18411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableOutputDevices[i]->dump(fd, 2, i); 18423a4311c68348f728558e87b5db67d47605783890Eric Laurent } 18433a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, "\n Available input devices:\n"); 18443a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, buffer, strlen(buffer)); 18453a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size(); i++) { 18461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableInputDevices[i]->dump(fd, 2, i); 18473a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 1850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 1852d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1); 1853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules[i]->dump(fd); 1855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nOutputs dump:\n"); 1858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 1861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.valueAt(i)->dump(fd); 1863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nInputs dump:\n"); 1866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 1868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 1869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputs.valueAt(i)->dump(fd); 1871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nStreams dump:\n"); 1874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, 1876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 1877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1878beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn for (size_t i = 0; i < AUDIO_STREAM_CNT; i++) { 1879d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " %02zu ", i); 1880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[i].dump(fd); 1882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 1885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 1886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "Registered effects:\n"); 1889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 1891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 1892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 1893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.valueAt(i)->dump(fd); 1894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 18964d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "\nAudio Patches:\n"); 18974d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent write(fd, buffer, strlen(buffer)); 18984d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent for (size_t i = 0; i < mAudioPatches.size(); i++) { 18994d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mAudioPatches[i]->dump(fd, 2, i); 19004d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } 1901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This function checks for the parameters which can be offloaded. 1906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This can be enhanced depending on the capability of the DSP and policy 1907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// of the system. 1908e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo) 1909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d," 1911d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent " BitRate=%u, duration=%" PRId64 " us, has_video=%d", 1912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate, offloadInfo.channel_mask, 1913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format, 1914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us, 1915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.has_video); 1916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check if offload has been disabled 1918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char propValue[PROPERTY_VALUE_MAX]; 1919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (property_get("audio.offload.disable", propValue, "0")) { 1920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (atoi(propValue) != 0) { 1921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("offload disabled by audio.offload.disable=%s", propValue ); 1922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check if stream type is music, then only allow offload as of now. 1927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC) 1928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: stream_type != MUSIC, returning false"); 1930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //TODO: enable audio offloading with video when ready 1934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.has_video) 1935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 1936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: has_video == true, returning false"); 1937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //If duration is less than minimum value defined in property, return false 1941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (property_get("audio.offload.min.duration.secs", propValue, NULL)) { 1942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) { 1943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue); 1944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) { 1947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS); 1948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 1952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 1953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // detects there is an active non offloadable effect. 1954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 1955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 1956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the background. 1957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isNonOffloadableEffectEnabled()) { 1958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 1959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // See if there is a profile to support this. 1962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // AUDIO_DEVICE_NONE 19631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */, 1964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate, 1965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format, 1966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.channel_mask, 1967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD); 19681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT "); 19691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return (profile != 0); 1970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPorts(audio_port_role_t role, 19736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_type_t type, 19746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent unsigned int *num_ports, 19756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port *ports, 19766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent unsigned int *generation) 19776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 19786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (num_ports == NULL || (*num_ports != 0 && ports == NULL) || 19796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent generation == NULL) { 19806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 19816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports); 19836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (ports == NULL) { 19846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports = 0; 19856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 19876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t portsWritten = 0; 19886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t portsMax = *num_ports; 19896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports = 0; 19906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) { 19916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) { 19926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; 19936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i < mAvailableOutputDevices.size() && portsWritten < portsMax; i++) { 19946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]); 19956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports += mAvailableOutputDevices.size(); 19976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 19986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) { 19996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; 20006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i < mAvailableInputDevices.size() && portsWritten < portsMax; i++) { 20016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]); 20026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports += mAvailableInputDevices.size(); 20046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) { 20076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) { 20086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++) { 20096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mInputs[i]->toAudioPort(&ports[portsWritten++]); 20106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports += mInputs.size(); 20126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) { 201484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent size_t numOutputs = 0; 201584c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 201684c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent if (!mOutputs[i]->isDuplicated()) { 201784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent numOutputs++; 201884c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent if (portsWritten < portsMax) { 201984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent mOutputs[i]->toAudioPort(&ports[portsWritten++]); 202084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent } 202184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent } 20226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 202384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent *num_ports += numOutputs; 20246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *generation = curAudioPortGeneration(); 2027beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPorts() got %zu ports needed %d", portsWritten, *num_ports); 20286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 20296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 20306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused) 20326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 20336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 20346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 20356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp<AudioPolicyManager::AudioOutputDescriptor> AudioPolicyManager::getOutputFromId( 20376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_handle_t id) const 20386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 20391f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = NULL; 20406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 20416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent outputDesc = mOutputs.valueAt(i); 20426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc->mId == id) { 20436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 20446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return outputDesc; 20476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 20486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20491f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp<AudioPolicyManager::AudioInputDescriptor> AudioPolicyManager::getInputFromId( 20506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_handle_t id) const 20516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 20521f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = NULL; 20536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 20546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent inputDesc = mInputs.valueAt(i); 20556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (inputDesc->mId == id) { 20566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 20576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return inputDesc; 20606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 20616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20621f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleForDevice( 20631f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent audio_devices_t device) const 20646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 20651f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp <HwModule> module; 20661f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 20676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 20686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (mHwModules[i]->mHandle == 0) { 20696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent continue; 20706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (audio_is_output_device(device)) { 20726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 20736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent { 20746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) { 20756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return mHwModules[i]; 20766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 20796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) { 20806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (mHwModules[i]->mInputProfiles[j]->mSupportedDevices.types() & 20816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent device & ~AUDIO_DEVICE_BIT_IN) { 20826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return mHwModules[i]; 20836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 20871f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent return module; 20886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 20896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 20901f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleFromName(const char *name) const 20911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 20921f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp <HwModule> module; 20931f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 20941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 20951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent { 20961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(mHwModules[i]->mName, name) == 0) { 20971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return mHwModules[i]; 20981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 20991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 21001f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent return module; 21011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 21021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 2103c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurentaudio_devices_t AudioPolicyManager::availablePrimaryOutputDevices() 2104c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent{ 2105c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput); 2106c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types(); 2107c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent return devices & mAvailableOutputDevices.types(); 2108c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent} 2109c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 2110c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurentaudio_devices_t AudioPolicyManager::availablePrimaryInputDevices() 2111c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent{ 2112c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_module_handle_t primaryHandle = 2113c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mOutputs.valueFor(mPrimaryOutput)->mProfile->mModule->mHandle; 2114c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t devices = AUDIO_DEVICE_NONE; 2115c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size(); i++) { 2116c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mAvailableInputDevices[i]->mModule->mHandle == primaryHandle) { 2117c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent devices |= mAvailableInputDevices[i]->mDeviceType; 2118c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 2119c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 2120c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent return devices; 2121c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent} 21221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 21236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, 21246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *handle, 21256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent uid_t uid) 21266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 21276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch()"); 21286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 21296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (handle == NULL || patch == NULL) { 21306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 21316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 21326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks); 21336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2134874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX || 2135874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) { 2136874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return BAD_VALUE; 2137874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2138874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // only one source per audio patch supported for now 2139874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->num_sources > 1) { 21406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 21416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 2142874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 2143874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->sources[0].role != AUDIO_PORT_ROLE_SOURCE) { 21446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 21456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 2146874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent for (size_t i = 0; i < patch->num_sinks; i++) { 2147874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->sinks[i].role != AUDIO_PORT_ROLE_SINK) { 2148874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2149874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2150874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 21516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 21526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc; 21536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(*handle); 21546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 21556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch source id %d role %d type %d", patch->sources[0].id, 21566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sources[0].role, 21576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sources[0].type); 2158874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent#if LOG_NDEBUG == 0 2159874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent for (size_t i = 0; i < patch->num_sinks; i++) { 2160874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent ALOGV("createAudioPatch sink %d: id %d role %d type %d", i, patch->sinks[i].id, 2161874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->sinks[i].role, 2162874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->sinks[i].type); 2163874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2164874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent#endif 21656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 21666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 21676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 21686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() mUidCached %d patchDesc->mUid %d uid %d", 21696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mUidCached, patchDesc->mUid, uid); 21706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) { 21716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 21726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 21736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 21746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *handle = 0; 21756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 21766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 21776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) { 21781f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id); 21796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc == NULL) { 21806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id); 21816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 21826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 218384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!outputDesc->isDuplicated(),"duplicated output %d in source in ports", 218484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent outputDesc->mIoHandle); 21856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0) { 21866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) { 21876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() source id differs for patch current id %d new id %d", 21886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch.sources[0].id, patch->sources[0].id); 21896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 21906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 21916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 2192874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent DeviceVector devices; 2193874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent for (size_t i = 0; i < patch->num_sinks; i++) { 2194874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // Only support mix to devices connection 2195874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // TODO add support for mix to mix connection 2196874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) { 2197874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent ALOGV("createAudioPatch() source mix but sink is not a device"); 2198874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2199874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2200874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent sp<DeviceDescriptor> devDesc = 2201874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id); 2202874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (devDesc == 0) { 2203874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent ALOGV("createAudioPatch() out device not found for id %d", patch->sinks[i].id); 2204874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return BAD_VALUE; 2205874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 22066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2207874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (!outputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType, 2208874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->sources[0].sample_rate, 2209874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent NULL, // updatedSamplingRate 2210874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->sources[0].format, 2211874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->sources[0].channel_mask, 2212874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) { 2213874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent ALOGV("createAudioPatch() profile not supported for device %08x", 2214874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent devDesc->mDeviceType); 2215874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2216874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2217874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent devices.add(devDesc); 2218874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2219874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (devices.size() == 0) { 22206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 22216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 2222874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 22236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // TODO: reconfigure output format and channels here 22246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() setting device %08x on output %d", 2225874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent devices.types(), outputDesc->mIoHandle); 2226874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent setOutputDevice(outputDesc->mIoHandle, devices.types(), true, 0, handle); 22276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*handle); 22286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 22296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) { 22306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setOutputDevice() did not reuse the patch provided"); 22316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 22326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 22336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = uid; 22346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() success"); 22356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 22366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setOutputDevice() failed to create a patch"); 22376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 22386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 22396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) { 22406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { 22416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // input device to input mix connection 2242874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // only one sink supported when connecting an input device to a mix 2243874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->num_sinks > 1) { 2244874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2245874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 22461f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id); 22476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (inputDesc == NULL) { 22486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 22496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 22506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0) { 22516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) { 22526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 22536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 22546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 22556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<DeviceDescriptor> devDesc = 22566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices.getDeviceFromId(patch->sources[0].id); 22576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (devDesc == 0) { 22586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 22596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 22606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 226184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent if (!inputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType, 2262cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten patch->sinks[0].sample_rate, 2263cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten NULL, /*updatedSampleRate*/ 22646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sinks[0].format, 22656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sinks[0].channel_mask, 22666a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten // FIXME for the parameter type, 22676a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten // and the NONE 22686a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten (audio_output_flags_t) 22696a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten AUDIO_INPUT_FLAG_NONE)) { 22706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 22716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 22726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // TODO: reconfigure output format and channels here 22736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() setting device %08x on output %d", 227484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent devDesc->mDeviceType, inputDesc->mIoHandle); 2275874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent setInputDevice(inputDesc->mIoHandle, devDesc->mDeviceType, true, handle); 22766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*handle); 22776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 22786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) { 22796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setInputDevice() did not reuse the patch provided"); 22806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 22816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 22826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = uid; 22836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() success"); 22846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 22856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setInputDevice() failed to create a patch"); 22866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 22876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 22886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) { 22896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // device to device connection 22906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0) { 2291874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) { 22926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 22936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 22946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 22956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<DeviceDescriptor> srcDeviceDesc = 22966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices.getDeviceFromId(patch->sources[0].id); 2297874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 22986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent //update source and sink with our own data as the data passed in the patch may 22996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // be incomplete. 23006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_patch newPatch = *patch; 23016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]); 2302874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (srcDeviceDesc == 0) { 2303874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return BAD_VALUE; 2304874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2305874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 2306874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent for (size_t i = 0; i < patch->num_sinks; i++) { 2307874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) { 2308874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent ALOGV("createAudioPatch() source device but one sink is not a device"); 2309874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2310874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2311874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 2312874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent sp<DeviceDescriptor> sinkDeviceDesc = 2313874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id); 2314874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (sinkDeviceDesc == 0) { 2315874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return BAD_VALUE; 2316874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2317874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]); 2318874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 2319874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (srcDeviceDesc->mModule != sinkDeviceDesc->mModule) { 2320874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // only one sink supported when connected devices across HW modules 2321874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->num_sinks > 1) { 232283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent return INVALID_OPERATION; 232383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent } 2324874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent SortedVector<audio_io_handle_t> outputs = 2325874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent getOutputsForDevice(sinkDeviceDesc->mDeviceType, 2326874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent mOutputs); 2327874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // if the sink device is reachable via an opened output stream, request to go via 2328874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // this output stream by adding a second source to the patch description 23298838a3895c365d443ee22e169ccf45956780c081Eric Laurent audio_io_handle_t output = selectOutput(outputs, 23308838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_OUTPUT_FLAG_NONE, 23318838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_FORMAT_INVALID); 2332874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (output != AUDIO_IO_HANDLE_NONE) { 2333874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 2334874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (outputDesc->isDuplicated()) { 2335874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2336874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2337874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent outputDesc->toAudioPortConfig(&newPatch.sources[1], &patch->sources[0]); 2338874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent newPatch.num_sources = 2; 2339874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 234083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent } 23416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 23426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // TODO: check from routing capabilities in config file and other conflicting patches 23436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 23446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 23456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 23466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent afPatchHandle = patchDesc->mAfPatchHandle; 23476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 23486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 23496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->createAudioPatch(&newPatch, 23506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &afPatchHandle, 23516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 0); 23526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() patch panel returned %d patchHandle %d", 23536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, afPatchHandle); 23546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (status == NO_ERROR) { 23556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 23566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 23576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &newPatch, uid); 23586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent addAudioPatch(patchDesc->mHandle, patchDesc); 23596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 23606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch = newPatch; 23616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 23626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mAfPatchHandle = afPatchHandle; 23636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *handle = patchDesc->mHandle; 23646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 2365b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 23666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 23676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() patch panel could not connect device patch, error %d", 23686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status); 23696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 23706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 23716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 23726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 23736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 23746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 23756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 23766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 23776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 23786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 23796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 23806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle, 23816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent uid_t uid) 23826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 23836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() patch %d", handle); 23846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 23856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(handle); 23866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 23876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 23886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 23896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 23906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 23916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() mUidCached %d patchDesc->mUid %d uid %d", 23926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mUidCached, patchDesc->mUid, uid); 23936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) { 23946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 23956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 23966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 23976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_patch *patch = &patchDesc->mPatch; 23986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = mUidCached; 23996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) { 24001f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id); 24016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc == NULL) { 24026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id); 24036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 24046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 24066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent setOutputDevice(outputDesc->mIoHandle, 24076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent getNewOutputDevice(outputDesc->mIoHandle, true /*fromCache*/), 24086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent true, 24096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 0, 24106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent NULL); 24116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) { 24126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { 24131f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id); 24146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (inputDesc == NULL) { 24156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id); 24166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 24176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent setInputDevice(inputDesc->mIoHandle, 24196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent getNewInputDevice(inputDesc->mIoHandle), 24206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent true, 24216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent NULL); 24226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) { 24236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = patchDesc->mAfPatchHandle; 24246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 24256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() patch panel returned %d patchHandle %d", 24266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, patchDesc->mAfPatchHandle); 24276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent removeAudioPatch(patchDesc->mHandle); 24286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 2429b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 24306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 24316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 24326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 24346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 24356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 24376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 24386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 24396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches, 24406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_patch *patches, 24416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent unsigned int *generation) 24426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 24436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (num_patches == NULL || (*num_patches != 0 && patches == NULL) || 24446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent generation == NULL) { 24456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 24466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 2447beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPatches() num_patches %d patches %p available patches %zu", 24486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_patches, patches, mAudioPatches.size()); 24496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patches == NULL) { 24506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_patches = 0; 24516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 24536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t patchesWritten = 0; 24546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t patchesMax = *num_patches; 24556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; 24566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i < mAudioPatches.size() && patchesWritten < patchesMax; i++) { 24576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patches[patchesWritten] = mAudioPatches[i]->mPatch; 24586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patches[patchesWritten++].id = mAudioPatches[i]->mHandle; 2459beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPatches() patch %zu num_sources %d num_sinks %d", 24606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i, mAudioPatches[i]->mPatch.num_sources, mAudioPatches[i]->mPatch.num_sinks); 24616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_patches = mAudioPatches.size(); 24636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 24646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *generation = curAudioPortGeneration(); 2465beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPatches() got %zu patches needed %d", patchesWritten, *num_patches); 24666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 24676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 24686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2469e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config) 24706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 2471e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("setAudioPortConfig()"); 2472e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2473e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config == NULL) { 2474e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2475e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2476e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("setAudioPortConfig() on port handle %d", config->id); 2477e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent // Only support gain configuration for now 2478a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask != AUDIO_PORT_CONFIG_GAIN) { 2479a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return INVALID_OPERATION; 2480e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2481e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2482a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent sp<AudioPortConfig> audioPortConfig; 2483e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config->type == AUDIO_PORT_TYPE_MIX) { 2484e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config->role == AUDIO_PORT_ROLE_SOURCE) { 24851f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = getOutputFromId(config->id); 2486e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (outputDesc == NULL) { 2487e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2488e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 248984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!outputDesc->isDuplicated(), 249084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent "setAudioPortConfig() called on duplicated output %d", 249184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent outputDesc->mIoHandle); 2492a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig = outputDesc; 2493e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else if (config->role == AUDIO_PORT_ROLE_SINK) { 24941f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = getInputFromId(config->id); 2495e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (inputDesc == NULL) { 2496e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2497e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2498a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig = inputDesc; 2499e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 2500e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2501e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2502e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else if (config->type == AUDIO_PORT_TYPE_DEVICE) { 2503e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent sp<DeviceDescriptor> deviceDesc; 2504e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config->role == AUDIO_PORT_ROLE_SOURCE) { 2505e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id); 2506e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else if (config->role == AUDIO_PORT_ROLE_SINK) { 2507e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id); 2508e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 2509e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2510e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2511e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (deviceDesc == NULL) { 2512e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2513e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2514a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig = deviceDesc; 2515e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 2516e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2517e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2518e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2519a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config backupConfig; 2520a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig); 2521a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status == NO_ERROR) { 2522a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config newConfig; 2523a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig->toAudioPortConfig(&newConfig, config); 2524a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status = mpClientInterface->setAudioPortConfig(&newConfig, 0); 2525e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2526a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 2527a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig->applyAudioPortConfig(&backupConfig); 2528e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2529e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2530e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return status; 25316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 25326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 25336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentvoid AudioPolicyManager::clearAudioPatches(uid_t uid) 25346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 25356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (ssize_t i = 0; i < (ssize_t)mAudioPatches.size(); i++) { 25366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i); 25376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid == uid) { 25386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // releaseAudioPatch() removes the patch from mAudioPatches 25396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (releaseAudioPatch(mAudioPatches.keyAt(i), uid) == NO_ERROR) { 25406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i--; 25416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 25456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2546df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentstatus_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session, 2547df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_io_handle_t *ioHandle, 2548df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_devices_t *device) 2549df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 2550df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent *session = (audio_session_t)mpClientInterface->newAudioUniqueId(); 2551df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId(); 2552df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent *device = getDeviceForInputSource(AUDIO_SOURCE_HOTWORD); 2553df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 2554df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mSoundTriggerSessions.add(*session, *ioHandle); 2555df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 2556df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return NO_ERROR; 2557df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 2558df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 2559df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentstatus_t AudioPolicyManager::releaseSoundTriggerSession(audio_session_t session) 2560df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 2561df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ssize_t index = mSoundTriggerSessions.indexOfKey(session); 2562df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (index < 0) { 2563df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGW("acquireSoundTriggerSession() session %d not registered", session); 2564df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return BAD_VALUE; 2565df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 2566df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 2567df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mSoundTriggerSessions.removeItem(session); 2568df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return NO_ERROR; 2569df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 2570df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 25716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::addAudioPatch(audio_patch_handle_t handle, 25726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const sp<AudioPatch>& patch) 25736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 25746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(handle); 25756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 25766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 25776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("addAudioPatch() patch %d already in", handle); 25786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return ALREADY_EXISTS; 25796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAudioPatches.add(handle, patch); 25816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("addAudioPatch() handle %d af handle %d num_sources %d num_sinks %d source handle %d" 25826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent "sink handle %d", 25836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent handle, patch->mAfPatchHandle, patch->mPatch.num_sources, patch->mPatch.num_sinks, 25846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->mPatch.sources[0].id, patch->mPatch.sinks[0].id); 25856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 25866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 25876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 25886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::removeAudioPatch(audio_patch_handle_t handle) 25896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 25906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(handle); 25916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 25926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 25936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("removeAudioPatch() patch %d not in", handle); 25946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return ALREADY_EXISTS; 25956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("removeAudioPatch() handle %d af handle %d", handle, 25976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAudioPatches.valueAt(index)->mAfPatchHandle); 25986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAudioPatches.removeItemsAt(index); 25996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 26006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 26016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 2603e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent// AudioPolicyManager 2604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 2605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 26063a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::nextUniqueId() 26073a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 26083a4311c68348f728558e87b5db67d47605783890Eric Laurent return android_atomic_inc(&mNextUniqueId); 26093a4311c68348f728558e87b5db67d47605783890Eric Laurent} 26103a4311c68348f728558e87b5db67d47605783890Eric Laurent 26116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentuint32_t AudioPolicyManager::nextAudioPortGeneration() 26126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 26136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return android_atomic_inc(&mAudioPortGeneration); 26146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 26156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2616e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) 2617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : 2618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 2619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent Thread(false), 2620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 2621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput((audio_io_handle_t)0), 26223b73df74357b33869b39a1d69427673c780bd805Eric Laurent mPhoneState(AUDIO_MODE_NORMAL), 2623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 2624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 26253a4311c68348f728558e87b5db67d47605783890Eric Laurent mA2dpSuspended(false), 26266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mSpeakerDrcEnabled(false), mNextUniqueId(1), 26276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAudioPortGeneration(1) 2628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 26296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mUidCached = getuid(); 2630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface = clientInterface; 2631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 26323b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) { 26333b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[i] = AUDIO_POLICY_FORCE_NONE; 2634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 26361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDefaultOutputDevice = new DeviceDescriptor(String8(""), AUDIO_DEVICE_OUT_SPEAKER); 2637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { 2638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { 2639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("could not load audio policy configuration file, setting defaults"); 2640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent defaultAudioPolicyConfig(); 2641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 26433a4311c68348f728558e87b5db67d47605783890Eric Laurent // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices 2644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // must be done after reading the policy 2646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent initializeVolumeCurves(); 2647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open all output streams needed to access attached devices 26493a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types(); 26503a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN; 2651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 2652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 2653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 2654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("could not open HW module %s", mHwModules[i]->mName); 2655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 2656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open all output streams needed to access attached devices 2658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // except for direct output streams that are only opened when they are actually 2659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // required by an app. 26603a4311c68348f728558e87b5db67d47605783890Eric Laurent // This also validates mAvailableOutputDevices list 2661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 2662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 26631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j]; 2664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 26653a4311c68348f728558e87b5db67d47605783890Eric Laurent if (outProfile->mSupportedDevices.isEmpty()) { 26663a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName); 26673a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 26683a4311c68348f728558e87b5db67d47605783890Eric Laurent } 26693a4311c68348f728558e87b5db67d47605783890Eric Laurent 267083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent audio_devices_t profileType = outProfile->mSupportedDevices.types(); 267183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if ((profileType & mDefaultOutputDevice->mDeviceType) != AUDIO_DEVICE_NONE) { 267283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent profileType = mDefaultOutputDevice->mDeviceType; 267383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent } else { 267483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent profileType = outProfile->mSupportedDevices[0]->mDeviceType; 267583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent } 267683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if ((profileType & outputDeviceTypes) && 2677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) { 26781f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile); 26793a4311c68348f728558e87b5db67d47605783890Eric Laurent 268083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent outputDesc->mDevice = profileType; 2681cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 2682cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = outputDesc->mSamplingRate; 2683cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = outputDesc->mChannelMask; 2684cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = outputDesc->mFormat; 2685cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; 2686cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status = mpClientInterface->openOutput(outProfile->mModule->mHandle, 2687cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &output, 2688cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 2689cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mDevice, 2690cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent String8(""), 2691cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mLatency, 2692cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFlags); 2693cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent 2694cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status != NO_ERROR) { 26953a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Cannot open output stream for device %08x on hw module %s", 26963a4311c68348f728558e87b5db67d47605783890Eric Laurent outputDesc->mDevice, 26973a4311c68348f728558e87b5db67d47605783890Eric Laurent mHwModules[i]->mName); 2698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2699cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mSamplingRate = config.sample_rate; 2700cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mChannelMask = config.channel_mask; 2701cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFormat = config.format; 2702cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent 27035b61dddd0dba28922068da2487894761486aec6cEric Laurent for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { 27041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType; 27053a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = 27065b61dddd0dba28922068da2487894761486aec6cEric Laurent mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]); 27073a4311c68348f728558e87b5db67d47605783890Eric Laurent // give a valid ID to an attached device once confirmed it is reachable 27083a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((index >= 0) && (mAvailableOutputDevices[index]->mId == 0)) { 27093a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices[index]->mId = nextUniqueId(); 27106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableOutputDevices[index]->mModule = mHwModules[i]; 27113a4311c68348f728558e87b5db67d47605783890Eric Laurent } 27123a4311c68348f728558e87b5db67d47605783890Eric Laurent } 2713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput == 0 && 2714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 2715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput = output; 2716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, outputDesc); 2718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, 27193a4311c68348f728558e87b5db67d47605783890Eric Laurent outputDesc->mDevice, 2720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent true); 2721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 27243a4311c68348f728558e87b5db67d47605783890Eric Laurent // open input streams needed to access attached devices to validate 27253a4311c68348f728558e87b5db67d47605783890Eric Laurent // mAvailableInputDevices list 27263a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 27273a4311c68348f728558e87b5db67d47605783890Eric Laurent { 27281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j]; 27293a4311c68348f728558e87b5db67d47605783890Eric Laurent 27303a4311c68348f728558e87b5db67d47605783890Eric Laurent if (inProfile->mSupportedDevices.isEmpty()) { 27313a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName); 27323a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 27333a4311c68348f728558e87b5db67d47605783890Eric Laurent } 2734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 273583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent audio_devices_t profileType = inProfile->mSupportedDevices[0]->mDeviceType; 273683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (profileType & inputDeviceTypes) { 27371f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile); 27383a4311c68348f728558e87b5db67d47605783890Eric Laurent 27393a4311c68348f728558e87b5db67d47605783890Eric Laurent inputDesc->mInputSource = AUDIO_SOURCE_MIC; 274083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent inputDesc->mDevice = profileType; 27413a4311c68348f728558e87b5db67d47605783890Eric Laurent 2742cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 2743cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = inputDesc->mSamplingRate; 2744cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = inputDesc->mChannelMask; 2745cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = inputDesc->mFormat; 2746cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; 2747cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status = mpClientInterface->openInput(inProfile->mModule->mHandle, 2748cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &input, 2749cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 2750cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &inputDesc->mDevice, 2751cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent String8(""), 2752cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent AUDIO_SOURCE_MIC, 2753cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent AUDIO_INPUT_FLAG_NONE); 2754cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent 2755cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status == NO_ERROR) { 27565b61dddd0dba28922068da2487894761486aec6cEric Laurent for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { 27571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType; 27583a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = 27595b61dddd0dba28922068da2487894761486aec6cEric Laurent mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]); 27603a4311c68348f728558e87b5db67d47605783890Eric Laurent // give a valid ID to an attached device once confirmed it is reachable 27613a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((index >= 0) && (mAvailableInputDevices[index]->mId == 0)) { 27623a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices[index]->mId = nextUniqueId(); 27636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices[index]->mModule = mHwModules[i]; 27643a4311c68348f728558e87b5db67d47605783890Eric Laurent } 27653a4311c68348f728558e87b5db67d47605783890Eric Laurent } 27663a4311c68348f728558e87b5db67d47605783890Eric Laurent mpClientInterface->closeInput(input); 27673a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 27683a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Cannot open input stream for device %08x on hw module %s", 27693a4311c68348f728558e87b5db67d47605783890Eric Laurent inputDesc->mDevice, 27703a4311c68348f728558e87b5db67d47605783890Eric Laurent mHwModules[i]->mName); 27713a4311c68348f728558e87b5db67d47605783890Eric Laurent } 27723a4311c68348f728558e87b5db67d47605783890Eric Laurent } 27733a4311c68348f728558e87b5db67d47605783890Eric Laurent } 27743a4311c68348f728558e87b5db67d47605783890Eric Laurent } 27753a4311c68348f728558e87b5db67d47605783890Eric Laurent // make sure all attached devices have been allocated a unique ID 27763a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableOutputDevices.size();) { 27773a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableOutputDevices[i]->mId == 0) { 27781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mDeviceType); 27793a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.remove(mAvailableOutputDevices[i]); 27803a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 27813a4311c68348f728558e87b5db67d47605783890Eric Laurent } 27823a4311c68348f728558e87b5db67d47605783890Eric Laurent i++; 27833a4311c68348f728558e87b5db67d47605783890Eric Laurent } 27843a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size();) { 27853a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableInputDevices[i]->mId == 0) { 27861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mDeviceType); 27873a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.remove(mAvailableInputDevices[i]); 27883a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 27893a4311c68348f728558e87b5db67d47605783890Eric Laurent } 27903a4311c68348f728558e87b5db67d47605783890Eric Laurent i++; 27913a4311c68348f728558e87b5db67d47605783890Eric Laurent } 27923a4311c68348f728558e87b5db67d47605783890Eric Laurent // make sure default device is reachable 27933a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) { 27941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mDeviceType); 27953a4311c68348f728558e87b5db67d47605783890Eric Laurent } 2796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 2798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 2800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 2802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput != 0) { 2803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 2804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"), 0); 2805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 2806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestDevice = AUDIO_DEVICE_OUT_SPEAKER; 2808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestSamplingRate = 44100; 28093b73df74357b33869b39a1d69427673c780bd805Eric Laurent mTestFormat = AUDIO_FORMAT_PCM_16_BIT; 28103b73df74357b33869b39a1d69427673c780bd805Eric Laurent mTestChannels = AUDIO_CHANNEL_OUT_STEREO; 2811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestLatencyMs = 0; 2812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput = 0; 2813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = false; 2814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 2815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[i] = 0; 2816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 2819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 2820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 2821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent run(buffer, ANDROID_PRIORITY_AUDIO); 2822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 2824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2826e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::~AudioPolicyManager() 2827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 2829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent exit(); 2830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 2831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(mOutputs.keyAt(i)); 2833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 2835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeInput(mInputs.keyAt(i)); 2836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 28373a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.clear(); 28383a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.clear(); 28391f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mOutputs.clear(); 28401f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mInputs.clear(); 28411f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mHwModules.clear(); 2842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2844e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::initCheck() 2845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; 2847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 2850e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::threadLoop() 2851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("entering threadLoop()"); 2853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (!exitPending()) 2854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 command; 2856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int valueInt; 2857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 value; 2858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent Mutex::Autolock _l(mLock); 2860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 2861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 2863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param = AudioParameter(command); 2864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 2866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent valueInt != 0) { 2867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Test command %s received", command.string()); 2868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 target; 2869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("target"), target) != NO_ERROR) { 2870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent target = "Manager"; 2871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 2873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_output")); 2874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput = valueInt; 2875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 2877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_direct")); 2878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "false") { 2879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = false; 2880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "true") { 2881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = true; 2882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 2885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_input")); 2886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestInput = valueInt; 2887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 2890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_format")); 28913b73df74357b33869b39a1d69427673c780bd805Eric Laurent int format = AUDIO_FORMAT_INVALID; 2892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "PCM 16 bits") { 28933b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_PCM_16_BIT; 2894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "PCM 8 bits") { 28953b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_PCM_8_BIT; 2896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "Compressed MP3") { 28973b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_MP3; 2898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 28993b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (format != AUDIO_FORMAT_INVALID) { 2900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 2901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestFormat = format; 2902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 2903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 2904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("format"), format); 2905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 2906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 2910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_channels")); 2911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int channels = 0; 2912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "Channels Stereo") { 29143b73df74357b33869b39a1d69427673c780bd805Eric Laurent channels = AUDIO_CHANNEL_OUT_STEREO; 2915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "Channels Mono") { 29163b73df74357b33869b39a1d69427673c780bd805Eric Laurent channels = AUDIO_CHANNEL_OUT_MONO; 2917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (channels != 0) { 2919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 2920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestChannels = channels; 2921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 2922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 2923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("channels"), channels); 2924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 2925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 2929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_sampleRate")); 2930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (valueInt >= 0 && valueInt <= 96000) { 2931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int samplingRate = valueInt; 2932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 2933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestSamplingRate = samplingRate; 2934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 2935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 2936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("sampling_rate"), samplingRate); 2937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 2938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 2943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_reopen")); 2944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 29451f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput); 2946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(mPrimaryOutput); 2947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; 2949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(mPrimaryOutput); 2951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 29521f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL); 2953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; 2954cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 2955cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = outputDesc->mSamplingRate; 2956cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = outputDesc->mChannelMask; 2957cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = outputDesc->mFormat; 2958cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status = mpClientInterface->openOutput(moduleHandle, 2959cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &mPrimaryOutput, 2960cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 2961cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mDevice, 2962cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent String8(""), 2963cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mLatency, 2964cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFlags); 2965cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status != NO_ERROR) { 2966cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent ALOGE("Failed to reopen hardware output stream, " 2967cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent "samplingRate: %d, format %d, channels %d", 2968cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); 2969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 2970cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mSamplingRate = config.sample_rate; 2971cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mChannelMask = config.channel_mask; 2972cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFormat = config.format; 2973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 2974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"), 0); 2975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 2976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(mPrimaryOutput, outputDesc); 2977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 2982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2987e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::exit() 2988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AutoMutex _l(mLock); 2991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent requestExit(); 2992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mWaitWorkCV.signal(); 2993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent requestExitAndWait(); 2995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2997e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::testOutputIndex(audio_io_handle_t output) 2998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 3000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == mTestOutputs[i]) return i; 3001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 3003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 3005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- 3007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30081f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc) 3009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 30101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mIoHandle = output; 30111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mId = nextUniqueId(); 30121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mOutputs.add(output, outputDesc); 30136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 3014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30161f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc) 3017d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 30181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mIoHandle = input; 30191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mId = nextUniqueId(); 30201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mInputs.add(input, inputDesc); 30216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 3022d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 3023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30240fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivivoid AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/, 30250fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi const String8 address /*in*/, 30260fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi SortedVector<audio_io_handle_t>& outputs /*out*/) { 30270fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi // look for a match on the given address on the addresses of the outputs: 30280fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi // find the address by finding the patch that maps to this output 30290fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ssize_t patchIdx = mAudioPatches.indexOfKey(desc->mPatchHandle); 30300fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi //ALOGV(" inspecting output %d (patch %d) for supported device=0x%x", 30310fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi // outputIdx, patchIdx, desc->mProfile->mSupportedDevices.types()); 30320fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (patchIdx >= 0) { 30330fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi const sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patchIdx); 30340fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi const int numSinks = patchDesc->mPatch.num_sinks; 30350fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi for (ssize_t j=0; j < numSinks; j++) { 30360fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (patchDesc->mPatch.sinks[j].type == AUDIO_PORT_TYPE_DEVICE) { 30370fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi const char* patchAddr = 30380fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi patchDesc->mPatch.sinks[j].ext.device.address; 30390fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (strncmp(patchAddr, 30400fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi address.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) { 3041f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s", 30420fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi desc->mIoHandle, patchDesc->mPatch.sinks[j].ext.device.address); 30430fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi outputs.add(desc->mIoHandle); 30440fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi break; 30450fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 30460fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 30470fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 30480fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 30490fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi} 30500fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi 3051f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivistatus_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> devDesc, 30523b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state, 3053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t>& outputs, 30543a4311c68348f728558e87b5db67d47605783890Eric Laurent const String8 address) 3055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3056f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi audio_devices_t device = devDesc->mDeviceType; 30571f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc; 3058f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi // erase all current sample rates, formats and channel masks 3059f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi devDesc->clearCapabilities(); 3060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30613b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { 3062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // first list already open outputs that can be routed to this device 3063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 3064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(i); 30653a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) { 30660fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (!deviceDistinguishesOnAddress(device)) { 30670fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i)); 30680fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi outputs.add(mOutputs.keyAt(i)); 30690fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } else { 30700fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV(" checking address match due to device 0x%x", device); 30710fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi findIoHandlesByAddress(desc, address, outputs); 30720fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 3073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // then look for output profiles that can be routed to this device 30761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent SortedVector< sp<IOProfile> > profiles; 3077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 3078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 3080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 3081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 3083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 30843a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) { 3085d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i); 3086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profiles.add(mHwModules[i]->mOutputProfiles[j]); 3087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30910fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV(" found %d profiles, %d outputs", profiles.size(), outputs.size()); 30920fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi 3093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profiles.isEmpty() && outputs.isEmpty()) { 3094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 3095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 3096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open outputs for matching profiles if needed. Direct outputs are also opened to 3099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 3100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 31011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = profiles[profile_index]; 3102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // nothing to do if one output is already opened for this profile 3104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent size_t j; 31050fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi for (j = 0; j < outputs.size(); j++) { 31060fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi desc = mOutputs.valueFor(outputs.itemAt(j)); 3107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && desc->mProfile == profile) { 3108f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi // matching profile: save the sample rates, format and channel masks supported 3109f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi // by the profile in our device descriptor 3110f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi devDesc->importAudioPort(profile); 3111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 31140fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (j != outputs.size()) { 3115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 3116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 311883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ALOGV("opening output for device %08x with params %s profile %p", 311983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent device, address.string(), profile.get()); 3120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = new AudioOutputDescriptor(profile); 3121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mDevice = device; 3122cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 3123cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = desc->mSamplingRate; 3124cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = desc->mChannelMask; 3125cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = desc->mFormat; 3126cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.sample_rate = desc->mSamplingRate; 3127cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.channel_mask = desc->mChannelMask; 3128cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.format = desc->mFormat; 3129cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; 3130cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status = mpClientInterface->openOutput(profile->mModule->mHandle, 3131cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &output, 3132cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 3133cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &desc->mDevice, 3134cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent address, 3135cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &desc->mLatency, 3136cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mFlags); 3137cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status == NO_ERROR) { 3138cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mSamplingRate = config.sample_rate; 3139cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mChannelMask = config.channel_mask; 3140cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mFormat = config.format; 3141cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent 3142d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where the out_set_parameters() for card & device gets called 31433a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!address.isEmpty()) { 3144cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent char *param = audio_device_address_to_parameter(device, address); 3145cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent mpClientInterface->setParameters(output, String8(param)); 3146cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent free(param); 3147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3149d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where we step through and resolve any "dynamic" fields 3150d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 reply; 3151d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char *value; 3152d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 3153d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 3154d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 31550fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice() supported sampling rates %s", 3156d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 3157d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3158d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 31591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadSamplingRates(value + 1); 3160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3161d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3162d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 3163d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 3164d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 31650fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice() supported formats %s", 3166d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 3167d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3168d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 31691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadFormats(value + 1); 3170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3171d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3172d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 3173d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 3174d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 31750fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice() supported channel masks %s", 3176d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 3177d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3178d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 31791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadOutChannels(value + 1); 3180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3181d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3182d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (((profile->mSamplingRates[0] == 0) && 3183d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mSamplingRates.size() < 2)) || 3184d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) && 3185d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mFormats.size() < 2)) || 3186d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mChannelMasks[0] == 0) && 3187d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mChannelMasks.size() < 2))) { 31880fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGW("checkOutputsForDevice() missing param"); 3189d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 3190cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent output = AUDIO_IO_HANDLE_NONE; 31911e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else if (profile->mSamplingRates[0] == 0 || profile->mFormats[0] == 0 || 31921e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent profile->mChannelMasks[0] == 0) { 3193d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 3194cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = profile->pickSamplingRate(); 3195cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = profile->pickChannelMask(); 3196cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = profile->pickFormat(); 3197cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.sample_rate = config.sample_rate; 3198cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.channel_mask = config.channel_mask; 3199cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.format = config.format; 3200cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status = mpClientInterface->openOutput(profile->mModule->mHandle, 3201cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &output, 3202cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 3203cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &desc->mDevice, 3204cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent address, 3205cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &desc->mLatency, 3206cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mFlags); 3207cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status == NO_ERROR) { 3208cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mSamplingRate = config.sample_rate; 3209cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mChannelMask = config.channel_mask; 3210cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mFormat = config.format; 3211cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent } else { 3212cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent output = AUDIO_IO_HANDLE_NONE; 3213cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent } 3214d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3215d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3216cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (output != AUDIO_IO_HANDLE_NONE) { 3217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, desc); 3218d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { 3219cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE; 3220d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3221d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // set initial stream volume for device 3222d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent applyStreamVolumes(output, device, 0, true); 3223d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3224d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent //TODO: configure audio effect output stage here 3225d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3226d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // open a duplicating output thread for the new output and the primary output 3227d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent duplicatedOutput = mpClientInterface->openDuplicateOutput(output, 3228d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mPrimaryOutput); 3229cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) { 3230d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // add duplicated output descriptor 3231cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent sp<AudioOutputDescriptor> dupOutputDesc = 3232cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent new AudioOutputDescriptor(NULL); 3233d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); 3234d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mOutput2 = mOutputs.valueFor(output); 3235d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mSamplingRate = desc->mSamplingRate; 3236d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mFormat = desc->mFormat; 3237d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mChannelMask = desc->mChannelMask; 3238d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mLatency = desc->mLatency; 3239d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addOutput(duplicatedOutput, dupOutputDesc); 3240d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent applyStreamVolumes(duplicatedOutput, device, 0, true); 3241d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 3242d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkOutputsForDevice() could not open dup output for %d and %d", 3243d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mPrimaryOutput, output); 3244d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 3245d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mOutputs.removeItem(output); 32466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 3247cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent output = AUDIO_IO_HANDLE_NONE; 3248d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3251cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent } else { 3252cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent output = AUDIO_IO_HANDLE_NONE; 3253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3254cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (output == AUDIO_IO_HANDLE_NONE) { 3255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice() could not open output for device %x", device); 3256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profiles.removeAt(profile_index); 3257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile_index--; 3258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(output); 3260f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi devDesc->importAudioPort(profile); 3261f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi 32620fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (deviceDistinguishesOnAddress(device)) { 32630fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)", 32640fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi device, address.string()); 32650fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi setOutputDevice(output, device, true/*force*/, 0/*delay*/, 32660fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi NULL/*patch handle*/, address.string()); 32670fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 3268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputsForDevice(): adding output %d", output); 3269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profiles.isEmpty()) { 3273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 3274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 3275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3276d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { // Disconnect 3277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check if one opened output is not needed any more after disconnecting one device 3278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 3279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(i); 32800fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (!desc->isDuplicated()) { 32810fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (!(desc->mProfile->mSupportedDevices.types() 32820fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi & mAvailableOutputDevices.types())) { 32830fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice(): disconnecting adding output %d", 32840fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi mOutputs.keyAt(i)); 32850fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi outputs.add(mOutputs.keyAt(i)); 32860fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } else if (deviceDistinguishesOnAddress(device) && 32870fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi // exact match on device 32880fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi (desc->mProfile->mSupportedDevices.types() == device)) { 32890fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi findIoHandlesByAddress(desc, address, outputs); 32900fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 3291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3293d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Clear any profiles associated with the disconnected device. 3294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 3295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 3297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 3298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 3300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 33011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j]; 3302d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSupportedDevices.types() & device) { 3303d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice(): " 3304d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent "clearing direct output profile %zu on module %zu", j, i); 3305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mSamplingRates[0] == 0) { 3306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.clear(); 3307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(0); 3308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 3310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.clear(); 3311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 3312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mChannelMasks[0] == 0) { 3314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.clear(); 3315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(0); 3316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 3322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3324d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentstatus_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, 3325d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent audio_policy_dev_state_t state, 3326d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector<audio_io_handle_t>& inputs, 3327d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent const String8 address) 3328d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 33291f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> desc; 3330d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { 3331d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // first list already open inputs that can be routed to this device 3332d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 3333d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 3334d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (desc->mProfile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) { 3335d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index)); 3336d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(mInputs.keyAt(input_index)); 3337d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3338d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3339d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3340d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // then look for input profiles that can be routed to this device 33411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent SortedVector< sp<IOProfile> > profiles; 3342d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++) 3343d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent { 3344d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_idx]->mHandle == 0) { 3345d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 3346d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3347d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t profile_index = 0; 3348d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index < mHwModules[module_idx]->mInputProfiles.size(); 3349d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index++) 3350d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent { 3351d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_idx]->mInputProfiles[profile_index]->mSupportedDevices.types() 3352d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent & (device & ~AUDIO_DEVICE_BIT_IN)) { 3353beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("checkInputsForDevice(): adding profile %zu from module %zu", 3354d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index, module_idx); 3355d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profiles.add(mHwModules[module_idx]->mInputProfiles[profile_index]); 3356d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3357d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3358d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3359d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3360d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profiles.isEmpty() && inputs.isEmpty()) { 3361d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 3362d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return BAD_VALUE; 3363d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3364d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3365d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // open inputs for matching profiles if needed. Direct inputs are also opened to 3366d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 3367d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 3368d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 33691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = profiles[profile_index]; 3370d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // nothing to do if one input is already opened for this profile 3371d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent size_t input_index; 3372d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (input_index = 0; input_index < mInputs.size(); input_index++) { 3373d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 3374d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (desc->mProfile == profile) { 3375d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent break; 3376d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3377d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3378d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input_index != mInputs.size()) { 3379d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 3380d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3381d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3382d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("opening input for device 0x%X with params %s", device, address.string()); 3383d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = new AudioInputDescriptor(profile); 3384d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc->mDevice = device; 3385cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 3386cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = desc->mSamplingRate; 3387cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = desc->mChannelMask; 3388cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = desc->mFormat; 3389cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; 3390cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status = mpClientInterface->openInput(profile->mModule->mHandle, 3391cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &input, 3392cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 3393cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &desc->mDevice, 3394cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent address, 3395cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent AUDIO_SOURCE_MIC, 3396cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent AUDIO_INPUT_FLAG_NONE /*FIXME*/); 3397d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3398cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status == NO_ERROR) { 3399cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mSamplingRate = config.sample_rate; 3400cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mChannelMask = config.channel_mask; 3401cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mFormat = config.format; 3402d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3403d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (!address.isEmpty()) { 3404cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent char *param = audio_device_address_to_parameter(device, address); 3405cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent mpClientInterface->setParameters(input, String8(param)); 3406cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent free(param); 3407d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3408d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3409d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where we step through and resolve any "dynamic" fields 3410d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 reply; 3411d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char *value; 3412d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 3413d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 3414d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 3415d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup sampling rates %s", 3416d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 3417d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3418d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 34191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadSamplingRates(value + 1); 3420d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3421d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3422d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 3423d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 3424d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 3425d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string()); 3426d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3427d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 34281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadFormats(value + 1); 3429d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3430d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3431d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 3432d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 3433d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 3434d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup channel masks %s", 3435d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 3436d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3437d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 34381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadInChannels(value + 1); 3439d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3440d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3441d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) || 3442d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) || 3443d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) { 3444d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice() direct input missing param"); 3445d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeInput(input); 3446cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent input = AUDIO_IO_HANDLE_NONE; 3447d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3448d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3449d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input != 0) { 3450d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addInput(input, desc); 3451d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3452d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // endif input != 0 3453d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3454cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (input == AUDIO_IO_HANDLE_NONE) { 3455d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice() could not open input for device 0x%X", device); 3456d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profiles.removeAt(profile_index); 3457d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index--; 3458d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 3459d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(input); 3460d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding input %d", input); 3461d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3462d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end scan profiles 3463d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3464d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profiles.isEmpty()) { 3465d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 3466d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return BAD_VALUE; 3467d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3468d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 3469d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Disconnect 3470d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // check if one opened input is not needed any more after disconnecting one device 3471d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 3472d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 3473d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types())) { 3474d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): disconnecting adding input %d", 3475d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mInputs.keyAt(input_index)); 3476d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(mInputs.keyAt(input_index)); 3477d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3478d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3479d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Clear any profiles associated with the disconnected device. 3480d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) { 3481d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_index]->mHandle == 0) { 3482d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 3483d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3484d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t profile_index = 0; 3485d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index < mHwModules[module_index]->mInputProfiles.size(); 3486d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index++) { 34871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index]; 3488d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSupportedDevices.types() & device) { 3489beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu", 3490d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index, module_index); 3491d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 3492d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mSamplingRates.clear(); 3493d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mSamplingRates.add(0); 3494d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3495d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 3496d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mFormats.clear(); 3497d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 3498d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3499d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 3500d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mChannelMasks.clear(); 3501d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mChannelMasks.add(0); 3502d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3503d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3504d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3505d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3506d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end disconnect 3507d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3508d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return NO_ERROR; 3509d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 3510d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3511d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3512e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::closeOutput(audio_io_handle_t output) 3513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("closeOutput(%d)", output); 3515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 35161f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 3517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc == NULL) { 3518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("closeOutput() unknown output %d", output); 3519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 3520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // look for duplicated outputs connected to the output being removed. 3523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 35241f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i); 3525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dupOutputDesc->isDuplicated() && 3526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (dupOutputDesc->mOutput1 == outputDesc || 3527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent dupOutputDesc->mOutput2 == outputDesc)) { 35281f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc2; 3529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dupOutputDesc->mOutput1 == outputDesc) { 3530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc2 = dupOutputDesc->mOutput2; 3531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc2 = dupOutputDesc->mOutput1; 3533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // As all active tracks on duplicated output will be deleted, 3535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and as they were also referenced on the other output, the reference 3536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // count for their stream type must be adjusted accordingly on 3537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the other output. 35383b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int j = 0; j < AUDIO_STREAM_CNT; j++) { 3539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int refCount = dupOutputDesc->mRefCount[j]; 35403b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount); 3541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i); 3543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); 3544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(duplicatedOutput); 3546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(duplicatedOutput); 3547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 355005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent nextAudioPortGeneration(); 355105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 355205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); 355305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent if (index >= 0) { 355405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 355505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 355605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mAudioPatches.removeItemsAt(index); 355705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 355805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent } 355905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 3560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param; 3561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.add(String8("closing"), String8("true")); 3562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(output, param.toString()); 3563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 3565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(output); 3566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 356705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent} 356805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 356905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurentvoid AudioPolicyManager::closeInput(audio_io_handle_t input) 357005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent{ 357105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent ALOGV("closeInput(%d)", input); 357205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 357305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); 357405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent if (inputDesc == NULL) { 357505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent ALOGW("closeInput() unknown input %d", input); 357605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent return; 357705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent } 357805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 35796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 358005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 358105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 358205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent if (index >= 0) { 358305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 358405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 358505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mAudioPatches.removeItemsAt(index); 358605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 358705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent } 358805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 358905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mpClientInterface->closeInput(input); 359005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mInputs.removeItem(input); 3591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3593e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device, 35941f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > openOutputs) 3595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> outputs; 3597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getOutputsForDevice() device %04x", device); 3599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < openOutputs.size(); i++) { 3600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("output %d isDuplicated=%d device=%04x", 3601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices()); 3602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) { 3603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i)); 3604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(openOutputs.keyAt(i)); 3605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs; 3608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3610e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, 3611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t>& outputs2) 3612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs1.size() != outputs2.size()) { 3614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs1.size(); i++) { 3617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs1[i] != outputs2[i]) { 3618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 3622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3624e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy) 3625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); 3627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); 3628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs); 3629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); 3630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!vectorsEqual(srcOutputs,dstOutputs)) { 3632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", 3633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent strategy, srcOutputs[0], dstOutputs[0]); 3634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute strategy while moving tracks from one output to another 3635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < srcOutputs.size(); i++) { 36361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]); 3637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->isStrategyActive(strategy)) { 3638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(strategy, true, srcOutputs[i]); 3639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); 3640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Move effects associated to this strategy from previous output to new output 3644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strategy == STRATEGY_MEDIA) { 3645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs); 3646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> moved; 3647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 36481f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = mEffects.valueAt(i); 36491f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (effectDesc->mSession == AUDIO_SESSION_OUTPUT_MIX && 36501f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mIo != fxOutput) { 36511f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (moved.indexOf(effectDesc->mIo) < 0) { 3652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputForStrategy() moving effect %d to output %d", 3653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.keyAt(i), fxOutput); 36541f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo, 3655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent fxOutput); 36561f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent moved.add(effectDesc->mIo); 3657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 36581f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mIo = fxOutput; 3659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Move tracks associated to this strategy from previous output to new output 36633b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 36643b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (getStrategy((audio_stream_type_t)i) == strategy) { 36653b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->invalidateStream((audio_stream_type_t)i); 3666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3671e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForAllStrategies() 3672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 3674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_PHONE); 3675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION); 3676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 3677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_MEDIA); 3678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_DTMF); 3679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3681e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getA2dpOutput() 3682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 36841f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); 3685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 3686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutputs.keyAt(i); 3687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 3691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3693e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkA2dpSuspend() 3694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t a2dpOutput = getA2dpOutput(); 3696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (a2dpOutput == 0) { 36973a4311c68348f728558e87b5db67d47605783890Eric Laurent mA2dpSuspended = false; 3698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 3699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 37013a4311c68348f728558e87b5db67d47605783890Eric Laurent bool isScoConnected = 37023a4311c68348f728558e87b5db67d47605783890Eric Laurent (mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) != 0; 3703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // suspend A2DP output if: 3704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (NOT already suspended) && 3705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ((SCO device is connected && 3706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (forced usage for communication || for record is SCO))) || 3707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (phone state is ringing || in call) 3708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // restore A2DP output if: 3710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (Already suspended) && 3711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ((SCO device is NOT connected || 3712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (forced usage NOT for communication && NOT for record is SCO))) && 3713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (phone state is NOT ringing && NOT in call) 3714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mA2dpSuspended) { 37163a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((!isScoConnected || 37173b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO) && 37183b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] != AUDIO_POLICY_FORCE_BT_SCO))) && 37193b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mPhoneState != AUDIO_MODE_IN_CALL) && 37203b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mPhoneState != AUDIO_MODE_RINGTONE))) { 3721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->restoreOutput(a2dpOutput); 3723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mA2dpSuspended = false; 3724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 37263a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((isScoConnected && 37273b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) || 37283b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO))) || 37293b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mPhoneState == AUDIO_MODE_IN_CALL) || 37303b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mPhoneState == AUDIO_MODE_RINGTONE))) { 3731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->suspendOutput(a2dpOutput); 3733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mA2dpSuspended = true; 3734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 37381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentaudio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, bool fromCache) 3739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = AUDIO_DEVICE_NONE; 3741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 37421f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 37436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 37446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); 37456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 37466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 37476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached) { 37486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("getNewOutputDevice() device %08x forced by patch %d", 37496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent outputDesc->device(), outputDesc->mPatchHandle); 37506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return outputDesc->device(); 37516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 37526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 37536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 3754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check the following by order of priority to request a routing change if necessary: 3755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: the strategy enforced audible is active on the output: 3756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy enforced audible 3757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: we are in call or the strategy phone is active on the output: 3758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy phone 3759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the strategy sonification is active on the output: 3760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy sonification 3761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 4: the strategy "respectful" sonification is active on the output: 3762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy "respectful" sonification 3763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 5: the strategy media is active on the output: 3764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy media 3765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 6: the strategy DTMF is active on the output: 3766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy DTMF 3767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { 3768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 3769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isInCall() || 3770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->isStrategyActive(STRATEGY_PHONE)) { 3771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 3772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) { 3773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 3774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { 3775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); 3776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { 3777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 3778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { 3779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 3780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 37821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("getNewOutputDevice() selected device %x", device); 37831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return device; 37841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 37851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 37861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentaudio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input) 37871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 37881f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); 37896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 37906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 37916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 37926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 37936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached) { 37946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("getNewInputDevice() device %08x forced by patch %d", 37956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent inputDesc->mDevice, inputDesc->mPatchHandle); 37966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return inputDesc->mDevice; 37976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 37986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 37996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 38001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t device = getDeviceForInputSource(inputDesc->mInputSource); 38011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 38021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("getNewInputDevice() selected device %x", device); 3803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 3804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3806e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) { 3807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (uint32_t)getStrategy(stream); 3808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3810e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) { 3811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // By checking the range of stream before calling getStrategy, we avoid 3812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 3813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and then return STRATEGY_MEDIA, but we want to return the empty set. 38143b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_CNT) { 38156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return AUDIO_DEVICE_NONE; 38166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 38176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_devices_t devices; 38186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent AudioPolicyManager::routing_strategy strategy = getStrategy(stream); 38196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent devices = getDeviceForStrategy(strategy, true /*fromCache*/); 38206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs); 38216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 38221f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); 38236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc->isStrategyActive(strategy)) { 38246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent devices = outputDesc->device(); 38256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 38266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 3827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 382811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund 382911c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it 383011c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund and doesn't really need to.*/ 383111c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) { 383211c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund devices |= AUDIO_DEVICE_OUT_SPEAKER; 383311c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund devices &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE; 383411c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund } 383511c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund 3836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return devices; 3837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3839e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy( 38403b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream) { 3841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // stream to strategy mapping 3842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (stream) { 38433b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_VOICE_CALL: 38443b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_BLUETOOTH_SCO: 3845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_PHONE; 38463b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_RING: 38473b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_ALARM: 3848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_SONIFICATION; 38493b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_NOTIFICATION: 3850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_SONIFICATION_RESPECTFUL; 38513b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_DTMF: 3852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_DTMF; 3853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 3854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("unknown stream type"); 38553b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_SYSTEM: 3856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 3857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while key clicks are played produces a poor result 38583b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_TTS: 38593b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_MUSIC: 3860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_MEDIA; 38613b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_ENFORCED_AUDIBLE: 3862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 3863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 38665bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviuint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) { 38675bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // flags to strategy mapping 38685bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { 38695bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_ENFORCED_AUDIBLE; 38705bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 38715bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 38725bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // usage to strategy mapping 38735bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi switch (attr->usage) { 38745bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_MEDIA: 38755bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_GAME: 38765bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: 38775bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 38785bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_SONIFICATION: 38795bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_MEDIA; 38805bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 38815bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION: 38825bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_PHONE; 38835bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 38845bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: 38855bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_DTMF; 38865bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 38875bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ALARM: 38885bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: 38895bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_SONIFICATION; 38905bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 38915bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION: 38925bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: 38935bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: 38945bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: 38955bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_EVENT: 38965bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_SONIFICATION_RESPECTFUL; 38975bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 38985bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_UNKNOWN: 38995bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi default: 39005bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_MEDIA; 39015bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 39025bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi} 39035bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 3904e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) { 3905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(stream) { 39063b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_MUSIC: 3907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 3908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 3909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 3911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3915e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, 3916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool fromCache) 3917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 3919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (fromCache) { 3921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x", 3922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent strategy, mDeviceForStrategy[strategy]); 3923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mDeviceForStrategy[strategy]; 3924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 39253a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types(); 3926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (strategy) { 3927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_SONIFICATION_RESPECTFUL: 3929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 3930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 39313b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC, 3932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 3933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while media is playing on a remote device, use the the sonification behavior. 3934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Note that we test this usecase before testing if media is playing because 3935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the isStreamActive() method only informs about the activity of a stream, not 3936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if it's for local playback. Note also that we use the same delay between both tests 3937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 393811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund //user "safe" speaker if available instead of normal speaker to avoid triggering 393911c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund //other acoustic safety mechanisms for notification 394011c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) 394111c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund device = AUDIO_DEVICE_OUT_SPEAKER_SAFE; 39423b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 3943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while media is playing (or has recently played), use the same device 3944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 3945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when media is not playing anymore, fall back on the sonification behavior 3947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 394811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund //user "safe" speaker if available instead of normal speaker to avoid triggering 394911c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund //other acoustic safety mechanisms for notification 395011c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) 395111c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund device = AUDIO_DEVICE_OUT_SPEAKER_SAFE; 3952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_DTMF: 3957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isInCall()) { 3958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when off call, DTMF strategy follows the same rules as MEDIA strategy 3959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 3960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when in call, DTMF and PHONE strategies follow the same rules 3963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 3964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_PHONE: 3966c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // Force use of only devices on primary output if: 3967c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // - in call AND 3968c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // - cannot route from voice call RX OR 3969c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // - audio HAL version is < 3.0 and TX device is on the primary HW module 3970c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mPhoneState == AUDIO_MODE_IN_CALL) { 3971c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION); 3972c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 3973c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (((mAvailableInputDevices.types() & 3974c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) || 3975c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent (((txDevice & availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN) != 0) && 3976961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen (hwOutputDesc->getAudioPort()->mModule->mHalVersion < 3977c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent AUDIO_DEVICE_API_VERSION_3_0))) { 3978c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent availableOutputDeviceTypes = availablePrimaryOutputDevices(); 3979c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 3980c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 3981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // for phone strategy, we first consider the forced use and then the available devices by order 3982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // of priority 39833b73df74357b33869b39a1d69427673c780bd805Eric Laurent switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) { 39843b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_BT_SCO: 3985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isInCall() || strategy != STRATEGY_DTMF) { 39863a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 3987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 3988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 39893a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 3990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 39913a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; 3992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 3993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if SCO device is requested but no SCO device is available, fall back to default case 3994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 3995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: // FORCE_NONE 3997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 39983a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!isInCall() && 39993b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 4000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 40013a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 4002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 40033a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 4004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 40063a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 4007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 40083a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET; 4009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4010c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 4011c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (device) break; 40123b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mPhoneState != AUDIO_MODE_IN_CALL) { 40133a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 4014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 40153a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 4016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 40173a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 4018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 40193a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 4020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 40223a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE; 4023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 40241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 4025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); 4027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 40303b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_SPEAKER: 4031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 4032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // A2DP speaker when forcing to speaker output 40333a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!isInCall() && 40343b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 4035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 40363a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 4037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 40393b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mPhoneState != AUDIO_MODE_IN_CALL) { 40403a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 4041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 40423a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 4043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 40443a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 4045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 40463a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 4047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 40483a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 4049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4051ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_LINE; 4052ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund if (device) break; 40533a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 4054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 40551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 4056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); 4058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_SONIFICATION: 4064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 4066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handleIncallSonification(). 4067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 4068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); 4069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 4072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 4074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 4075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // except: 4076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - when in call where it doesn't default to STRATEGY_PHONE behavior 4077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - in countries where not enforced in which case it follows STRATEGY_MEDIA 4078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((strategy == STRATEGY_SONIFICATION) || 40803b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) { 40813a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 4082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); 4084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The second device used for sonification is the same as the device used by media strategy 4087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 4088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_MEDIA: { 4090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device2 = AUDIO_DEVICE_NONE; 4091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strategy != STRATEGY_SONIFICATION) { 4092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no sonification on remote submix (e.g. WFD) 40933a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; 4094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 40963b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 4097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (getA2dpOutput() != 0) && !mA2dpSuspended) { 40983a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 4099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 41003a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 4101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 41033a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 4104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 41073a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 4108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4109ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund if ((device2 == AUDIO_DEVICE_NONE)) { 4110ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_LINE; 4111ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund } 4112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 41133a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET; 4114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 41163a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 4117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 41193a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 4120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 41223a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 4123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { 4125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no sonification on aux digital (e.g. HDMI) 41263a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 4127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 41293b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) { 41303a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 4131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 41333a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 4134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4135839e4f33906b650140b578d42d6a51300f26703cJungshik Jang int device3 = AUDIO_DEVICE_NONE; 4136839e4f33906b650140b578d42d6a51300f26703cJungshik Jang if (strategy == STRATEGY_MEDIA) { 41377b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang // ARC, SPDIF and AUX_LINE can co-exist with others. 41380c94309d3c6db555b57f2e2e2dc3a0a2676ac6b7Jungshik Jang device3 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_HDMI_ARC; 41390c94309d3c6db555b57f2e2e2dc3a0a2676ac6b7Jungshik Jang device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPDIF); 41407b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_LINE); 4141839e4f33906b650140b578d42d6a51300f26703cJungshik Jang } 4142839e4f33906b650140b578d42d6a51300f26703cJungshik Jang 4143839e4f33906b650140b578d42d6a51300f26703cJungshik Jang device2 |= device3; 4144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 4145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise 4146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device |= device2; 4147839e4f33906b650140b578d42d6a51300f26703cJungshik Jang 41487b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang // If hdmi system audio mode is on, remove speaker out of output list. 41497b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang if ((strategy == STRATEGY_MEDIA) && 41507b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] == 41517b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) { 41527b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang device &= ~AUDIO_DEVICE_OUT_SPEAKER; 41537b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang } 41547b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang 4155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 41561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 4157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); 4159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } break; 4161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 4163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 4164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 4168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 4169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4171e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::updateDevicesAndOutputs() 4172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_STRATEGIES; i++) { 4174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 4175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 4177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 41791f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentuint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc, 4180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t prevDevice, 4181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t delayMs) 4182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute/unmute strategies using an incompatible device combination 4184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if muting, wait for the audio in pcm buffer to be drained before proceeding 4185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if unmuting, unmute only after the specified delay 4186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isDuplicated()) { 4187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 4188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs = 0; 4191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = outputDesc->device(); 41923b73df74357b33869b39a1d69427673c780bd805Eric Laurent bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2); 4193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 4195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 4196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool mute = shouldMute && (curDevice & device) && (curDevice != device); 4197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool doMute = false; 4198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mute && !outputDesc->mStrategyMutedByDevice[i]) { 4200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent doMute = true; 4201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = true; 4202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){ 4203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent doMute = true; 4204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = false; 4205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 420699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (doMute) { 4207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mOutputs.size(); j++) { 42081f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j); 4209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // skip output if it does not share any device with current output 4210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->supportedDevices() & outputDesc->supportedDevices()) 4211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent == AUDIO_DEVICE_NONE) { 4212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 4213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(j); 4215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", 4216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mute ? "muting" : "unmuting", i, curDevice, curOutput); 4217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); 4218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->isStrategyActive((routing_strategy)i)) { 421999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (mute) { 422099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // FIXME: should not need to double latency if volume could be applied 422199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // immediately by the audioflinger mixer. We must account for the delay 422299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // between now and the next time the audioflinger thread for this output 422399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // will process a buffer (which corresponds to one buffer size, 422499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // usually 1/2 or 1/4 of the latency). 422599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (muteWaitMs < desc->latency() * 2) { 422699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs = desc->latency() * 2; 4227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 423499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // temporary mute output if device selection changes to avoid volume bursts due to 423599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // different per device volumes 423699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (outputDesc->isActive() && (device != prevDevice)) { 423799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (muteWaitMs < outputDesc->latency() * 2) { 423899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs = outputDesc->latency() * 2; 423999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 424099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 424199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (outputDesc->isStrategyActive((routing_strategy)i)) { 42421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setStrategyMute((routing_strategy)i, true, outputDesc->mIoHandle); 424399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // do tempMute unmute after twice the mute wait time 42441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setStrategyMute((routing_strategy)i, false, outputDesc->mIoHandle, 424599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs *2, device); 424699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 424799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 424899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 424999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent 4250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // wait for the PCM output buffers to empty before proceeding with the rest of the command 4251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (muteWaitMs > delayMs) { 4252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs -= delayMs; 4253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent usleep(muteWaitMs * 1000); 4254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 4255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 4257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4259e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output, 4260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 4261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force, 42626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent int delayMs, 42630fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi audio_patch_handle_t *patchHandle, 42640fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi const char* address) 4265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); 42671f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 4268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param; 4269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs; 4270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isDuplicated()) { 42721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent muteWaitMs = setOutputDevice(outputDesc->mOutput1->mIoHandle, device, force, delayMs); 42731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent muteWaitMs += setOutputDevice(outputDesc->mOutput2->mIoHandle, device, force, delayMs); 4274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 4275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current 4277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // output profile 4278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device != AUDIO_DEVICE_NONE) && 42793a4311c68348f728558e87b5db67d47605783890Eric Laurent ((device & outputDesc->mProfile->mSupportedDevices.types()) == 0)) { 4280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 4281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // filter devices according to output selected 42843a4311c68348f728558e87b5db67d47605783890Eric Laurent device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices.types()); 4285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t prevDevice = outputDesc->mDevice; 4287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() prevDevice %04x", prevDevice); 4289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device != AUDIO_DEVICE_NONE) { 4291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = device; 4292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); 4294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not change the routing if: 4296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the requested device is AUDIO_DEVICE_NONE 4297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the requested device is the same as current device and force is not specified. 4298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Doing this check here allows the caller to call setOutputDevice() without conditions 4299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) { 4300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); 4301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 4302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() changing device"); 43051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 4306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do the routing 43071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (device == AUDIO_DEVICE_NONE) { 43086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent resetOutputDevice(output, delayMs, NULL); 43091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 43100fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi DeviceVector deviceList = (address == NULL) ? 43110fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi mAvailableOutputDevices.getDevicesFromType(device) 43120fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi : mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address)); 43131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (!deviceList.isEmpty()) { 43141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_patch patch; 43151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->toAudioPortConfig(&patch.sources[0]); 43161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sources = 1; 43171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks = 0; 43181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) { 43191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]); 43201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks++; 43211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 43226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 43236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) { 43246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 43256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 43266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); 43276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 43286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc; 43296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 43306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 43316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 43326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent afPatchHandle = patchDesc->mAfPatchHandle; 43336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 43346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 43351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = mpClientInterface->createAudioPatch(&patch, 43366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &afPatchHandle, 43376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent delayMs); 43381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d" 43391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent "num_sources %d num_sinks %d", 43406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, afPatchHandle, patch.num_sources, patch.num_sinks); 43411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (status == NO_ERROR) { 43426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 43436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 43446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &patch, mUidCached); 43456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent addAudioPatch(patchDesc->mHandle, patchDesc); 43466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 43476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch = patch; 43486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 43496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mAfPatchHandle = afPatchHandle; 43506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = mUidCached; 43516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 43526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *patchHandle = patchDesc->mHandle; 43536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 43546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent outputDesc->mPatchHandle = patchDesc->mHandle; 43556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 4356b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 43571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 43581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 4359f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu 4360f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu // inform all input as well 4361f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu for (size_t i = 0; i < mInputs.size(); i++) { 4362f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i); 4363f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu if (!isVirtualInputDevice(inputDescriptor->mDevice)) { 4364f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu AudioParameter inputCmd = AudioParameter(); 4365f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu ALOGV("%s: inform input %d of device:%d", __func__, 4366f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu inputDescriptor->mIoHandle, device); 4367f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu inputCmd.addInt(String8(AudioParameter::keyRouting),device); 4368f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu mpClientInterface->setParameters(inputDescriptor->mIoHandle, 4369f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu inputCmd.toString(), 4370f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu delayMs); 4371f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu } 4372f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu } 43731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 4374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update stream volumes according to new device 4376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent applyStreamVolumes(output, device, delayMs); 4377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 4379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output, 43826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent int delayMs, 43836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *patchHandle) 43841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 43851f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 43866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 43876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 43886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 43896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 43906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); 43916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 43926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 43931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return INVALID_OPERATION; 43941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 43956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index); 43966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, delayMs); 43971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status); 43981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mPatchHandle = 0; 43996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent removeAudioPatch(patchDesc->mHandle); 44006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 4401b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 44021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 44031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 44041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 44051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::setInputDevice(audio_io_handle_t input, 44061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t device, 44076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent bool force, 44086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *patchHandle) 44091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 44101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 44111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 44121f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); 44131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) { 44141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mDevice = device; 44151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 44161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device); 44171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (!deviceList.isEmpty()) { 44181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_patch patch; 44191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->toAudioPortConfig(&patch.sinks[0]); 4420daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent // AUDIO_SOURCE_HOTWORD is for internal use only: 4421daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent // handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL 4422df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD && 4423df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent !inputDesc->mIsSoundTrigger) { 4424daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION; 4425daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent } 44261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks = 1; 44271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent //only one input device for now 44281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]); 44291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sources = 1; 44306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 44316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) { 44326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 44336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 44346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 44356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 44366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc; 44376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 44386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 44396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 44406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent afPatchHandle = patchDesc->mAfPatchHandle; 44416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 44426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 44431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = mpClientInterface->createAudioPatch(&patch, 44446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &afPatchHandle, 44451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 0); 44461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d", 44476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, afPatchHandle); 44481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (status == NO_ERROR) { 44496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 44506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 44516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &patch, mUidCached); 44526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent addAudioPatch(patchDesc->mHandle, patchDesc); 44536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 44546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch = patch; 44556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 44566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mAfPatchHandle = afPatchHandle; 44576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = mUidCached; 44586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 44596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *patchHandle = patchDesc->mHandle; 44606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 44616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent inputDesc->mPatchHandle = patchDesc->mHandle; 44626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 4463b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 44641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 44651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 44661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 44671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 44681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 44691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 44706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input, 44716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *patchHandle) 44721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 44731f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); 44746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 44756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 44766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 44776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 44786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 44796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 44806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 44811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return INVALID_OPERATION; 44821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 44836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index); 44846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 44851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("resetInputDevice() releaseAudioPatch returned %d", status); 44861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mPatchHandle = 0; 44876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent removeAudioPatch(patchDesc->mHandle); 44886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 4489b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 44901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 44911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 44921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 44931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device, 4494cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten uint32_t& samplingRate, 4495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 44966a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten audio_channel_mask_t channelMask, 4497cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten audio_input_flags_t flags) 4498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Choose an input profile based on the requested capture parameters: select the first available 4500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // profile supporting all requested parameters. 4501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 4503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 4504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 4505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 4506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 4508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 45091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j]; 4510d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // profile->log(); 4511cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (profile->isCompatibleProfile(device, samplingRate, 4512cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten &samplingRate /*updatedSamplingRate*/, 4513cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten format, channelMask, (audio_output_flags_t) flags)) { 4514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return profile; 4515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NULL; 4519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4521e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource) 4522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 45243a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & 45253a4311c68348f728558e87b5db67d47605783890Eric Laurent ~AUDIO_DEVICE_BIT_IN; 4526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (inputSource) { 4527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 45283a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { 4529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 4530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4532c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 4533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_DEFAULT: 4535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_MIC: 453641b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) { 453741b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP; 4538c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { 4539c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_WIRED_HEADSET; 4540c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { 4541c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_USB_DEVICE; 4542c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 4543c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 454441b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood } 4545c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 4546c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 4547c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent case AUDIO_SOURCE_VOICE_COMMUNICATION: 4548c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // Allow only use of devices on primary input if in call and HAL does not support routing 4549c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // to voice call path. 4550c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if ((mPhoneState == AUDIO_MODE_IN_CALL) && 4551c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent (mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) { 4552c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent availableDeviceTypes = availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN; 4553c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 4554c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 4555c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) { 4556c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent case AUDIO_POLICY_FORCE_BT_SCO: 4557c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // if SCO device is requested but no SCO device is available, fall back to default case 4558c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 4559c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 4560c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 4561c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 4562c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // FALL THROUGH 4563c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 4564c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent default: // FORCE_NONE 4565c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { 4566c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_WIRED_HEADSET; 4567c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { 4568c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_USB_DEVICE; 4569c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 4570c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 4571c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 4572c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 4573c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 4574c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent case AUDIO_POLICY_FORCE_SPEAKER: 4575c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) { 4576c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_BACK_MIC; 4577c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 4578c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 4579c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 4580c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 4581c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 4582c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 458341b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood 4584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_RECOGNITION: 4585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_HOTWORD: 45863b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO && 45873a4311c68348f728558e87b5db67d47605783890Eric Laurent availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 4588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 45893a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { 4590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_WIRED_HEADSET; 4591d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { 4592d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent device = AUDIO_DEVICE_IN_USB_DEVICE; 45933a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 4594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 4595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_CAMCORDER: 45983a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) { 4599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BACK_MIC; 46003a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 4601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 4602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_DOWNLINK: 4605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_CALL: 46063a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { 4607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 4608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_REMOTE_SUBMIX: 46113a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { 4612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; 4613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 4616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 4617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 4620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 4621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4623e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device) 4624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & AUDIO_DEVICE_BIT_IN) != 0) { 4626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device &= ~AUDIO_DEVICE_BIT_IN; 4627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) 4628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 4629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 46330fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivibool AudioPolicyManager::deviceDistinguishesOnAddress(audio_devices_t device) { 46340fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi return ((device & APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL) != 0); 46350fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi} 46360fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi 4637e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs) 4638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 46401f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioInputDescriptor> input_descriptor = mInputs.valueAt(i); 4641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((input_descriptor->mRefCount > 0) 4642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) { 4643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mInputs.keyAt(i); 4644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 4647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4649df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentuint32_t AudioPolicyManager::activeInputsCount() const 4650df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 4651df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent uint32_t count = 0; 4652df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 4653df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent const sp<AudioInputDescriptor> desc = mInputs.valueAt(i); 4654df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (desc->mRefCount > 0) { 4655df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return count++; 4656df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 4657df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 4658df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return count; 4659df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 4660df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 4661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4662e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device) 4663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this happens when forcing a route update and no track is active on an output. 4666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // In this case the returned category is not important. 4667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 46683b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (popcount(device) > 1) { 4669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Multiple device selection is either: 4670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - speaker + one other device: give priority to speaker in this case. 4671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 4672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 4673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // selection if not the speaker. 4674a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang // - HDMI-CEC system audio mode only output: give priority to available item in order. 4675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 4676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 4677a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang } else if (device & AUDIO_DEVICE_OUT_HDMI_ARC) { 4678a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang device = AUDIO_DEVICE_OUT_HDMI_ARC; 4679a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang } else if (device & AUDIO_DEVICE_OUT_AUX_LINE) { 4680a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang device = AUDIO_DEVICE_OUT_AUX_LINE; 4681a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang } else if (device & AUDIO_DEVICE_OUT_SPDIF) { 4682a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang device = AUDIO_DEVICE_OUT_SPDIF; 4683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 4685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 468811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund /*SPEAKER_SAFE is an alias of SPEAKER for purposes of volume control*/ 468911c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund if (device == AUDIO_DEVICE_OUT_SPEAKER_SAFE) 469011c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund device = AUDIO_DEVICE_OUT_SPEAKER; 469111c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund 46923b73df74357b33869b39a1d69427673c780bd805Eric Laurent ALOGW_IF(popcount(device) != 1, 4693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 4694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device); 4695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 4697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4699e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device) 4700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(getDeviceForVolume(device)) { 4702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 4703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_EARPIECE; 4704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 4705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 4706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 4707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 4708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 4709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 4710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_HEADSET; 4711ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund case AUDIO_DEVICE_OUT_LINE: 4712ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund case AUDIO_DEVICE_OUT_AUX_DIGITAL: 4713ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund /*USB? Remote submix?*/ 4714ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund return DEVICE_CATEGORY_EXT_MEDIA; 4715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 4716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 4717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 4718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_USB_ACCESSORY: 4719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_USB_DEVICE: 4720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_REMOTE_SUBMIX: 4721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 4722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_SPEAKER; 4723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4726e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, 4727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexInUi) 4728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device_category deviceCategory = getDeviceCategory(device); 4730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 4731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the volume index in the UI is relative to the min and max volume indices for this stream type 4733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 4734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[VOLMIN].mIndex; 4735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 4736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (streamDesc.mIndexMax - streamDesc.mIndexMin); 4737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // find what part of the curve this index volume belongs to, or if it's out of bounds 4739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int segment = 0; 4740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 4741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0.0f; 4742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 4743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 0; 4744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 4745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 1; 4746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 4747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 2; 4748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { // out of bounds 4749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 1.0f; 4750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // linear interpolation in the attenuation table in dB 4753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float decibels = curve[segment].mDBAttenuation + 4754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 4755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ( (curve[segment+1].mDBAttenuation - 4756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mDBAttenuation) / 4757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((float)(curve[segment+1].mIndex - 4758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mIndex)) ); 4759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 4761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 4763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mIndex, volIdx, 4764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment+1].mIndex, 4765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mDBAttenuation, 4766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent decibels, 4767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment+1].mDBAttenuation, 4768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent amplification); 4769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return amplification; 4771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4773e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4774e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultVolumeCurve[AudioPolicyManager::VOLCNT] = { 4775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 4776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4778e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4779e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { 4780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 4781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4783e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4784ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund AudioPolicyManager::sExtMediaSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 4785ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund {1, -58.0f}, {20, -40.0f}, {60, -21.0f}, {100, -10.0f} 4786ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund}; 4787ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund 4788ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklundconst AudioPolicyManager::VolumeCurvePoint 4789e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { 4790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 4791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4793e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4794ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi AudioPolicyManager::sSpeakerMediaVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 479598c6043e089743355bb6686176877f2ba5125213Jean-Michel Trivi {1, -55.0f}, {20, -43.0f}, {86, -12.0f}, {100, 0.0f} 4796ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi}; 4797ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi 4798ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Triviconst AudioPolicyManager::VolumeCurvePoint 4799e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = { 4800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 4801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4803e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4804e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 4805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f} 4806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks 4809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets. 4810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java). 4811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset. 4812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4813e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4814e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 4815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f} 4816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4818e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4819e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 4820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f} 4821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4823e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4824e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 4825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f} 4826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4828e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4829e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { 4830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f} 4831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4833e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4834e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { 4835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f} 4836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4838e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 4839e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT] 4840e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent [AudioPolicyManager::DEVICE_CATEGORY_CNT] = { 4841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_VOICE_CALL 4842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 4843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4844ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE 4845ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 4846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_SYSTEM 4848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 4849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4850ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE 4851ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 4852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_RING 4854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 4855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4856ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultVolumeCurve, // DEVICE_CATEGORY_EARPIECE 4857ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 4858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_MUSIC 4860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 4861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4862ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE 4863ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 4864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_ALARM 4866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 4867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4868ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultVolumeCurve, // DEVICE_CATEGORY_EARPIECE 4869ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 4870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_NOTIFICATION 4872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 4873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4874ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultVolumeCurve, // DEVICE_CATEGORY_EARPIECE 4875ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 4876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_BLUETOOTH_SCO 4878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 4879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4880ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE 4881ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 4882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_ENFORCED_AUDIBLE 4884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 4885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4886ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE 4887ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 4888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_DTMF 4890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 4891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4892ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE 4893ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 4894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_TTS 4896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 4897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 4898ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE 4899ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 4900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 4901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 4902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4903e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initializeVolumeCurves() 4904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 4906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 4907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[i].mVolumeCurve[j] = 4908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[i][j]; 4909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check availability of DRC on speaker path: if available, override some of the speaker curves 4913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mSpeakerDrcEnabled) { 4914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 4915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurveDrc; 4916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 4917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 4918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 4919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 4920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 4921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 4922ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi mStreams[AUDIO_STREAM_MUSIC].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 4923ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi sSpeakerMediaVolumeCurveDrc; 4924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4927e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::computeVolume(audio_stream_type_t stream, 4928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 4929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 4930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 4931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float volume = 1.0; 49331f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 4934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent StreamDescriptor &streamDesc = mStreams[stream]; 4935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = outputDesc->device(); 4938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume = volIndexToAmpl(device, streamDesc, index); 4941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if a headset is connected, apply the following rules to ring tones and notifications 4943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // to avoid sound level bursts in user's ears: 4944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - always attenuate ring tones and notifications volume by 6dB 4945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - if music is playing, always limit the volume to current music volume, 4946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // with a minimum threshold at -36dB so that notification is always perceived. 49473b73df74357b33869b39a1d69427673c780bd805Eric Laurent const routing_strategy stream_strategy = getStrategy(stream); 4948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | 4949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 4950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADSET | 4951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) && 4952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((stream_strategy == STRATEGY_SONIFICATION) 4953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) 49543b73df74357b33869b39a1d69427673c780bd805Eric Laurent || (stream == AUDIO_STREAM_SYSTEM) 4955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) && 49563b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) && 4957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent streamDesc.mCanBeMuted) { 4958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 4959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when the phone is ringing we must consider that music could have been paused just before 4960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by the music application and behave as if music was active if the last music track was 4961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // just stopped 49623b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || 4963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume) { 4964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/); 49653b73df74357b33869b39a1d69427673c780bd805Eric Laurent float musicVol = computeVolume(AUDIO_STREAM_MUSIC, 49663b73df74357b33869b39a1d69427673c780bd805Eric Laurent mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice), 4967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 4968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent musicDevice); 4969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 4970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 4971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volume > minVol) { 4972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume = minVol; 4973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 4974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return volume; 4979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4981e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream, 4982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 4983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 4984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 4985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 4986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force) 4987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not change actual stream volume if the stream is muted 4990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 4991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkAndSetVolume() stream %d muted count %d", 4992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, mOutputs.valueFor(output)->mMuteCount[stream]); 4993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 4994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not change in call volume if bluetooth is connected and vice versa 49973b73df74357b33869b39a1d69427673c780bd805Eric Laurent if ((stream == AUDIO_STREAM_VOICE_CALL && 49983b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) || 49993b73df74357b33869b39a1d69427673c780bd805Eric Laurent (stream == AUDIO_STREAM_BLUETOOTH_SCO && 50003b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO)) { 5001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 50023b73df74357b33869b39a1d69427673c780bd805Eric Laurent stream, mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]); 5003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 5004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float volume = computeVolume(stream, index, output, device); 5007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // We actually change the volume if: 5008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the float value returned by computeVolume() changed 5009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the force flag is set 5010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 5011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force) { 5012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.valueFor(output)->mCurVolume[stream] = volume; 5013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 5014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 5015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // enabled 50163b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_BLUETOOTH_SCO) { 50173b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs); 5018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 50193b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->setStreamVolume(stream, volume, output, delayMs); 5020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 50223b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_VOICE_CALL || 50233b73df74357b33869b39a1d69427673c780bd805Eric Laurent stream == AUDIO_STREAM_BLUETOOTH_SCO) { 5024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float voiceVolume; 5025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force voice volume to max for bluetooth SCO as volume is managed by the headset 50263b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_VOICE_CALL) { 5027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 5028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent voiceVolume = 1.0; 5030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { 5033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 5034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLastVoiceVolume = voiceVolume; 5035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 5039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5041e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output, 5042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 5043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 5044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force) 5045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("applyStreamVolumes() for output %d and device %x", output, device); 5047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 50483b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 50493b73df74357b33869b39a1d69427673c780bd805Eric Laurent checkAndSetVolume((audio_stream_type_t)stream, 5050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].getVolumeIndex(device), 5051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 5052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, 5053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs, 5054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force); 5055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5058e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStrategyMute(routing_strategy strategy, 5059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool on, 5060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 5061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 5062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 5063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 50653b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 50663b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (getStrategy((audio_stream_type_t)stream) == strategy) { 50673b73df74357b33869b39a1d69427673c780bd805Eric Laurent setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device); 5068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5072e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStreamMute(audio_stream_type_t stream, 5073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool on, 5074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 5075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 5076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 5077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent StreamDescriptor &streamDesc = mStreams[stream]; 50791f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 5080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 5081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = outputDesc->device(); 5082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x", 5085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, on, output, outputDesc->mMuteCount[stream], device); 5086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (on) { 5088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mMuteCount[stream] == 0) { 5089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (streamDesc.mCanBeMuted && 50903b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) || 50913b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) { 5092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 5093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 5096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mMuteCount[stream]++; 5097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mMuteCount[stream] == 0) { 5099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setStreamMute() unmuting non muted stream!"); 5100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 5101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (--outputDesc->mMuteCount[stream] == 0) { 5103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 5104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent streamDesc.getVolumeIndex(device), 5105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 5106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, 5107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs); 5108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5112e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream, 51133b73df74357b33869b39a1d69427673c780bd805Eric Laurent bool starting, bool stateChange) 5114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if the stream pertains to sonification strategy and we are in call we must 5116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute the stream if it is low visibility. If it is high visibility, we must play a tone 5117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the device used for phone strategy and play the tone if the selected device does not 5118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // interfere with the device used for phone strategy 5119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 5120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // many times as there are active tracks on the output 51213b73df74357b33869b39a1d69427673c780bd805Eric Laurent const routing_strategy stream_strategy = getStrategy(stream); 5122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((stream_strategy == STRATEGY_SONIFICATION) || 5123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { 51241f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput); 5125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 5126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, starting, outputDesc->mDevice, stateChange); 5127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream]) { 5128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int muteCount = 1; 5129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (stateChange) { 5130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteCount = outputDesc->mRefCount[stream]; 5131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 51323b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (audio_is_low_visibility(stream)) { 5133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 5134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < muteCount; i++) { 5135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 5136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() high visibility"); 5139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->device() & 5140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) { 5141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 5142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < muteCount; i++) { 5143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 5144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (starting) { 51473b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION, 51483b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_STREAM_VOICE_CALL); 5149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->stopTone(); 5151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5157e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isInCall() 5158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return isStateInCall(mPhoneState); 5160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5162e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStateInCall(int state) { 51633b73df74357b33869b39a1d69427673c780bd805Eric Laurent return ((state == AUDIO_MODE_IN_CALL) || 51643b73df74357b33869b39a1d69427673c780bd805Eric Laurent (state == AUDIO_MODE_IN_COMMUNICATION)); 5165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5167e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsCpuLoad() 5168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return MAX_EFFECTS_CPU_LOAD; 5170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5172e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsMemory() 5173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return MAX_EFFECTS_MEMORY; 5175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 51776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 5178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioOutputDescriptor class implementation 5179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5180e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor( 51811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile>& profile) 51821f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent : mId(0), mIoHandle(0), mLatency(0), 51831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), 5184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0) 5185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // clear usage count for all stream types 51873b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 5188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[i] = 0; 5189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurVolume[i] = -1.0; 5190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mMuteCount[i] = 0; 5191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStopTime[i] = 0; 5192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_STRATEGIES; i++) { 5194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStrategyMutedByDevice[i] = false; 5195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile != NULL) { 5197d8622371d5ac5b98abcc5d388bd952bb3dd4fda9Eric Laurent mFlags = profile->mFlags; 51981e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mSamplingRate = profile->pickSamplingRate(); 51991e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mFormat = profile->pickFormat(); 52001e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mChannelMask = profile->pickChannelMask(); 5201a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (profile->mGains.size() > 0) { 5202a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent profile->mGains[0]->getDefaultConfig(&mGain); 5203a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5207e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::device() const 5208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 5210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 5211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mDevice; 5213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5216e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::AudioOutputDescriptor::latency() 5217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 5219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 5220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mLatency; 5222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5225e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith( 52261f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioOutputDescriptor> outputDesc) 5227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 5229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 5230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isDuplicated()){ 5231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2); 5232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mProfile->mModule == outputDesc->mProfile->mModule); 5234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5237e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 52383b73df74357b33869b39a1d69427673c780bd805Eric Laurent int delta) 5239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // forward usage count change to attached outputs 5241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 5242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput1->changeRefCount(stream, delta); 5243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput2->changeRefCount(stream, delta); 5244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((delta + (int)mRefCount[stream]) < 0) { 52463b73df74357b33869b39a1d69427673c780bd805Eric Laurent ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", 52473b73df74357b33869b39a1d69427673c780bd805Eric Laurent delta, stream, mRefCount[stream]); 5248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[stream] = 0; 5249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 5250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[stream] += delta; 5252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 5253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5255e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::supportedDevices() 5256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 5258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 5259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 52603a4311c68348f728558e87b5db67d47605783890Eric Laurent return mProfile->mSupportedDevices.types() ; 5261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5264e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isActive(uint32_t inPastMs) const 5265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return isStrategyActive(NUM_STRATEGIES, inPastMs); 5267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5269e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy, 5270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t inPastMs, 5271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime) const 5272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((sysTime == 0) && (inPastMs != 0)) { 5274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime = systemTime(); 5275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 52763b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 52773b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (((getStrategy((audio_stream_type_t)i) == strategy) || 5278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (NUM_STRATEGIES == strategy)) && 52793b73df74357b33869b39a1d69427673c780bd805Eric Laurent isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) { 5280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 5281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 5284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5286e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, 5287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t inPastMs, 5288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime) const 5289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mRefCount[stream] != 0) { 5291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 5292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (inPastMs == 0) { 5294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 5295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (sysTime == 0) { 5297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime = systemTime(); 5298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 5300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 5301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 5303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 53051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::toAudioPortConfig( 53066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port_config *dstConfig, 53076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const struct audio_port_config *srcConfig) const 53086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 530984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle); 531084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent 53116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 53121f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 53136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (srcConfig != NULL) { 531484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent dstConfig->config_mask |= srcConfig->config_mask; 53156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 53161f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 53171f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 53181f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->id = mId; 53191f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->role = AUDIO_PORT_ROLE_SOURCE; 53201f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->type = AUDIO_PORT_TYPE_MIX; 53216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle; 53226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.mix.handle = mIoHandle; 53236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 53241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 53251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 53261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::toAudioPort( 53271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_port *port) const 53281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 532984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle); 53301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mProfile->toAudioPort(port); 53311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 53326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent toAudioPortConfig(&port->active_config); 53336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent port->ext.mix.hw_module = mProfile->mModule->mHandle; 53341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.handle = mIoHandle; 53351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.latency_class = 53361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL; 53371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 5338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5339e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd) 5340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 5342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 5343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 5344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 53454d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, " ID: %d\n", mId); 53464d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 5347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 5348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 5350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 5352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 5354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 5356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Devices %08x\n", device()); 5358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 5360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 53613b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 53623b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", 53633b73df74357b33869b39a1d69427673c780bd805Eric Laurent i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 5364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 5367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 5369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioInputDescriptor class implementation 5372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 53731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile) 53741f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent : mId(0), mIoHandle(0), 53751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mRefCount(0), 5376df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile), mIsSoundTrigger(false) 5377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 53783a4311c68348f728558e87b5db67d47605783890Eric Laurent if (profile != NULL) { 53791e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mSamplingRate = profile->pickSamplingRate(); 53801e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mFormat = profile->pickFormat(); 53811e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mChannelMask = profile->pickChannelMask(); 5382a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (profile->mGains.size() > 0) { 5383a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent profile->mGains[0]->getDefaultConfig(&mGain); 5384a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 53853a4311c68348f728558e87b5db67d47605783890Eric Laurent } 5386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 53881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioInputDescriptor::toAudioPortConfig( 53896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port_config *dstConfig, 53906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const struct audio_port_config *srcConfig) const 53916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 539284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(mProfile != 0, 539384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent "toAudioPortConfig() called on input with null profile %d", mIoHandle); 53946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 53951f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 53966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (srcConfig != NULL) { 539784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent dstConfig->config_mask |= srcConfig->config_mask; 53986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 53991f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 54001f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 54011f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 54021f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->id = mId; 54031f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->role = AUDIO_PORT_ROLE_SINK; 54041f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->type = AUDIO_PORT_TYPE_MIX; 540562aaabb3905c61bb7acd6037414c206240a31c32Eric Laurent dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle; 540662aaabb3905c61bb7acd6037414c206240a31c32Eric Laurent dstConfig->ext.mix.handle = mIoHandle; 540762aaabb3905c61bb7acd6037414c206240a31c32Eric Laurent dstConfig->ext.mix.usecase.source = mInputSource; 54081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 54091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 54101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioInputDescriptor::toAudioPort( 54111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_port *port) const 54121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 541384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle); 541484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent 54151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mProfile->toAudioPort(port); 54161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 54176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent toAudioPortConfig(&port->active_config); 54186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent port->ext.mix.hw_module = mProfile->mModule->mHandle; 54191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.handle = mIoHandle; 54201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL; 54211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 54221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 5423e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioInputDescriptor::dump(int fd) 5424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 5426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 5427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 5428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 54294d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, " ID: %d\n", mId); 54304d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 5431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 5432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Format: %d\n", mFormat); 5434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 5436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 5438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 5440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 54416a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten snprintf(buffer, SIZE, " Open Ref Count %d\n", mOpenRefCount); 54426a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten result.append(buffer); 54436a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten 5444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 5445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 5447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- StreamDescriptor class implementation 5450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5451e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::StreamDescriptor::StreamDescriptor() 5452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 5453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 5455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5457e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::StreamDescriptor::getVolumeIndex(audio_devices_t device) 5458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5459e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent device = AudioPolicyManager::getDeviceForVolume(device); 5460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 5461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 5462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 5463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mIndexCur.valueFor(device); 5465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5467e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::StreamDescriptor::dump(int fd) 5468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 5470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 5471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 5472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 5474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 5475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 5477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 5478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.keyAt(i), 5479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.valueAt(i)); 5480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append("\n"); 5483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 5485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- EffectDescriptor class implementation 5488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5489e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::EffectDescriptor::dump(int fd) 5490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 5492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 5493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 5494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 5496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 5498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Session: %d\n", mSession); 5500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 5502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 5504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 5506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 5508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 55101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- HwModule class implementation 5511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5512e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::HwModule(const char *name) 5513eb108a4622825688b02d7afc981014d149913cd8Eric Laurent : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), 5514eb108a4622825688b02d7afc981014d149913cd8Eric Laurent mHalVersion(AUDIO_DEVICE_API_VERSION_MIN), mHandle(0) 5515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5518e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::~HwModule() 5519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 55213a4311c68348f728558e87b5db67d47605783890Eric Laurent mOutputProfiles[i]->mSupportedDevices.clear(); 5522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 55243a4311c68348f728558e87b5db67d47605783890Eric Laurent mInputProfiles[i]->mSupportedDevices.clear(); 5525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free((void *)mName); 5527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 55291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::HwModule::loadInput(cnode *root) 55301afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 55311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 55321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 55331afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SINK, this); 55341afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 55351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 55361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 55371afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadSamplingRates((char *)node->value); 55381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 55391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadFormats((char *)node->value); 55401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 55411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadInChannels((char *)node->value); 55421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 55431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.loadDevicesFromName((char *)node->value, 55441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices); 55451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAINS_TAG) == 0) { 55461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadGains(node); 55471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 55481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 55491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 55501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSupportedDevices.isEmpty(), 55511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported devices"); 55521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 55531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported channel masks"); 55541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 55551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported sampling rates"); 55561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mFormats.size() == 0, 55571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported formats"); 55581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (!profile->mSupportedDevices.isEmpty() && 55591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mChannelMasks.size() != 0) && 55601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mSamplingRates.size() != 0) && 55611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mFormats.size() != 0)) { 55621afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 55631afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadInput() adding input Supported Devices %04x", 55641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.types()); 55651afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 55661afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mInputProfiles.add(profile); 55671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return NO_ERROR; 55681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 55691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return BAD_VALUE; 55701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 55711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 55721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 55731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::HwModule::loadOutput(cnode *root) 55741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 55751afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 55761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 55771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SOURCE, this); 55781afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 55791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 55801afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 55811afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadSamplingRates((char *)node->value); 55821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 55831afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadFormats((char *)node->value); 55841afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 55851afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadOutChannels((char *)node->value); 55861afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 55871afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.loadDevicesFromName((char *)node->value, 55881afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices); 55891afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, FLAGS_TAG) == 0) { 55901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mFlags = parseFlagNames((char *)node->value); 55911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAINS_TAG) == 0) { 55921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadGains(node); 55931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 55941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 55951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 55961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSupportedDevices.isEmpty(), 55971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported devices"); 55981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 55991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported channel masks"); 56001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 56011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported sampling rates"); 56021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mFormats.size() == 0, 56031afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported formats"); 56041afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (!profile->mSupportedDevices.isEmpty() && 56051afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mChannelMasks.size() != 0) && 56061afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mSamplingRates.size() != 0) && 56071afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mFormats.size() != 0)) { 56081afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 56091afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x", 56101afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.types(), profile->mFlags); 56111afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 56121afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mOutputProfiles.add(profile); 56131afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return NO_ERROR; 56141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 56151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return BAD_VALUE; 56161afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 56171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 56181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 56191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::HwModule::loadDevice(cnode *root) 56201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 56211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 56221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 56231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent audio_devices_t type = AUDIO_DEVICE_NONE; 56241afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 56251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, DEVICE_TYPE) == 0) { 56261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent type = parseDeviceNames((char *)node->value); 56271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent break; 56281afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 56291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 56301afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 56311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (type == AUDIO_DEVICE_NONE || 56321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (!audio_is_input_device(type) && !audio_is_output_device(type))) { 56331afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW("loadDevice() bad type %08x", type); 56341afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return BAD_VALUE; 56351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 56361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> deviceDesc = new DeviceDescriptor(String8(root->name), type); 56371afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->mModule = this; 56381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 56391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = root->first_child; 56401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 56411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, DEVICE_ADDRESS) == 0) { 56421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->mAddress = String8((char *)node->value); 56431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 56441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (audio_is_input_device(type)) { 56451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->loadInChannels((char *)node->value); 56461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 56471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->loadOutChannels((char *)node->value); 56481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 56491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAINS_TAG) == 0) { 56501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->loadGains(node); 56511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 56521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 56531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 56541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 56551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadDevice() adding device name %s type %08x address %s", 56561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->mName.string(), type, deviceDesc->mAddress.string()); 56571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 56581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices.add(deviceDesc); 56591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 56601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return NO_ERROR; 56611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 56621afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 5663e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::HwModule::dump(int fd) 5664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 5666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 5667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 5668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - name: %s\n", mName); 5670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 5672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 5673eb108a4622825688b02d7afc981014d149913cd8Eric Laurent snprintf(buffer, SIZE, " - version: %u.%u\n", mHalVersion >> 8, mHalVersion & 0xFF); 5674eb108a4622825688b02d7afc981014d149913cd8Eric Laurent result.append(buffer); 5675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 5676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mOutputProfiles.size()) { 5677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, " - outputs:\n", strlen(" - outputs:\n")); 5678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 5679d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " output %zu:\n", i); 5680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 5681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputProfiles[i]->dump(fd); 5682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mInputProfiles.size()) { 5685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, " - inputs:\n", strlen(" - inputs:\n")); 5686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 5687d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " input %zu:\n", i); 5688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 5689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputProfiles[i]->dump(fd); 5690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 56921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mDeclaredDevices.size()) { 56931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, " - devices:\n", strlen(" - devices:\n")); 56941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mDeclaredDevices.size(); i++) { 56951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices[i]->dump(fd, 4, i); 56961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 56971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 5698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 57001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- AudioPort class implementation 57011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 5702a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 5703a121f90f388343dc48793cbc7eb899aba42e7664Eric LaurentAudioPolicyManager::AudioPort::AudioPort(const String8& name, audio_port_type_t type, 5704a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audio_port_role_t role, const sp<HwModule>& module) : 57051e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mName(name), mType(type), mRole(role), mModule(module), mFlags((audio_output_flags_t)0) 5706a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 5707a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mUseInChannelMask = ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) || 5708a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK)); 5709a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 5710a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 57111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const 57121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 57131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->role = mRole; 57141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->type = mType; 57151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent unsigned int i; 57161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) { 5717f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (mSamplingRates[i] != 0) { 5718f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi port->sample_rates[i] = mSamplingRates[i]; 5719f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 57201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 57211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_sample_rates = i; 57221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) { 5723f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (mChannelMasks[i] != 0) { 5724f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi port->channel_masks[i] = mChannelMasks[i]; 5725f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 57261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 57271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_channel_masks = i; 57281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) { 5729f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (mFormats[i] != 0) { 5730f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi port->formats[i] = mFormats[i]; 5731f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 57321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 57331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_formats = i; 5734e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 5735beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size()); 5736e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 5737e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) { 5738e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent port->gains[i] = mGains[i]->mGain; 5739e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 5740e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent port->num_gains = i; 57411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 57421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 5743f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivivoid AudioPolicyManager::AudioPort::importAudioPort(const sp<AudioPort> port) { 5744f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t k = 0 ; k < port->mSamplingRates.size() ; k++) { 5745f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi const uint32_t rate = port->mSamplingRates.itemAt(k); 5746f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (rate != 0) { // skip "dynamic" rates 5747f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi bool hasRate = false; 5748f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t l = 0 ; l < mSamplingRates.size() ; l++) { 5749f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (rate == mSamplingRates.itemAt(l)) { 5750f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi hasRate = true; 5751f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi break; 5752f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5753f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5754f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (!hasRate) { // never import a sampling rate twice 5755f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mSamplingRates.add(rate); 5756f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5757f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5758f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5759f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t k = 0 ; k < port->mChannelMasks.size() ; k++) { 5760f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi const audio_channel_mask_t mask = port->mChannelMasks.itemAt(k); 5761f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (mask != 0) { // skip "dynamic" masks 5762f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi bool hasMask = false; 5763f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t l = 0 ; l < mChannelMasks.size() ; l++) { 5764f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (mask == mChannelMasks.itemAt(l)) { 5765f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi hasMask = true; 5766f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi break; 5767f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5768f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5769f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (!hasMask) { // never import a channel mask twice 5770f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mChannelMasks.add(mask); 5771f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5772f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5773f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5774f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t k = 0 ; k < port->mFormats.size() ; k++) { 5775f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi const audio_format_t format = port->mFormats.itemAt(k); 5776f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (format != 0) { // skip "dynamic" formats 5777f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi bool hasFormat = false; 5778f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t l = 0 ; l < mFormats.size() ; l++) { 5779f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (format == mFormats.itemAt(l)) { 5780f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi hasFormat = true; 5781f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi break; 5782f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5783f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5784f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (!hasFormat) { // never import a channel mask twice 5785f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mFormats.add(format); 5786f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5787f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5788f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 5789f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi} 5790f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi 5791f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivivoid AudioPolicyManager::AudioPort::clearCapabilities() { 5792f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mChannelMasks.clear(); 5793f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mFormats.clear(); 5794f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mSamplingRates.clear(); 5795f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi} 57961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 57971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadSamplingRates(char *name) 57981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 57991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent char *str = strtok(name, "|"); 58001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling 58021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // rates should be read from the output stream after it is opened for the first time 58031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 58041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mSamplingRates.add(0); 58051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 58061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 58091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent uint32_t rate = atoi(str); 58101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (rate != 0) { 58111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadSamplingRates() adding rate %d", rate); 58121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mSamplingRates.add(rate); 58131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 58151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 58171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadFormats(char *name) 58191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 58201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent char *str = strtok(name, "|"); 58211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mFormats indicates the supported formats 58231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // should be read from the output stream after it is opened for the first time 58241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 58251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFormats.add(AUDIO_FORMAT_DEFAULT); 58261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 58271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 58301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable, 58311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 58321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 58331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (format != AUDIO_FORMAT_DEFAULT) { 58341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFormats.add(format); 58351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 58371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 58391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadInChannels(char *name) 58411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 58421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const char *str = strtok(name, "|"); 58431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadInChannels() %s", name); 58451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 58471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(0); 58481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 58491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 58521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_channel_mask_t channelMask = 58531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 58541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 58551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 58561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (channelMask != 0) { 58571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadInChannels() adding channelMask %04x", channelMask); 58581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(channelMask); 58591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 58611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 58631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadOutChannels(char *name) 58651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 58661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const char *str = strtok(name, "|"); 58671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadOutChannels() %s", name); 58691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mChannelMasks indicates the supported channel 58711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // masks should be read from the output stream after it is opened for the first time 58721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 58731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(0); 58741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 58751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 58781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_channel_mask_t channelMask = 58791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 58801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 58811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 58821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (channelMask != 0) { 58831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(channelMask); 58841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 58861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 58871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 58881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 58891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 58901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentaudio_gain_mode_t AudioPolicyManager::AudioPort::loadGainMode(char *name) 58911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 58921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const char *str = strtok(name, "|"); 58931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 58941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadGainMode() %s", name); 58951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent audio_gain_mode_t mode = 0; 58961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (str != NULL) { 58971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mode |= (audio_gain_mode_t)stringToEnum(sGainModeNameToEnumTable, 58981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sGainModeNameToEnumTable), 58991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent str); 59001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent str = strtok(NULL, "|"); 59011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 59021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return mode; 59031afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 59041afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 5905a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentvoid AudioPolicyManager::AudioPort::loadGain(cnode *root, int index) 59061afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 59071afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 59081afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 5909a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent sp<AudioGain> gain = new AudioGain(index, mUseInChannelMask); 59101afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 59111afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 59121afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, GAIN_MODE) == 0) { 59131afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.mode = loadGainMode((char *)node->value); 59141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_CHANNELS) == 0) { 5915a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mUseInChannelMask) { 59161afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.channel_mask = 59171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 59181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 59191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (char *)node->value); 59201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 59211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.channel_mask = 59221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 59231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 59241afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (char *)node->value); 59251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 59261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MIN_VALUE) == 0) { 59271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.min_value = atoi((char *)node->value); 59281afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MAX_VALUE) == 0) { 59291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.max_value = atoi((char *)node->value); 59301afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_DEFAULT_VALUE) == 0) { 59311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.default_value = atoi((char *)node->value); 59321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_STEP_VALUE) == 0) { 59331afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.step_value = atoi((char *)node->value); 59341afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MIN_RAMP_MS) == 0) { 59351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.min_ramp_ms = atoi((char *)node->value); 59361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MAX_RAMP_MS) == 0) { 59371afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.max_ramp_ms = atoi((char *)node->value); 59381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 59391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 59401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 59411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 59421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadGain() adding new gain mode %08x channel mask %08x min mB %d max mB %d", 59431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.mode, gain->mGain.channel_mask, gain->mGain.min_value, gain->mGain.max_value); 59441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 59451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (gain->mGain.mode == 0) { 59461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return; 59471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 59481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mGains.add(gain); 59491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 59501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 59511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::AudioPort::loadGains(cnode *root) 59521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 59531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 5954a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent int index = 0; 59551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 59561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadGains() loading gain %s", node->name); 5957a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent loadGain(node, index++); 59581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 59591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 59601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 59611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 5962cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kastenstatus_t AudioPolicyManager::AudioPort::checkExactSamplingRate(uint32_t samplingRate) const 5963a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 5964a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i ++) { 5965a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mSamplingRates[i] == samplingRate) { 5966a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 5967a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5968a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5969a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 5970a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 5971a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 5972cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kastenstatus_t AudioPolicyManager::AudioPort::checkCompatibleSamplingRate(uint32_t samplingRate, 5973cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten uint32_t *updatedSamplingRate) const 5974cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten{ 5975cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // Search for the closest supported sampling rate that is above (preferred) 5976cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // or below (acceptable) the desired sampling rate, within a permitted ratio. 5977cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // The sampling rates do not need to be sorted in ascending order. 5978cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten ssize_t maxBelow = -1; 5979cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten ssize_t minAbove = -1; 5980cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten uint32_t candidate; 5981cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten for (size_t i = 0; i < mSamplingRates.size(); i++) { 5982cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten candidate = mSamplingRates[i]; 5983cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (candidate == samplingRate) { 5984cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (updatedSamplingRate != NULL) { 5985cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten *updatedSamplingRate = candidate; 5986cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 5987cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return NO_ERROR; 5988cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 5989cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // candidate < desired 5990cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (candidate < samplingRate) { 5991cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (maxBelow < 0 || candidate > mSamplingRates[maxBelow]) { 5992cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten maxBelow = i; 5993cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 5994cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // candidate > desired 5995cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } else { 5996cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (minAbove < 0 || candidate < mSamplingRates[minAbove]) { 5997cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten minAbove = i; 5998cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 5999cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6000cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6001cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // This uses hard-coded knowledge about AudioFlinger resampling ratios. 6002cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // TODO Move these assumptions out. 6003cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten static const uint32_t kMaxDownSampleRatio = 6; // beyond this aliasing occurs 6004cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten static const uint32_t kMaxUpSampleRatio = 256; // beyond this sample rate inaccuracies occur 6005cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // due to approximation by an int32_t of the 6006cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // phase increments 6007cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // Prefer to down-sample from a higher sampling rate, as we get the desired frequency spectrum. 6008cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (minAbove >= 0) { 6009cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten candidate = mSamplingRates[minAbove]; 6010cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (candidate / kMaxDownSampleRatio <= samplingRate) { 6011cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (updatedSamplingRate != NULL) { 6012cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten *updatedSamplingRate = candidate; 6013cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6014cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return NO_ERROR; 6015cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6016cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6017cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // But if we have to up-sample from a lower sampling rate, that's OK. 6018cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (maxBelow >= 0) { 6019cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten candidate = mSamplingRates[maxBelow]; 6020cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (candidate * kMaxUpSampleRatio >= samplingRate) { 6021cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (updatedSamplingRate != NULL) { 6022cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten *updatedSamplingRate = candidate; 6023cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6024cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return NO_ERROR; 6025cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6026cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6027cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // leave updatedSamplingRate unmodified 6028cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return BAD_VALUE; 6029cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten} 6030cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 6031cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kastenstatus_t AudioPolicyManager::AudioPort::checkExactChannelMask(audio_channel_mask_t channelMask) const 6032a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 6033cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten for (size_t i = 0; i < mChannelMasks.size(); i++) { 6034a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mChannelMasks[i] == channelMask) { 6035a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 6036a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6037a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6038a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 6039a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 6040a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 6041cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kastenstatus_t AudioPolicyManager::AudioPort::checkCompatibleChannelMask(audio_channel_mask_t channelMask) 6042cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten const 6043cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten{ 6044cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK; 6045cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten for (size_t i = 0; i < mChannelMasks.size(); i ++) { 6046cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // FIXME Does not handle multi-channel automatic conversions yet 6047cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten audio_channel_mask_t supported = mChannelMasks[i]; 6048cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (supported == channelMask) { 6049cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return NO_ERROR; 6050cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6051cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isRecordThread) { 6052cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // This uses hard-coded knowledge that AudioFlinger can silently down-mix and up-mix. 6053cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // FIXME Abstract this out to a table. 6054cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (((supported == AUDIO_CHANNEL_IN_FRONT_BACK || supported == AUDIO_CHANNEL_IN_STEREO) 6055cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten && channelMask == AUDIO_CHANNEL_IN_MONO) || 6056cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten (supported == AUDIO_CHANNEL_IN_MONO && (channelMask == AUDIO_CHANNEL_IN_FRONT_BACK 6057cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten || channelMask == AUDIO_CHANNEL_IN_STEREO))) { 6058cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return NO_ERROR; 6059cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6060cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6061cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6062cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return BAD_VALUE; 6063cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten} 6064cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 6065a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioPort::checkFormat(audio_format_t format) const 6066a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 6067a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < mFormats.size(); i ++) { 6068a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mFormats[i] == format) { 6069a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 6070a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6071a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6072a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 6073a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 6074a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 60751e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 60761e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentuint32_t AudioPolicyManager::AudioPort::pickSamplingRate() const 60771e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 60781e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // special case for uninitialized dynamic profile 60791e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mSamplingRates.size() == 1 && mSamplingRates[0] == 0) { 60801e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return 0; 60811e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 60821e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 6083828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // For direct outputs, pick minimum sampling rate: this helps ensuring that the 6084828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // channel count / sampling rate combination chosen will be supported by the connected 6085828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // sink 6086828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && 6087828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) { 6088828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent uint32_t samplingRate = UINT_MAX; 6089828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent for (size_t i = 0; i < mSamplingRates.size(); i ++) { 6090828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if ((mSamplingRates[i] < samplingRate) && (mSamplingRates[i] > 0)) { 6091828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent samplingRate = mSamplingRates[i]; 6092828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6093828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6094828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent return (samplingRate == UINT_MAX) ? 0 : samplingRate; 6095828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6096828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent 60971e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t samplingRate = 0; 60981e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t maxRate = MAX_MIXER_SAMPLING_RATE; 60991e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 61001e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // For mixed output and inputs, use max mixer sampling rates. Do not 61011e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // limit sampling rate otherwise 6102828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if (mType != AUDIO_PORT_TYPE_MIX) { 61031e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent maxRate = UINT_MAX; 61041e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61051e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i ++) { 61061e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((mSamplingRates[i] > samplingRate) && (mSamplingRates[i] <= maxRate)) { 61071e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent samplingRate = mSamplingRates[i]; 61081e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61091e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61101e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return samplingRate; 61111e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 61121e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 61131e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentaudio_channel_mask_t AudioPolicyManager::AudioPort::pickChannelMask() const 61141e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 61151e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // special case for uninitialized dynamic profile 61161e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mChannelMasks.size() == 1 && mChannelMasks[0] == 0) { 61171e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return AUDIO_CHANNEL_NONE; 61181e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61191e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent audio_channel_mask_t channelMask = AUDIO_CHANNEL_NONE; 6120828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent 6121828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // For direct outputs, pick minimum channel count: this helps ensuring that the 6122828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // channel count / sampling rate combination chosen will be supported by the connected 6123828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // sink 6124828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && 6125828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) { 6126828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent uint32_t channelCount = UINT_MAX; 6127828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent for (size_t i = 0; i < mChannelMasks.size(); i ++) { 6128828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent uint32_t cnlCount; 6129828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if (mUseInChannelMask) { 6130828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]); 6131828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } else { 6132828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]); 6133828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6134828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if ((cnlCount < channelCount) && (cnlCount > 0)) { 6135828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent channelMask = mChannelMasks[i]; 6136828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent channelCount = cnlCount; 6137828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6138828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6139828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent return channelMask; 6140828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6141828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent 61421e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t channelCount = 0; 61431e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t maxCount = MAX_MIXER_CHANNEL_COUNT; 61441e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 61451e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // For mixed output and inputs, use max mixer channel count. Do not 61461e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // limit channel count otherwise 6147828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if (mType != AUDIO_PORT_TYPE_MIX) { 61481e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent maxCount = UINT_MAX; 61491e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61501e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; i < mChannelMasks.size(); i ++) { 61511e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t cnlCount; 61521e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mUseInChannelMask) { 61531e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]); 61541e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 61551e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]); 61561e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61571e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((cnlCount > channelCount) && (cnlCount <= maxCount)) { 61581e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent channelMask = mChannelMasks[i]; 6159828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent channelCount = cnlCount; 61601e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61611e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61621e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return channelMask; 61631e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 61641e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 61659a60538b9ee2b097770dcd378281b31f4218ae56Andy Hung/* format in order of increasing preference */ 61661e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentconst audio_format_t AudioPolicyManager::AudioPort::sPcmFormatCompareTable[] = { 61671e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent AUDIO_FORMAT_DEFAULT, 61681e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent AUDIO_FORMAT_PCM_16_BIT, 6169a204994e7dd7dab931297176c66b5d3b82e2c90bEric Laurent AUDIO_FORMAT_PCM_8_24_BIT, 61701e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent AUDIO_FORMAT_PCM_24_BIT_PACKED, 6171a204994e7dd7dab931297176c66b5d3b82e2c90bEric Laurent AUDIO_FORMAT_PCM_32_BIT, 61729a60538b9ee2b097770dcd378281b31f4218ae56Andy Hung AUDIO_FORMAT_PCM_FLOAT, 61731e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent}; 61741e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 61751e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentint AudioPolicyManager::AudioPort::compareFormats(audio_format_t format1, 61761e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent audio_format_t format2) 61771e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 61781e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // NOTE: AUDIO_FORMAT_INVALID is also considered not PCM and will be compared equal to any 61791e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // compressed format and better than any PCM format. This is by design of pickFormat() 61801e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (!audio_is_linear_pcm(format1)) { 61811e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (!audio_is_linear_pcm(format2)) { 61821e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return 0; 61831e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61841e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return 1; 61851e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61861e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (!audio_is_linear_pcm(format2)) { 61871e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return -1; 61881e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61891e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 61901e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent int index1 = -1, index2 = -1; 61911e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; 61921e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent (i < ARRAY_SIZE(sPcmFormatCompareTable)) && ((index1 == -1) || (index2 == -1)); 61931e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent i ++) { 61941e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (sPcmFormatCompareTable[i] == format1) { 61951e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent index1 = i; 61961e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 61971e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (sPcmFormatCompareTable[i] == format2) { 61981e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent index2 = i; 61991e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 62001e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 62011e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // format1 not found => index1 < 0 => format2 > format1 62021e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // format2 not found => index2 < 0 => format2 < format1 62031e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return index1 - index2; 62041e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 62051e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 62061e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentaudio_format_t AudioPolicyManager::AudioPort::pickFormat() const 62071e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 62081e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // special case for uninitialized dynamic profile 62091e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mFormats.size() == 1 && mFormats[0] == 0) { 62101e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return AUDIO_FORMAT_DEFAULT; 62111e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 62121e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 62131e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent audio_format_t format = AUDIO_FORMAT_DEFAULT; 62149a60538b9ee2b097770dcd378281b31f4218ae56Andy Hung audio_format_t bestFormat = 62159a60538b9ee2b097770dcd378281b31f4218ae56Andy Hung AudioPolicyManager::AudioPort::sPcmFormatCompareTable[ 62169a60538b9ee2b097770dcd378281b31f4218ae56Andy Hung ARRAY_SIZE(AudioPolicyManager::AudioPort::sPcmFormatCompareTable) - 1]; 62171e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // For mixed output and inputs, use best mixer output format. Do not 62181e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // limit format otherwise 62191e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((mType != AUDIO_PORT_TYPE_MIX) || 62201e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ((mRole == AUDIO_PORT_ROLE_SOURCE) && 6221d8622371d5ac5b98abcc5d388bd952bb3dd4fda9Eric Laurent (((mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) != 0)))) { 62221e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent bestFormat = AUDIO_FORMAT_INVALID; 62231e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 62241e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 62251e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; i < mFormats.size(); i ++) { 62261e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((compareFormats(mFormats[i], format) > 0) && 62271e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent (compareFormats(mFormats[i], bestFormat) <= 0)) { 62281e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent format = mFormats[i]; 62291e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 62301e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 62311e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return format; 62321e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 62331e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 6234a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioPort::checkGain(const struct audio_gain_config *gainConfig, 6235a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent int index) const 6236a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 6237a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (index < 0 || (size_t)index >= mGains.size()) { 6238a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 6239a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6240a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return mGains[index]->checkConfig(gainConfig); 6241a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 6242a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 62431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::AudioPort::dump(int fd, int spaces) const 62441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 62451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const size_t SIZE = 256; 62461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent char buffer[SIZE]; 62471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent String8 result; 62481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 62491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mName.size() != 0) { 62501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string()); 62511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 62521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 62531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 62541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mSamplingRates.size() != 0) { 62551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- sampling rates: ", spaces, ""); 62561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 62571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 62581e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (i == 0 && mSamplingRates[i] == 0) { 62591e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "Dynamic"); 62601e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 62611e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "%d", mSamplingRates[i]); 62621e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 62631afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 62641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(i == (mSamplingRates.size() - 1) ? "" : ", "); 62651afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 62661afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append("\n"); 62671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 62681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 62691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mChannelMasks.size() != 0) { 62701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- channel masks: ", spaces, ""); 62711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 62721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 62731e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ALOGV("AudioPort::dump mChannelMasks %zu %08x", i, mChannelMasks[i]); 62741e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 62751e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (i == 0 && mChannelMasks[i] == 0) { 62761e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "Dynamic"); 62771e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 62781e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]); 62791e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 62801afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 62811afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(i == (mChannelMasks.size() - 1) ? "" : ", "); 62821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 62831afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append("\n"); 62841afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 62851afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 62861afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mFormats.size() != 0) { 62871afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- formats: ", spaces, ""); 62881afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 62891afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 62901e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent const char *formatStr = enumToString(sFormatNameToEnumTable, 62911e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 62921e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mFormats[i]); 62931e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (i == 0 && strcmp(formatStr, "") == 0) { 62941e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "Dynamic"); 62951e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 6296cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent snprintf(buffer, SIZE, "%s", formatStr); 62971e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 62981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 62991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(i == (mFormats.size() - 1) ? "" : ", "); 63001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append("\n"); 63021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63031afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, result.string(), result.size()); 63041afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mGains.size() != 0) { 63051afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- gains:\n", spaces, ""); 63061afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, buffer, strlen(buffer) + 1); 63071afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 63081afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mGains.size(); i++) { 63091afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mGains[i]->dump(fd, spaces + 2, i); 63101afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63111afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63121afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 63131afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent// --- AudioGain class implementation 63151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 6316a121f90f388343dc48793cbc7eb899aba42e7664Eric LaurentAudioPolicyManager::AudioGain::AudioGain(int index, bool useInChannelMask) 63171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 6318a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mIndex = index; 6319a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mUseInChannelMask = useInChannelMask; 63201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent memset(&mGain, 0, sizeof(struct audio_gain)); 63211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 63221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 6323a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentvoid AudioPolicyManager::AudioGain::getDefaultConfig(struct audio_gain_config *config) 6324a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 6325a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->index = mIndex; 6326a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->mode = mGain.mode; 6327a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->channel_mask = mGain.channel_mask; 6328a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((mGain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { 6329a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->values[0] = mGain.default_value; 6330a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 6331a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent uint32_t numValues; 6332a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mUseInChannelMask) { 6333a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_in_mask(mGain.channel_mask); 6334a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 6335a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_out_mask(mGain.channel_mask); 6336a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6337a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < numValues; i++) { 6338a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->values[i] = mGain.default_value; 6339a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6340a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6341a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((mGain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { 6342a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->ramp_duration_ms = mGain.min_ramp_ms; 6343a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6344a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 6345a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 6346a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioGain::checkConfig(const struct audio_gain_config *config) 6347a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 6348a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->mode & ~mGain.mode) != 0) { 6349a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 6350a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6351a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { 6352a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->values[0] < mGain.min_value) || 6353a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent (config->values[0] > mGain.max_value)) { 6354a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 6355a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6356a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 6357a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->channel_mask & ~mGain.channel_mask) != 0) { 6358a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 6359a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6360a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent uint32_t numValues; 6361a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mUseInChannelMask) { 6362a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_in_mask(config->channel_mask); 6363a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 6364a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_out_mask(config->channel_mask); 6365a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6366a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < numValues; i++) { 6367a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->values[i] < mGain.min_value) || 6368a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent (config->values[i] > mGain.max_value)) { 6369a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 6370a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6371a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6372a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6373a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { 6374a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->ramp_duration_ms < mGain.min_ramp_ms) || 6375a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent (config->ramp_duration_ms > mGain.max_ramp_ms)) { 6376a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 6377a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6378a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6379a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 6380a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 6381a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 63821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::AudioGain::dump(int fd, int spaces, int index) const 63831afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 63841afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const size_t SIZE = 256; 63851afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent char buffer[SIZE]; 63861afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent String8 result; 63871afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63881afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*sGain %d:\n", spaces, "", index+1); 63891afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 63901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- mode: %08x\n", spaces, "", mGain.mode); 63911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 63921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask); 63931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 63941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- min_value: %d mB\n", spaces, "", mGain.min_value); 63951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 63961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- max_value: %d mB\n", spaces, "", mGain.max_value); 63971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 63981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- default_value: %d mB\n", spaces, "", mGain.default_value); 63991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 64001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- step_value: %d mB\n", spaces, "", mGain.step_value); 64011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 64021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms); 64031afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 64041afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms); 64051afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 64061afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 64071afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, result.string(), result.size()); 64081afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 64091afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 64101f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent// --- AudioPortConfig class implementation 64111f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 64121f2f2230900581e5de9cf01a883e5d9338f0df94Eric LaurentAudioPolicyManager::AudioPortConfig::AudioPortConfig() 64131f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent{ 64141f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mSamplingRate = 0; 64151f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mChannelMask = AUDIO_CHANNEL_NONE; 64161f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mFormat = AUDIO_FORMAT_INVALID; 64171f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mGain.index = -1; 64181f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent} 64191f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 6420a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioPortConfig::applyAudioPortConfig( 6421a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent const struct audio_port_config *config, 6422a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config *backupConfig) 6423a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 6424a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config localBackupConfig; 6425a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status_t status = NO_ERROR; 6426a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 6427a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent localBackupConfig.config_mask = config->config_mask; 6428a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent toAudioPortConfig(&localBackupConfig); 6429a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 6430961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen sp<AudioPort> audioport = getAudioPort(); 6431961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen if (audioport == 0) { 6432a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status = NO_INIT; 6433a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 6434a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6435a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { 6436961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen status = audioport->checkExactSamplingRate(config->sample_rate); 6437a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 6438a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 6439a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6440a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mSamplingRate = config->sample_rate; 6441a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6442a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { 6443961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen status = audioport->checkExactChannelMask(config->channel_mask); 6444a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 6445a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 6446a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6447a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mChannelMask = config->channel_mask; 6448a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6449a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) { 6450961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen status = audioport->checkFormat(config->format); 6451a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 6452a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 6453a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6454a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mFormat = config->format; 6455a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6456a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) { 6457961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen status = audioport->checkGain(&config->gain, config->gain.index); 6458a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 6459a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 6460a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6461a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mGain = config->gain; 6462a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6463a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 6464a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentexit: 6465a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 6466a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent applyAudioPortConfig(&localBackupConfig); 6467a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6468a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (backupConfig != NULL) { 6469a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent *backupConfig = localBackupConfig; 6470a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6471a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return status; 6472a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 6473a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 64741f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::AudioPortConfig::toAudioPortConfig( 64751f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent struct audio_port_config *dstConfig, 64761f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const struct audio_port_config *srcConfig) const 64771f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent{ 64781f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { 64791f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->sample_rate = mSamplingRate; 64801f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)) { 64811f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->sample_rate = srcConfig->sample_rate; 64821f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 64831f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 64841f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->sample_rate = 0; 64851f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 64861f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { 64871f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->channel_mask = mChannelMask; 64881f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)) { 64891f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->channel_mask = srcConfig->channel_mask; 64901f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 64911f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 64921f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->channel_mask = AUDIO_CHANNEL_NONE; 64931f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 64941f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) { 64951f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->format = mFormat; 64961f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)) { 64971f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->format = srcConfig->format; 64981f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 64991f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 65001f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->format = AUDIO_FORMAT_INVALID; 65011f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 65021f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) { 65031f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->gain = mGain; 65041f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)) { 65051f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->gain = srcConfig->gain; 65061f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 65071f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 65081f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->gain.index = -1; 65091f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 65101f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->gain.index != -1) { 65111f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN; 65121f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 65131f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN; 65141f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 65151f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent} 65161f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 65171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- IOProfile class implementation 65181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 65191afeecb88bea660b2c10b2096be0fd02433303ceEric LaurentAudioPolicyManager::IOProfile::IOProfile(const String8& name, audio_port_role_t role, 65201f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<HwModule>& module) 65211e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent : AudioPort(name, AUDIO_PORT_TYPE_MIX, role, module) 6522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6525e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile::~IOProfile() 6526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// checks if the IO profile is compatible with specified parameters. 6530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Sampling rate, format and channel mask must be specified in order to 6531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// get a valid a match 6532e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device, 6533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 6534cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten uint32_t *updatedSamplingRate, 6535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 6536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 6537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_output_flags_t flags) const 6538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6539cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten const bool isPlaybackThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SOURCE; 6540cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK; 6541cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten ALOG_ASSERT(isPlaybackThread != isRecordThread); 6542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6543cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if ((mSupportedDevices.types() & device) != device) { 6544cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 6545cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6546cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 6547cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (samplingRate == 0) { 6548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 6549cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6550cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten uint32_t myUpdatedSamplingRate = samplingRate; 6551cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isPlaybackThread && checkExactSamplingRate(samplingRate) != NO_ERROR) { 6552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 6553cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6554cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isRecordThread && checkCompatibleSamplingRate(samplingRate, &myUpdatedSamplingRate) != 6555cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten NO_ERROR) { 6556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 6557cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6558cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 6559cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (!audio_is_valid_format(format) || checkFormat(format) != NO_ERROR) { 6560cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 6561cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6562cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 6563cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isPlaybackThread && (!audio_is_output_channel(channelMask) || 6564cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten checkExactChannelMask(channelMask) != NO_ERROR)) { 6565cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 6566cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6567cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isRecordThread && (!audio_is_input_channel(channelMask) || 6568cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten checkCompatibleChannelMask(channelMask) != NO_ERROR)) { 6569cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 6570cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6571cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 6572cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isPlaybackThread && (mFlags & flags) != flags) { 6573cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 6574cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6575cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // The only input flag that is allowed to be different is the fast flag. 6576cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // An existing fast stream is compatible with a normal track request. 6577cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // An existing normal stream is compatible with a fast track request, 6578cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // but the fast request will be denied by AudioFlinger and converted to normal track. 6579cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isRecordThread && (((audio_input_flags_t) mFlags ^ (audio_input_flags_t) flags) & 6580cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten ~AUDIO_INPUT_FLAG_FAST)) { 6581cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 6582cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6583cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 6584cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (updatedSamplingRate != NULL) { 6585cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten *updatedSamplingRate = myUpdatedSamplingRate; 6586cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6587cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return true; 6588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6590e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::IOProfile::dump(int fd) 6591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 6593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 6594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 6595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 65961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent AudioPort::dump(fd, 4); 6597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 65981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, " - flags: 0x%04x\n", mFlags); 6599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 66003a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, " - devices:\n"); 6601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 66023a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, result.string(), result.size()); 66033a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mSupportedDevices.size(); i++) { 66041afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mSupportedDevices[i]->dump(fd, 6, i); 66053a4311c68348f728558e87b5db67d47605783890Eric Laurent } 6606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6608d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::IOProfile::log() 6609d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 6610d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent const size_t SIZE = 256; 6611d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char buffer[SIZE]; 6612d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 result; 6613d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 6614d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - sampling rates: "); 6615d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 6616d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" %d", mSamplingRates[i]); 6617d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 6618d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 6619d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - channel masks: "); 6620d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 6621d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" 0x%04x", mChannelMasks[i]); 6622d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 6623d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 6624d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - formats: "); 6625d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 6626d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" 0x%08x", mFormats[i]); 6627d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 6628d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 6629d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - devices: 0x%04x\n", mSupportedDevices.types()); 6630d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - flags: 0x%04x\n", mFlags); 6631d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 6632d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 6633d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 66343a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- DeviceDescriptor implementation 6635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 66361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 66371f2f2230900581e5de9cf01a883e5d9338f0df94Eric LaurentAudioPolicyManager::DeviceDescriptor::DeviceDescriptor(const String8& name, audio_devices_t type) : 66381f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPort(name, AUDIO_PORT_TYPE_DEVICE, 66391f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK : 66401f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_PORT_ROLE_SOURCE, 66411f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent NULL), 66421e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mDeviceType(type), mAddress(""), mId(0) 66431f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent{ 6644a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mGains.size() > 0) { 6645a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mGains[0]->getDefaultConfig(&mGain); 6646a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 66471f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent} 66481f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 66493a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const 66503a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 66513a4311c68348f728558e87b5db67d47605783890Eric Laurent // Devices are considered equal if they: 66523a4311c68348f728558e87b5db67d47605783890Eric Laurent // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE) 66533a4311c68348f728558e87b5db67d47605783890Eric Laurent // - have the same address or one device does not specify the address 66543a4311c68348f728558e87b5db67d47605783890Eric Laurent // - have the same channel mask or one device does not specify the channel mask 66551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return (mDeviceType == other->mDeviceType) && 66563a4311c68348f728558e87b5db67d47605783890Eric Laurent (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) && 66572f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent (mChannelMask == 0 || other->mChannelMask == 0 || 66583a4311c68348f728558e87b5db67d47605783890Eric Laurent mChannelMask == other->mChannelMask); 66593a4311c68348f728558e87b5db67d47605783890Eric Laurent} 6660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 66613a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::refreshTypes() 66623a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 66631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDeviceTypes = AUDIO_DEVICE_NONE; 66643a4311c68348f728558e87b5db67d47605783890Eric Laurent for(size_t i = 0; i < size(); i++) { 66651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDeviceTypes |= itemAt(i)->mDeviceType; 66663a4311c68348f728558e87b5db67d47605783890Eric Laurent } 66671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes); 66683a4311c68348f728558e87b5db67d47605783890Eric Laurent} 6669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 66703a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const 66713a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 66723a4311c68348f728558e87b5db67d47605783890Eric Laurent for(size_t i = 0; i < size(); i++) { 66733a4311c68348f728558e87b5db67d47605783890Eric Laurent if (item->equals(itemAt(i))) { 66743a4311c68348f728558e87b5db67d47605783890Eric Laurent return i; 66753a4311c68348f728558e87b5db67d47605783890Eric Laurent } 66763a4311c68348f728558e87b5db67d47605783890Eric Laurent } 66773a4311c68348f728558e87b5db67d47605783890Eric Laurent return -1; 66783a4311c68348f728558e87b5db67d47605783890Eric Laurent} 6679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 66803a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::add(const sp<DeviceDescriptor>& item) 66813a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 66823a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t ret = indexOf(item); 6683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 66843a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret < 0) { 66853a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = SortedVector::add(item); 66863a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret >= 0) { 66873a4311c68348f728558e87b5db67d47605783890Eric Laurent refreshTypes(); 66883a4311c68348f728558e87b5db67d47605783890Eric Laurent } 66893a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 66901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("DeviceVector::add device %08x already in", item->mDeviceType); 66913a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = -1; 66923a4311c68348f728558e87b5db67d47605783890Eric Laurent } 66933a4311c68348f728558e87b5db67d47605783890Eric Laurent return ret; 66943a4311c68348f728558e87b5db67d47605783890Eric Laurent} 6695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 66963a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::remove(const sp<DeviceDescriptor>& item) 66973a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 66983a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t i; 66993a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t ret = indexOf(item); 6700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 67013a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret < 0) { 67021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("DeviceVector::remove device %08x not in", item->mDeviceType); 67033a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 67043a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = SortedVector::removeAt(ret); 67053a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret >= 0) { 67063a4311c68348f728558e87b5db67d47605783890Eric Laurent refreshTypes(); 67073a4311c68348f728558e87b5db67d47605783890Eric Laurent } 67083a4311c68348f728558e87b5db67d47605783890Eric Laurent } 67093a4311c68348f728558e87b5db67d47605783890Eric Laurent return ret; 67103a4311c68348f728558e87b5db67d47605783890Eric Laurent} 6711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 67123a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::loadDevicesFromType(audio_devices_t types) 6713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 67143a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceVector deviceList; 67153a4311c68348f728558e87b5db67d47605783890Eric Laurent 67163a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t role_bit = AUDIO_DEVICE_BIT_IN & types; 67173a4311c68348f728558e87b5db67d47605783890Eric Laurent types &= ~role_bit; 67183a4311c68348f728558e87b5db67d47605783890Eric Laurent 67193a4311c68348f728558e87b5db67d47605783890Eric Laurent while (types) { 67203a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t i = 31 - __builtin_clz(types); 67213a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t type = 1 << i; 67223a4311c68348f728558e87b5db67d47605783890Eric Laurent types &= ~type; 67231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent add(new DeviceDescriptor(String8(""), type | role_bit)); 6724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 67271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::DeviceVector::loadDevicesFromName(char *name, 67281afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const DeviceVector& declaredDevices) 67291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 67301afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent char *devName = strtok(name, "|"); 67311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (devName != NULL) { 67321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strlen(devName) != 0) { 67331afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent audio_devices_t type = stringToEnum(sDeviceNameToEnumTable, 67341afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 67351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent devName); 67361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (type != AUDIO_DEVICE_NONE) { 67371afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent add(new DeviceDescriptor(String8(""), type)); 67381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 67391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> deviceDesc = 67401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices.getDeviceFromName(String8(devName)); 67411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (deviceDesc != 0) { 67421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent add(deviceDesc); 67431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 67441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 67451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 67461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent devName = strtok(NULL, "|"); 67471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 67481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 67491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 67501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDevice( 67511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type, String8 address) const 67521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 67531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<DeviceDescriptor> device; 67541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; i < size(); i++) { 67551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (itemAt(i)->mDeviceType == type) { 67561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = itemAt(i); 67571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (itemAt(i)->mAddress = address) { 67581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent break; 67591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 67601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 67611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 67621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("DeviceVector::getDevice() for type %d address %s found %p", 67631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent type, address.string(), device.get()); 67641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return device; 67651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 67661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 67676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromId( 67686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_handle_t id) const 67696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 67706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<DeviceDescriptor> device; 67716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < size(); i++) { 6772beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("DeviceVector::getDeviceFromId(%d) itemAt(%zu)->mId %d", id, i, itemAt(i)->mId); 67736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (itemAt(i)->mId == id) { 67746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent device = itemAt(i); 67756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 67766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 67776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 67786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return device; 67796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 67806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 67811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromType( 67821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type) const 67831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 67841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent DeviceVector devices; 67851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) { 67861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (itemAt(i)->mDeviceType & type & ~AUDIO_DEVICE_BIT_IN) { 67871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent devices.add(itemAt(i)); 67881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent type &= ~itemAt(i)->mDeviceType; 67891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("DeviceVector::getDevicesFromType() for type %x found %p", 67901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent itemAt(i)->mDeviceType, itemAt(i).get()); 67911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 67921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 67931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return devices; 67941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 67951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 67960fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel TriviAudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromTypeAddr( 67970fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi audio_devices_t type, String8 address) const 67980fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi{ 67990fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi DeviceVector devices; 68000fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi //ALOGV(" looking for device=%x, addr=%s", type, address.string()); 68010fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi for (size_t i = 0; i < size(); i++) { 68020fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi //ALOGV(" at i=%d: device=%x, addr=%s", 68030fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi // i, itemAt(i)->mDeviceType, itemAt(i)->mAddress.string()); 68040fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (itemAt(i)->mDeviceType == type) { 68050fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (itemAt(i)->mAddress == address) { 68060fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi //ALOGV(" found matching address %s", address.string()); 68070fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi devices.add(itemAt(i)); 68080fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 68090fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 68100fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 68110fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi return devices; 68120fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi} 68130fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi 68141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromName( 68151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const String8& name) const 68161afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 68171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> device; 68181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < size(); i++) { 68191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (itemAt(i)->mName == name) { 68201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent device = itemAt(i); 68211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent break; 68221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 68231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 68241afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return device; 68251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 68261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 68276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentvoid AudioPolicyManager::DeviceDescriptor::toAudioPortConfig( 68286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port_config *dstConfig, 68296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const struct audio_port_config *srcConfig) const 68301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 68311f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK|AUDIO_PORT_CONFIG_GAIN; 68321f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (srcConfig != NULL) { 683384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent dstConfig->config_mask |= srcConfig->config_mask; 68341f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 68351f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 68361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 68371f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 68386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->id = mId; 68396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->role = audio_is_output_device(mDeviceType) ? 68401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE; 68416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->type = AUDIO_PORT_TYPE_DEVICE; 68426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.device.type = mDeviceType; 68436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.device.hw_module = mModule->mHandle; 68446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN); 68451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 68461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 68471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::DeviceDescriptor::toAudioPort(struct audio_port *port) const 68481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 684983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ALOGV("DeviceDescriptor::toAudioPort() handle %d type %x", mId, mDeviceType); 68501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AudioPort::toAudioPort(port); 68511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 68526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent toAudioPortConfig(&port->active_config); 68531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.device.type = mDeviceType; 68546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent port->ext.device.hw_module = mModule->mHandle; 68551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN); 68561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 68571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 68581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::DeviceDescriptor::dump(int fd, int spaces, int index) const 68593a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 68603a4311c68348f728558e87b5db67d47605783890Eric Laurent const size_t SIZE = 256; 68613a4311c68348f728558e87b5db67d47605783890Eric Laurent char buffer[SIZE]; 68621afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent String8 result; 68633a4311c68348f728558e87b5db67d47605783890Eric Laurent 68641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1); 68651afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 68661afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mId != 0) { 68671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId); 68681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 68691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 68701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "", 68711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent enumToString(sDeviceNameToEnumTable, 68721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 68731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeviceType)); 68741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 68751afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mAddress.size() != 0) { 68761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string()); 68771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 68781afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 68791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, result.string(), result.size()); 68801afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent AudioPort::dump(fd, spaces); 68813a4311c68348f728558e87b5db67d47605783890Eric Laurent 68823a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_ERROR; 68833a4311c68348f728558e87b5db67d47605783890Eric Laurent} 68843a4311c68348f728558e87b5db67d47605783890Eric Laurent 68854d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurentstatus_t AudioPolicyManager::AudioPatch::dump(int fd, int spaces, int index) const 68864d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent{ 68874d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent const size_t SIZE = 256; 68884d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent char buffer[SIZE]; 68894d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent String8 result; 68904d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent 68914d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent 68924d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*sAudio patch %d:\n", spaces, "", index+1); 68934d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 68944d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- handle: %2d\n", spaces, "", mHandle); 68954d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 68964d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- audio flinger handle: %2d\n", spaces, "", mAfPatchHandle); 68974d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 68984d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid); 68994d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 69004d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- %d sources:\n", spaces, "", mPatch.num_sources); 69014d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 69024d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent for (size_t i = 0; i < mPatch.num_sources; i++) { 69034d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent if (mPatch.sources[i].type == AUDIO_PORT_TYPE_DEVICE) { 69044d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "", 69054d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sources[i].id, enumToString(sDeviceNameToEnumTable, 69064d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 69074d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sources[i].ext.device.type)); 69084d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } else { 69094d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "", 69104d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sources[i].id, mPatch.sources[i].ext.mix.handle); 69114d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } 69124d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 69134d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } 69144d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- %d sinks:\n", spaces, "", mPatch.num_sinks); 69154d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 69164d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent for (size_t i = 0; i < mPatch.num_sinks; i++) { 69174d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent if (mPatch.sinks[i].type == AUDIO_PORT_TYPE_DEVICE) { 69184d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "", 69194d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sinks[i].id, enumToString(sDeviceNameToEnumTable, 69204d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 69214d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sinks[i].ext.device.type)); 69224d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } else { 69234d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "", 69244d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sinks[i].id, mPatch.sinks[i].ext.mix.handle); 69254d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } 69264d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 69274d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } 69284d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent 69294d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent write(fd, result.string(), result.size()); 69304d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent return NO_ERROR; 69314d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent} 69323a4311c68348f728558e87b5db67d47605783890Eric Laurent 69333a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- audio_policy.conf file parsing 69343a4311c68348f728558e87b5db67d47605783890Eric Laurent 6935e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_output_flags_t AudioPolicyManager::parseFlagNames(char *name) 6936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t flag = 0; 6938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // it is OK to cast name to non const here as we are not going to use it after 6940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // strtok() modifies it 6941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *flagName = strtok(name, "|"); 6942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (flagName != NULL) { 6943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strlen(flagName) != 0) { 6944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flag |= stringToEnum(sFlagNameToEnumTable, 6945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sFlagNameToEnumTable), 6946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flagName); 6947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flagName = strtok(NULL, "|"); 6949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //force direct flag if offload flag is set: offloading implies a direct output stream 6951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and all common behaviors are driven by checking only the direct flag 6952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this should normally be set appropriately in the policy configuration file 6953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 6954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flag |= AUDIO_OUTPUT_FLAG_DIRECT; 6955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_output_flags_t)flag; 6958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6960e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::parseDeviceNames(char *name) 6961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = 0; 6963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *devName = strtok(name, "|"); 6965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (devName != NULL) { 6966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strlen(devName) != 0) { 6967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device |= stringToEnum(sDeviceNameToEnumTable, 6968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 6969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devName); 69703a4311c68348f728558e87b5db67d47605783890Eric Laurent } 6971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devName = strtok(NULL, "|"); 69723a4311c68348f728558e87b5db67d47605783890Eric Laurent } 6973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 6974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6976e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModule(cnode *root) 6977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t status = NAME_NOT_FOUND; 69791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node; 69801f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module = new HwModule(root->name); 6981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 69821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = config_find(root, DEVICES_TAG); 69831afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (node != NULL) { 69841afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->first_child; 69851afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 69861afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadHwModule() loading device %s", node->name); 69871afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status_t tmpStatus = module->loadDevice(node); 69881afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 69891afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status = tmpStatus; 69901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 69911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 69921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 69931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 69941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = config_find(root, OUTPUTS_TAG); 6995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node != NULL) { 6996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 6997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 6998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModule() loading output %s", node->name); 69991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status_t tmpStatus = module->loadOutput(node); 7000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 7001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = tmpStatus; 7002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 7004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = config_find(root, INPUTS_TAG); 7007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node != NULL) { 7008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 7009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 7010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModule() loading input %s", node->name); 70111afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status_t tmpStatus = module->loadInput(node); 7012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 7013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = tmpStatus; 7014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 7016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 70181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent loadGlobalConfig(root, module); 70191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 7020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NO_ERROR) { 7021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules.add(module); 7022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7025e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModules(cnode *root) 7026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); 7028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node == NULL) { 7029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 7030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 7033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 7034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModules() loading module %s", node->name); 7035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadHwModule(node); 7036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 7037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 70401f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::loadGlobalConfig(cnode *root, const sp<HwModule>& module) 7041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, GLOBAL_CONFIG_TAG); 7043eb108a4622825688b02d7afc981014d149913cd8Eric Laurent 7044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node == NULL) { 7045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 7046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 70471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent DeviceVector declaredDevices; 70481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (module != NULL) { 70491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices = module->mDeclaredDevices; 70501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 70511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 7052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 7053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 7054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { 70551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableOutputDevices.loadDevicesFromName((char *)node->value, 70561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices); 70573a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadGlobalConfig() Attached Output Devices %08x", 70583a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.types()); 7059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { 70603a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t device = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable, 7061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 7062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (char *)node->value); 70633a4311c68348f728558e87b5db67d47605783890Eric Laurent if (device != AUDIO_DEVICE_NONE) { 70641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDefaultOutputDevice = new DeviceDescriptor(String8(""), device); 70653a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 70663a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("loadGlobalConfig() default device not specified"); 70673a4311c68348f728558e87b5db67d47605783890Eric Laurent } 70681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", mDefaultOutputDevice->mDeviceType); 7069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { 70701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableInputDevices.loadDevicesFromName((char *)node->value, 70711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices); 70723a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadGlobalConfig() Available InputDevices %08x", mAvailableInputDevices.types()); 7073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) { 7074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mSpeakerDrcEnabled = stringToBool((char *)node->value); 7075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled); 7076eb108a4622825688b02d7afc981014d149913cd8Eric Laurent } else if (strcmp(AUDIO_HAL_VERSION_TAG, node->name) == 0) { 7077eb108a4622825688b02d7afc981014d149913cd8Eric Laurent uint32_t major, minor; 7078eb108a4622825688b02d7afc981014d149913cd8Eric Laurent sscanf((char *)node->value, "%u.%u", &major, &minor); 7079eb108a4622825688b02d7afc981014d149913cd8Eric Laurent module->mHalVersion = HARDWARE_DEVICE_API_VERSION(major, minor); 7080eb108a4622825688b02d7afc981014d149913cd8Eric Laurent ALOGV("loadGlobalConfig() mHalVersion = %04x major %u minor %u", 7081eb108a4622825688b02d7afc981014d149913cd8Eric Laurent module->mHalVersion, major, minor); 7082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 7084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7087e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadAudioPolicyConfig(const char *path) 7088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *root; 7090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *data; 7091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent data = (char *)load_file(path, NULL); 7093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (data == NULL) { 7094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return -ENODEV; 7095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent root = config_node("", ""); 7097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent config_load(root, data); 7098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadHwModules(root); 71001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent // legacy audio_policy.conf files have one global_configuration section 71011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent loadGlobalConfig(root, getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)); 7102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent config_free(root); 7103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free(root); 7104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free(data); 7105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGI("loadAudioPolicyConfig() loaded %s\n", path); 7107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 7109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7111e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::defaultAudioPolicyConfig(void) 7112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 71131f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module; 71141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile; 71151f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(String8(""), 71161f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_DEVICE_IN_BUILTIN_MIC); 71173a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.add(mDefaultOutputDevice); 71183a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.add(defaultInputDevice); 7119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module = new HwModule("primary"); 7121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 71221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SOURCE, module); 7123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(44100); 7124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 7125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO); 71263a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.add(mDefaultOutputDevice); 7127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY; 7128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mOutputProfiles.add(profile); 7129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 71301afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SINK, module); 7131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(8000); 7132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 7133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO); 71343a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.add(defaultInputDevice); 7135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mInputProfiles.add(profile); 7136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules.add(module); 7138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 71405bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr) 71415bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{ 71425bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // flags to stream type mapping 71435bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { 71445bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_ENFORCED_AUDIBLE; 71455bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 71465bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) { 71475bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_BLUETOOTH_SCO; 71485bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 71495bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 71505bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // usage to stream type mapping 71515bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi switch (attr->usage) { 71525bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_MEDIA: 71535bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_GAME: 71545bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: 71555bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 71565bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_MUSIC; 71575bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_SONIFICATION: 71585bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_SYSTEM; 71595bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION: 71605bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_VOICE_CALL; 71615bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 71625bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: 71635bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_DTMF; 71645bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 71655bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ALARM: 71665bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_ALARM; 71675bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: 71685bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_RING; 71695bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 71705bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION: 71715bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: 71725bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: 71735bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: 71745bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_EVENT: 71755bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_NOTIFICATION; 71765bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 71775bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_UNKNOWN: 71785bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi default: 71795bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_MUSIC; 71805bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 71815bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi} 7182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; // namespace android 7183