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() 29327cb70dcbf3a1f1679aeafaaa62d8532abea86dHochi Huang#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX|AUDIO_DEVICE_IN_FM_TUNER) 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> 46e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent#include <media/AudioPolicyHelper.h> 47df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent#include <soundtrigger/SoundTrigger.h> 48d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include "AudioPolicyManager.h" 491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent#include "audio_policy_conf.h" 50e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 513b73df74357b33869b39a1d69427673c780bd805Eric Laurentnamespace android { 52e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 53e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 543a4311c68348f728558e87b5db67d47605783890Eric Laurent// Definitions for audio_policy.conf file parsing 553a4311c68348f728558e87b5db67d47605783890Eric Laurent// ---------------------------------------------------------------------------- 563a4311c68348f728558e87b5db67d47605783890Eric Laurent 573a4311c68348f728558e87b5db67d47605783890Eric Laurentstruct StringToEnum { 583a4311c68348f728558e87b5db67d47605783890Eric Laurent const char *name; 593a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t value; 603a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 613a4311c68348f728558e87b5db67d47605783890Eric Laurent 623a4311c68348f728558e87b5db67d47605783890Eric Laurent#define STRING_TO_ENUM(string) { #string, string } 633a4311c68348f728558e87b5db67d47605783890Eric Laurent#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 643a4311c68348f728558e87b5db67d47605783890Eric Laurent 653a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sDeviceNameToEnumTable[] = { 663a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE), 673a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER), 6811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER_SAFE), 693a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET), 703a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE), 713a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO), 723a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET), 733a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT), 743a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO), 753a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP), 763a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES), 773a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER), 783a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP), 793a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL), 801b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI), 813a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET), 823a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET), 833a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY), 843a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE), 853a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB), 863a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX), 871b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_TELEPHONY_TX), 881b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_LINE), 891b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC), 901b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPDIF), 911b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM), 92e1d37b784f3970e44a7331c189cbfdca15404648Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_LINE), 93a57ab8da6fe56fdb91dfc95ebd0282eb879dde53Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_AMBIENT), 943a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), 953a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), 963a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO), 973a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET), 983a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL), 991b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_HDMI), 1001b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX), 101c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL), 1023a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC), 1033a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX), 1043a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET), 1053a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET), 1063a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY), 107d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE), 1081b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_FM_TUNER), 1091b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_TV_TUNER), 1101b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_LINE), 1111b776237ec911f4bb09f42f295b41e13f5f49113Eric Laurent STRING_TO_ENUM(AUDIO_DEVICE_IN_SPDIF), 11241b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP), 1137999a2236cb641dc1d7bf7bd8d2499d40d0a806dTerry Heo STRING_TO_ENUM(AUDIO_DEVICE_IN_LOOPBACK), 1143a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1153a4311c68348f728558e87b5db67d47605783890Eric Laurent 1165dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurentconst StringToEnum sOutputFlagNameToEnumTable[] = { 1173a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT), 1183a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), 1193a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), 1203a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), 1213a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD), 1223a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING), 12393c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_HW_AV_SYNC), 1243a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1253a4311c68348f728558e87b5db67d47605783890Eric Laurent 1265dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurentconst StringToEnum sInputFlagNameToEnumTable[] = { 1275dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent STRING_TO_ENUM(AUDIO_INPUT_FLAG_FAST), 1285dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent STRING_TO_ENUM(AUDIO_INPUT_FLAG_HW_HOTWORD), 1295dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent}; 1305dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent 1313a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFormatNameToEnumTable[] = { 1323a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT), 1333a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT), 1343a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT), 1353a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT), 1363a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT), 1373a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED), 1383a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_MP3), 1393a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AAC), 1402829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_MAIN), 1412829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_LC), 1422829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_SSR), 1432829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_LTP), 1442829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V1), 1452829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_SCALABLE), 1462829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_ERLC), 1472829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_LD), 1482829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V2), 1492829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad STRING_TO_ENUM(AUDIO_FORMAT_AAC_ELD), 1503a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_FORMAT_VORBIS), 151ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V1), 152ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V2), 153ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_OPUS), 154ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_AC3), 155ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent STRING_TO_ENUM(AUDIO_FORMAT_E_AC3), 1563a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1573a4311c68348f728558e87b5db67d47605783890Eric Laurent 1583a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sOutChannelsNameToEnumTable[] = { 1593a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO), 1603a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 1613a0fe12fbd08b13e9f57d79b0391186be05072f5Andy Hung STRING_TO_ENUM(AUDIO_CHANNEL_OUT_QUAD), 1623a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 1633a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 1643a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1653a4311c68348f728558e87b5db67d47605783890Eric Laurent 1663a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sInChannelsNameToEnumTable[] = { 1673a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), 1683a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), 1693a4311c68348f728558e87b5db67d47605783890Eric Laurent STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK), 1703a4311c68348f728558e87b5db67d47605783890Eric Laurent}; 1713a4311c68348f728558e87b5db67d47605783890Eric Laurent 1721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentconst StringToEnum sGainModeNameToEnumTable[] = { 1731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent STRING_TO_ENUM(AUDIO_GAIN_MODE_JOINT), 1741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent STRING_TO_ENUM(AUDIO_GAIN_MODE_CHANNELS), 1751afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent STRING_TO_ENUM(AUDIO_GAIN_MODE_RAMP), 1761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent}; 1771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 1783a4311c68348f728558e87b5db67d47605783890Eric Laurent 1793a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::stringToEnum(const struct StringToEnum *table, 1803a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t size, 1813a4311c68348f728558e87b5db67d47605783890Eric Laurent const char *name) 1823a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1833a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < size; i++) { 1843a4311c68348f728558e87b5db67d47605783890Eric Laurent if (strcmp(table[i].name, name) == 0) { 1853a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("stringToEnum() found %s", table[i].name); 1863a4311c68348f728558e87b5db67d47605783890Eric Laurent return table[i].value; 1873a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1883a4311c68348f728558e87b5db67d47605783890Eric Laurent } 1893a4311c68348f728558e87b5db67d47605783890Eric Laurent return 0; 1903a4311c68348f728558e87b5db67d47605783890Eric Laurent} 1913a4311c68348f728558e87b5db67d47605783890Eric Laurent 1923a4311c68348f728558e87b5db67d47605783890Eric Laurentconst char *AudioPolicyManager::enumToString(const struct StringToEnum *table, 1933a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t size, 1943a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t value) 1953a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 1963a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < size; i++) { 1973a4311c68348f728558e87b5db67d47605783890Eric Laurent if (table[i].value == value) { 1983a4311c68348f728558e87b5db67d47605783890Eric Laurent return table[i].name; 1993a4311c68348f728558e87b5db67d47605783890Eric Laurent } 2003a4311c68348f728558e87b5db67d47605783890Eric Laurent } 2013a4311c68348f728558e87b5db67d47605783890Eric Laurent return ""; 2023a4311c68348f728558e87b5db67d47605783890Eric Laurent} 2033a4311c68348f728558e87b5db67d47605783890Eric Laurent 2043a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::stringToBool(const char *value) 2053a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 2063a4311c68348f728558e87b5db67d47605783890Eric Laurent return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0)); 2073a4311c68348f728558e87b5db67d47605783890Eric Laurent} 2083a4311c68348f728558e87b5db67d47605783890Eric Laurent 2093a4311c68348f728558e87b5db67d47605783890Eric Laurent 2103a4311c68348f728558e87b5db67d47605783890Eric Laurent// ---------------------------------------------------------------------------- 211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AudioPolicyInterface implementation 212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 214e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, 2153b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state, 216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *device_address) 217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 218c73ca6ef04136f28306784ad35f444538f081957Eric Laurent return setDeviceConnectionStateInt(device, state, device_address); 219c73ca6ef04136f28306784ad35f444538f081957Eric Laurent} 220c73ca6ef04136f28306784ad35f444538f081957Eric Laurent 221c73ca6ef04136f28306784ad35f444538f081957Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device, 222a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent audio_policy_dev_state_t state, 223a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent const char *device_address) 224c73ca6ef04136f28306784ad35f444538f081957Eric Laurent{ 225222260168c144cca5a4e8f1c79df8c8baa22b591Eric Laurent ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", 226a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent device, state, device_address != NULL ? device_address : ""); 227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // connect/disconnect only 1 device at a time 229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; 230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 231a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent sp<DeviceDescriptor> devDesc = getDeviceDescriptor(device, device_address); 232a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent 233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output devices 234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_output_device(device)) { 235d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector <audio_io_handle_t> outputs; 236d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 2373a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = mAvailableOutputDevices.indexOf(devDesc); 2383a4311c68348f728558e87b5db67d47605783890Eric Laurent 239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // save a copy of the opened output descriptors before any output is opened or closed 240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() 241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (state) 243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output device connection 2453ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: { 2463a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device already connected: %x", device); 248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setDeviceConnectionState() connecting device %x", device); 251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // register new device as available 2533a4311c68348f728558e87b5db67d47605783890Eric Laurent index = mAvailableOutputDevices.add(devDesc); 2543a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 2551f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module = getModuleForDevice(device); 256cf817a2330936947df94c11859f48771f5596a59Eric Laurent if (module == 0) { 257cf817a2330936947df94c11859f48771f5596a59Eric Laurent ALOGD("setDeviceConnectionState() could not find HW module for device %08x", 258cf817a2330936947df94c11859f48771f5596a59Eric Laurent device); 259cf817a2330936947df94c11859f48771f5596a59Eric Laurent mAvailableOutputDevices.remove(devDesc); 260cf817a2330936947df94c11859f48771f5596a59Eric Laurent return INVALID_OPERATION; 261cf817a2330936947df94c11859f48771f5596a59Eric Laurent } 262cf817a2330936947df94c11859f48771f5596a59Eric Laurent mAvailableOutputDevices[index]->mId = nextUniqueId(); 2636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableOutputDevices[index]->mModule = module; 2643a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 2653a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_MEMORY; 266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 268a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) { 2690fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi mAvailableOutputDevices.remove(devDesc); 2700fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi return INVALID_OPERATION; 2710fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 2720fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi // outputs should never be empty here 2730fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():" 2740fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi "checkOutputsForDevice() returned no outputs but status OK"); 2750fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs", 2760fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi outputs.size()); 2773ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent 2783ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent 2793ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent // Set connect to HALs 2803ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent AudioParameter param = AudioParameter(devDesc->mAddress); 2813ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device); 2823ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString()); 2833ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent 2843ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent } break; 285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle output device disconnection 2863b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: { 2873a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index < 0) { 288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device not connected: %x", device); 289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2925c477aa6205e2ebafec237411900d89a510cc105Paul McLean ALOGV("setDeviceConnectionState() disconnecting output device %x", device); 2935c477aa6205e2ebafec237411900d89a510cc105Paul McLean 2945c477aa6205e2ebafec237411900d89a510cc105Paul McLean // Set Disconnect to HALs 295a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent AudioParameter param = AudioParameter(devDesc->mAddress); 2965c477aa6205e2ebafec237411900d89a510cc105Paul McLean param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device); 2975c477aa6205e2ebafec237411900d89a510cc105Paul McLean mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString()); 2985c477aa6205e2ebafec237411900d89a510cc105Paul McLean 299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // remove device from available output devices 3003a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.remove(devDesc); 3013a4311c68348f728558e87b5db67d47605783890Eric Laurent 302a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress); 303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } break; 304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("setDeviceConnectionState() invalid state: %x", state); 307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3103a4311c68348f728558e87b5db67d47605783890Eric Laurent // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP 3113a4311c68348f728558e87b5db67d47605783890Eric Laurent // output is suspended before any tracks are moved to it 312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // outputs must be closed after checkOutputForAllStrategies() is executed 315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputs.isEmpty()) { 316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 3171f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]); 318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // close unused outputs after device disconnection or direct outputs that have been 319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // opened by checkOutputsForDevice() to query dynamic parameters 3203b73df74357b33869b39a1d69427673c780bd805Eric Laurent if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) || 321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) && 322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (desc->mDirectOpenCount == 0))) { 323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent closeOutput(outputs[i]); 324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3263a4311c68348f728558e87b5db67d47605783890Eric Laurent // check again after closing A2DP output to reset mA2dpSuspended if needed 3273a4311c68348f728558e87b5db67d47605783890Eric Laurent checkA2dpSuspend(); 328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 331c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mPhoneState == AUDIO_MODE_IN_CALL) { 332c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/); 333c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent updateCallRouting(newDevice); 334c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 336c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 337c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if ((mPhoneState != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) { 338c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t newDevice = getNewOutputDevice(mOutputs.keyAt(i), 339c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent true /*fromCache*/); 340c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // do not force device change on duplicated output because if device is 0, it will 341c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // also force a device 0 for the two outputs it is duplicated to which may override 342c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // a valid device selection on those outputs. 343c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent bool force = !mOutputs.valueAt(i)->isDuplicated() 344c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent && (!deviceDistinguishesOnAddress(device) 345c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // always force when disconnecting (a non-duplicated device) 346c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE)); 347c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent setOutputDevice(output, newDevice, force, 0); 348c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 35172aa32f7dbbfb658097930b57659d8e50f24a953Eric Laurent mpClientInterface->onAudioPortListUpdate(); 352b71e58b64cd4992355cf6afaf3f3530f723bc72cEric Laurent return NO_ERROR; 353d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end if is output device 354d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input devices 356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_input_device(device)) { 357d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector <audio_io_handle_t> inputs; 358d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3593a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t index = mAvailableInputDevices.indexOf(devDesc); 360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (state) 361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input device connection 3633b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: { 3643a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device already connected: %d", device); 366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3681f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module = getModuleForDevice(device); 3696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (module == NULL) { 3706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("setDeviceConnectionState(): could not find HW module for device %08x", 3716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent device); 3726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 3736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 374a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent if (checkInputsForDevice(device, state, inputs, devDesc->mAddress) != NO_ERROR) { 375d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return INVALID_OPERATION; 376d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 377d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3783a4311c68348f728558e87b5db67d47605783890Eric Laurent index = mAvailableInputDevices.add(devDesc); 3793a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 3803a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices[index]->mId = nextUniqueId(); 3816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices[index]->mModule = module; 3823a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 3833a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_MEMORY; 3843a4311c68348f728558e87b5db67d47605783890Eric Laurent } 3853ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent 3863ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent // Set connect to HALs 3873ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent AudioParameter param = AudioParameter(devDesc->mAddress); 3883ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device); 3893ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString()); 3903ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent 391d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } break; 392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle input device disconnection 3943b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: { 3953a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index < 0) { 396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() device not connected: %d", device); 397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3995c477aa6205e2ebafec237411900d89a510cc105Paul McLean 4005c477aa6205e2ebafec237411900d89a510cc105Paul McLean ALOGV("setDeviceConnectionState() disconnecting input device %x", device); 4015c477aa6205e2ebafec237411900d89a510cc105Paul McLean 4025c477aa6205e2ebafec237411900d89a510cc105Paul McLean // Set Disconnect to HALs 403a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent AudioParameter param = AudioParameter(devDesc->mAddress); 4045c477aa6205e2ebafec237411900d89a510cc105Paul McLean param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device); 4055c477aa6205e2ebafec237411900d89a510cc105Paul McLean mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString()); 4065c477aa6205e2ebafec237411900d89a510cc105Paul McLean 407a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent checkInputsForDevice(device, state, inputs, devDesc->mAddress); 4083a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.remove(devDesc); 4095c477aa6205e2ebafec237411900d89a510cc105Paul McLean 410d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } break; 411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("setDeviceConnectionState() invalid state: %x", state); 414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 417d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent closeAllInputs(); 418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 419c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mPhoneState == AUDIO_MODE_IN_CALL) { 420c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/); 421c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent updateCallRouting(newDevice); 422c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 423c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 424b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 426d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end if is input device 427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setDeviceConnectionState() invalid device: %x", device); 429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 432e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device, 433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const char *device_address) 434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 435a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent sp<DeviceDescriptor> devDesc = getDeviceDescriptor(device, device_address); 4363a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceVector *deviceVector; 4373a4311c68348f728558e87b5db67d47605783890Eric Laurent 438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_output_device(device)) { 4393a4311c68348f728558e87b5db67d47605783890Eric Laurent deviceVector = &mAvailableOutputDevices; 440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (audio_is_input_device(device)) { 4413a4311c68348f728558e87b5db67d47605783890Eric Laurent deviceVector = &mAvailableInputDevices; 4423a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 4433a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("getDeviceConnectionState() invalid device type %08x", device); 4443a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 447a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent ssize_t index = deviceVector->indexOf(devDesc); 4483a4311c68348f728558e87b5db67d47605783890Eric Laurent if (index >= 0) { 4493a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_AVAILABLE; 4503a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 4513a4311c68348f728558e87b5db67d47605783890Eric Laurent return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; 4523a4311c68348f728558e87b5db67d47605783890Eric Laurent } 453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 455a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::getDeviceDescriptor( 456a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent const audio_devices_t device, 457a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent const char *device_address) 458a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent{ 459a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent String8 address = (device_address == NULL) ? String8("") : String8(device_address); 460a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent // handle legacy remote submix case where the address was not always specified 461a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent if (deviceDistinguishesOnAddress(device) && (address.length() == 0)) { 462a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent address = String8("0"); 463a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent } 464a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent 465a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 466a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent if (mHwModules[i]->mHandle == 0) { 467a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent continue; 468a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent } 469a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent DeviceVector deviceList = 470a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent mHwModules[i]->mDeclaredDevices.getDevicesFromTypeAddr(device, address); 471a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent if (!deviceList.isEmpty()) { 472a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent return deviceList.itemAt(0); 473a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent } 474a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent deviceList = mHwModules[i]->mDeclaredDevices.getDevicesFromType(device); 475a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent if (!deviceList.isEmpty()) { 476a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent return deviceList.itemAt(0); 477a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent } 478a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent } 479a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent 480a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); 481a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent devDesc->mAddress = address; 482a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent return devDesc; 483a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent} 484a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent 485c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurentvoid AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs) 486c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent{ 487c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent bool createTxPatch = false; 488c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent struct audio_patch patch; 489c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sources = 1; 490c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sinks = 1; 491c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent status_t status; 492c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_patch_handle_t afPatchHandle; 493c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent DeviceVector deviceList; 494c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 495c73ca6ef04136f28306784ad35f444538f081957Eric Laurent audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION); 496c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice); 497c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 498c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // release existing RX patch if any 499c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mCallRxPatch != 0) { 500c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0); 501c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallRxPatch.clear(); 502c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 503c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // release TX patch if any 504c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mCallTxPatch != 0) { 505c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0); 506c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallTxPatch.clear(); 507c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 508c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 509c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // If the RX device is on the primary HW module, then use legacy routing method for voice calls 510c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // via setOutputDevice() on primary output. 511c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // Otherwise, create two audio patches for TX and RX path. 512c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (availablePrimaryOutputDevices() & rxDevice) { 513c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent setOutputDevice(mPrimaryOutput, rxDevice, true, delayMs); 514c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // If the TX device is also on the primary HW module, setOutputDevice() will take care 515c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // of it due to legacy implementation. If not, create a patch. 516c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if ((availablePrimaryInputDevices() & txDevice & ~AUDIO_DEVICE_BIT_IN) 517c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent == AUDIO_DEVICE_NONE) { 518c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent createTxPatch = true; 519c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 520c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else { 521c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // create RX path audio patch 522c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent deviceList = mAvailableOutputDevices.getDevicesFromType(rxDevice); 523c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!deviceList.isEmpty(), 524c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() selected device not in output device list"); 525c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<DeviceDescriptor> rxSinkDeviceDesc = deviceList.itemAt(0); 526c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent deviceList = mAvailableInputDevices.getDevicesFromType(AUDIO_DEVICE_IN_TELEPHONY_RX); 527c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!deviceList.isEmpty(), 528c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() no telephony RX device"); 529c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<DeviceDescriptor> rxSourceDeviceDesc = deviceList.itemAt(0); 530c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 531c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent rxSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]); 532c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent rxSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]); 533c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 534c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // request to reuse existing output stream if one is already opened to reach the RX device 535c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent SortedVector<audio_io_handle_t> outputs = 536c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent getOutputsForDevice(rxDevice, mOutputs); 5378838a3895c365d443ee22e169ccf45956780c081Eric Laurent audio_io_handle_t output = selectOutput(outputs, 5388838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_OUTPUT_FLAG_NONE, 5398838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_FORMAT_INVALID); 540c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (output != AUDIO_IO_HANDLE_NONE) { 541c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 542c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!outputDesc->isDuplicated(), 543c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() RX device output is duplicated"); 544c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent outputDesc->toAudioPortConfig(&patch.sources[1]); 545c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sources = 2; 546c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 547c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 548c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 549c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, 0); 550c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOGW_IF(status != NO_ERROR, "updateCallRouting() error %d creating RX audio patch", 551c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent status); 552c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (status == NO_ERROR) { 553c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallRxPatch = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 554c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent &patch, mUidCached); 555c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallRxPatch->mAfPatchHandle = afPatchHandle; 556c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallRxPatch->mUid = mUidCached; 557c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 558c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent createTxPatch = true; 559c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 560c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (createTxPatch) { 561c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 562c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent struct audio_patch patch; 563c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sources = 1; 564c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sinks = 1; 565c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent deviceList = mAvailableInputDevices.getDevicesFromType(txDevice); 566c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!deviceList.isEmpty(), 567c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() selected device not in input device list"); 568c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<DeviceDescriptor> txSourceDeviceDesc = deviceList.itemAt(0); 569c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent txSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]); 570c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent deviceList = mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX); 571c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!deviceList.isEmpty(), 572c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() no telephony TX device"); 573c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<DeviceDescriptor> txSinkDeviceDesc = deviceList.itemAt(0); 574c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent txSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]); 575c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 576c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent SortedVector<audio_io_handle_t> outputs = 577c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent getOutputsForDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX, mOutputs); 5788838a3895c365d443ee22e169ccf45956780c081Eric Laurent audio_io_handle_t output = selectOutput(outputs, 5798838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_OUTPUT_FLAG_NONE, 5808838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_FORMAT_INVALID); 581c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // request to reuse existing output stream if one is already opened to reach the TX 582c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // path output device 583c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (output != AUDIO_IO_HANDLE_NONE) { 584c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 585c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOG_ASSERT(!outputDesc->isDuplicated(), 586c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent "updateCallRouting() RX device output is duplicated"); 587c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent outputDesc->toAudioPortConfig(&patch.sources[1]); 588c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent patch.num_sources = 2; 589c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 590c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 591c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 592c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, 0); 593c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent ALOGW_IF(status != NO_ERROR, "setPhoneState() error %d creating TX audio patch", 594c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent status); 595c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (status == NO_ERROR) { 596c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallTxPatch = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 597c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent &patch, mUidCached); 598c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallTxPatch->mAfPatchHandle = afPatchHandle; 599c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallTxPatch->mUid = mUidCached; 600c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 601c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 602c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent} 603c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 604e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setPhoneState(audio_mode_t state) 605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() state %d", state); 6073b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state < 0 || state >= AUDIO_MODE_CNT) { 608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setPhoneState() invalid state %d", state); 609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (state == mPhoneState ) { 613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setPhoneState() setting same state %d", state); 614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if leaving call state, handle special case of active streams 618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // pertaining to sonification strategy see handleIncallSonification() 619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() in call state management: new state is %d", state); 6213b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 622223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if (stream == AUDIO_STREAM_PATCH) { 623223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent continue; 624223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } 6253b73df74357b33869b39a1d69427673c780bd805Eric Laurent handleIncallSonification((audio_stream_type_t)stream, false, true); 626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6272cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent 6282cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent // force reevaluating accessibility routing when call starts 6292cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY); 630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // store previous phone state for management of sonification strategy below 633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int oldState = mPhoneState; 634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPhoneState = state; 635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force = false; 636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // are we entering or starting a call 638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isStateInCall(oldState) && isStateInCall(state)) { 639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Entering call in setPhoneState()"); 640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when starting a call 641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j]; 646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isStateInCall(oldState) && !isStateInCall(state)) { 648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Exiting call in setPhoneState()"); 649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when exiting a call 650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] = 654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[AUDIO_STREAM_DTMF][j]; 655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isStateInCall(state) && (state != oldState)) { 657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV(" Switching between telephony and VoIP in setPhoneState()"); 658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force routing command to audio hardware when switching between telephony and VoIP 659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // even if no device change is needed 660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check for device and output changes triggered by new phone state 664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6681f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs = 0; 671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(state)) { 672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 6741f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute media and sonification strategies and delay device switch by the largest 676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // latency of any output where either strategy is active. 677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This avoid sending the ring tone or music tail into the earpiece or headset. 678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->isStrategyActive(STRATEGY_MEDIA, 679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime) || 681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->isStrategyActive(STRATEGY_SONIFICATION, 682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_HEADSET_MUSIC_DELAY, 683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime)) && 684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (delayMs < (int)desc->mLatency*2)) { 685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs = desc->mLatency*2; 686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); 688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, 689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); 690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i)); 691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS, 692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/)); 693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 696c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // Note that despite the fact that getNewOutputDevice() is called on the primary output, 697c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // the device returned is not necessarily reachable via this output 698c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/); 699c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // force routing command to audio hardware when ending call 700c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // even if no device change is needed 701c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) { 702c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent rxDevice = hwOutputDesc->device(); 703c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 705c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (state == AUDIO_MODE_IN_CALL) { 706c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent updateCallRouting(rxDevice, delayMs); 707c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (oldState == AUDIO_MODE_IN_CALL) { 708c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mCallRxPatch != 0) { 709c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0); 710c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallRxPatch.clear(); 711c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 712c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mCallTxPatch != 0) { 713c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0); 714c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mCallTxPatch.clear(); 715c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 716c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent setOutputDevice(mPrimaryOutput, rxDevice, force, 0); 717c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else { 718c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent setOutputDevice(mPrimaryOutput, rxDevice, force, 0); 719c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if entering in call state, handle special case of active streams 721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // pertaining to sonification strategy see handleIncallSonification() 722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isStateInCall(state)) { 723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setPhoneState() in call state management: new state is %d", state); 7243b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 725223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if (stream == AUDIO_STREAM_PATCH) { 726223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent continue; 727223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } 7283b73df74357b33869b39a1d69427673c780bd805Eric Laurent handleIncallSonification((audio_stream_type_t)stream, true, true); 729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE 7333b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state == AUDIO_MODE_RINGTONE && 7343b73df74357b33869b39a1d69427673c780bd805Eric Laurent isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { 735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume = true; 736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume = false; 738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 741e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setForceUse(audio_policy_force_use_t usage, 7423b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_forced_cfg_t config) 743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); 745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool forceVolumeReeval = false; 747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(usage) { 7483b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_COMMUNICATION: 7493b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO && 7503b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NONE) { 751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); 752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 7573b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_MEDIA: 7583b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP && 7593b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 7603b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_ANALOG_DOCK && 7613b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE && 762327cb70dcbf3a1f1679aeafaaa62d8532abea86dHochi Huang config != AUDIO_POLICY_FORCE_NO_BT_A2DP && config != AUDIO_POLICY_FORCE_SPEAKER ) { 763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); 764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 7683b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_RECORD: 7693b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 7703b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_NONE) { 771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); 772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 7763b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_DOCK: 7773b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK && 7783b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_BT_DESK_DOCK && 7793b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && 7803b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_ANALOG_DOCK && 7813b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) { 782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); 783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 7873b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_FOR_SYSTEM: 7883b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (config != AUDIO_POLICY_FORCE_NONE && 7893b73df74357b33869b39a1d69427673c780bd805Eric Laurent config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { 790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config); 791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent forceVolumeReeval = true; 793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mForceUse[usage] = config; 794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 7957b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO: 7967b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang if (config != AUDIO_POLICY_FORCE_NONE && 7977b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) { 7987b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang ALOGW("setForceUse() invalid config %d forHDMI_SYSTEM_AUDIO", config); 7997b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang } 8007b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang mForceUse[usage] = config; 8017b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang break; 802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setForceUse() invalid usage %d", usage); 804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check for device and output changes triggered by new force usage 808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkA2dpSuspend(); 809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForAllStrategies(); 810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 811c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mPhoneState == AUDIO_MODE_IN_CALL) { 812c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/); 813c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent updateCallRouting(newDevice); 814c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = mOutputs.keyAt(i); 8171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t newDevice = getNewOutputDevice(output, true /*fromCache*/); 818c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if ((mPhoneState != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) { 819c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE)); 820c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) { 822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent applyStreamVolumes(output, newDevice, 0, true); 823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t activeInput = getActiveInput(); 827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (activeInput != 0) { 8281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setInputDevice(activeInput, getNewInputDevice(activeInput)); 829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 833e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage) 834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mForceUse[usage]; 836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 838e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setSystemProperty(const char* property, const char* value) 839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setSystemProperty() property %s, value %s", property, value); 841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Find a direct output profile compatible with the parameters passed, even if the input flags do 844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// not explicitly request a direct output 8451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::IOProfile> AudioPolicyManager::getProfileForDirectOutput( 846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_output_flags_t flags) 851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { 8571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j]; 858275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent bool found = profile->isCompatibleProfile(device, String8(""), samplingRate, 859cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten NULL /*updatedSamplingRate*/, format, channelMask, 860cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD ? 861cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD : AUDIO_OUTPUT_FLAG_DIRECT); 8623a4311c68348f728558e87b5db67d47605783890Eric Laurent if (found && (mAvailableOutputDevices.types() & profile->mSupportedDevices.types())) { 8633a4311c68348f728558e87b5db67d47605783890Eric Laurent return profile; 8643a4311c68348f728558e87b5db67d47605783890Eric Laurent } 865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 870e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream, 871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t samplingRate, 872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_channel_mask_t channelMask, 8743b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_output_flags_t flags, 875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const audio_offload_info_t *offloadInfo) 876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 8773b73df74357b33869b39a1d69427673c780bd805Eric Laurent routing_strategy strategy = getStrategy(stream); 878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x", 880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, stream, samplingRate, format, channelMask, flags); 881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 882e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent return getOutputForDevice(device, AUDIO_SESSION_ALLOCATE, 883e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent stream, samplingRate,format, channelMask, 884e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent flags, offloadInfo); 885e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent} 886e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent 887e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentstatus_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr, 888e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_io_handle_t *output, 889e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_session_t session, 890e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_stream_type_t *stream, 891e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent uint32_t samplingRate, 892e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_format_t format, 893e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_channel_mask_t channelMask, 894e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_output_flags_t flags, 895e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent const audio_offload_info_t *offloadInfo) 896e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent{ 897e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_attributes_t attributes; 898e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent if (attr != NULL) { 899e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent if (!isValidAttributes(attr)) { 900e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]", 901e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent attr->usage, attr->content_type, attr->flags, 902e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent attr->tags); 903e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent return BAD_VALUE; 904e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent } 905e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent attributes = *attr; 906e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent } else { 907e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) { 908e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent ALOGE("getOutputForAttr(): invalid stream type"); 909e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent return BAD_VALUE; 910e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent } 911e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent stream_type_to_audio_attributes(*stream, &attributes); 9125bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 913e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent 914275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t i = 0; i < mPolicyMixes.size(); i++) { 915275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<AudioOutputDescriptor> desc; 916275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (mPolicyMixes[i]->mMix.mMixType == MIX_TYPE_PLAYERS) { 917275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t j = 0; j < mPolicyMixes[i]->mMix.mCriteria.size(); j++) { 918275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if ((RULE_MATCH_ATTRIBUTE_USAGE == mPolicyMixes[i]->mMix.mCriteria[j].mRule && 919275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mPolicyMixes[i]->mMix.mCriteria[j].mAttr.mUsage == attributes.usage) || 920275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent (RULE_EXCLUDE_ATTRIBUTE_USAGE == mPolicyMixes[i]->mMix.mCriteria[j].mRule && 921275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mPolicyMixes[i]->mMix.mCriteria[j].mAttr.mUsage != attributes.usage)) { 922275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent desc = mPolicyMixes[i]->mOutput; 923275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 924275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 925275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 && 926275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent strncmp(attributes.tags + strlen("addr="), 927275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mPolicyMixes[i]->mMix.mRegistrationId.string(), 928275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) { 929275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent desc = mPolicyMixes[i]->mOutput; 930275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 931275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 932275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 933275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } else if (mPolicyMixes[i]->mMix.mMixType == MIX_TYPE_RECORDERS) { 934275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE && 935275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 && 936275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent strncmp(attributes.tags + strlen("addr="), 937275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mPolicyMixes[i]->mMix.mRegistrationId.string(), 938275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) { 939275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent desc = mPolicyMixes[i]->mOutput; 940275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 941275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 942275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (desc != 0) { 943275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (!audio_is_linear_pcm(format)) { 944275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return BAD_VALUE; 945275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 946c722f30eef03e77054395ae122470cf8dba93937Eric Laurent desc->mPolicyMix = &mPolicyMixes[i]->mMix; 947275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent *stream = streamTypefromAttributesInt(&attributes); 948275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent *output = desc->mIoHandle; 949275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGV("getOutputForAttr() returns output %d", *output); 950275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return NO_ERROR; 951275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 952275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 953275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) { 954275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE"); 955275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return BAD_VALUE; 956275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 957275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 95893c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x", 959e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent attributes.usage, attributes.content_type, attributes.tags, attributes.flags); 9605bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 961e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes); 9625bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 96393c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent 964e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) { 96593c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC); 96693c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent } 96793c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent 968fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi ALOGV("getOutputForAttr() device 0x%x, samplingRate %d, format %x, channelMask %x, flags %x", 9695bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi device, samplingRate, format, channelMask, flags); 9705bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 971e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent *stream = streamTypefromAttributesInt(&attributes); 972e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent *output = getOutputForDevice(device, session, *stream, 973e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent samplingRate, format, channelMask, 974e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent flags, offloadInfo); 975e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent if (*output == AUDIO_IO_HANDLE_NONE) { 976e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent return INVALID_OPERATION; 977e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent } 978e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent return NO_ERROR; 9795bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi} 9805bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 9815bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_io_handle_t AudioPolicyManager::getOutputForDevice( 9825bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_devices_t device, 983caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent audio_session_t session __unused, 9845bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_stream_type_t stream, 9855bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi uint32_t samplingRate, 9865bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_format_t format, 9875bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_channel_mask_t channelMask, 9885bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi audio_output_flags_t flags, 9895bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi const audio_offload_info_t *offloadInfo) 9905bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{ 991cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; 9925bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi uint32_t latency = 0; 993cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status; 9945bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mCurOutput != 0) { 997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", 998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); 999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTestOutputs[mCurOutput] == 0) { 1001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() opening test output"); 10021f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL); 1003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = mTestDevice; 1004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency = mTestLatencyMs; 10053b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc->mFlags = 10063b73df74357b33869b39a1d69427673c780bd805Eric Laurent (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0); 1007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mRefCount[stream] = 0; 1008cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 1009cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = mTestSamplingRate; 1010cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = mTestChannels; 1011cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = mTestFormat; 101277cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk if (offloadInfo != NULL) { 101377cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk config.offload_info = *offloadInfo; 101477cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk } 1015cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status = mpClientInterface->openOutput(0, 1016cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &mTestOutputs[mCurOutput], 1017cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 1018cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mDevice, 1019cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent String8(""), 1020cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mLatency, 1021cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFlags); 1022cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status == NO_ERROR) { 1023cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mSamplingRate = config.sample_rate; 1024cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFormat = config.format; 1025cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mChannelMask = config.channel_mask; 1026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 1027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"),mCurOutput); 1028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); 1029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(mTestOutputs[mCurOutput], outputDesc); 1030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mTestOutputs[mCurOutput]; 1033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open a direct output if required by specified parameters 1037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //force direct flag if offload flag is set: offloading implies a direct output stream 1038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and all common behaviors are driven by checking only the direct flag 1039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this should normally be set appropriately in the policy configuration file 1040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 10413b73df74357b33869b39a1d69427673c780bd805Eric Laurent flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT); 1042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 104393c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) { 104493c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT); 104593c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent } 1046e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent // only allow deep buffering for music stream type 1047e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent if (stream != AUDIO_STREAM_MUSIC) { 1048e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER); 1049e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent } 1050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1051b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent sp<IOProfile> profile; 1052b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent 1053b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent // skip direct output selection if the request can obviously be attached to a mixed output 1054c260784e37dea73a2090d4ccd91472d61d3b6230Eric Laurent // and not explicitly requested 1055c260784e37dea73a2090d4ccd91472d61d3b6230Eric Laurent if (((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) && 1056c260784e37dea73a2090d4ccd91472d61d3b6230Eric Laurent audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE && 1057b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent audio_channel_count_from_out_mask(channelMask) <= 2) { 1058b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent goto non_direct_output; 1059b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent } 1060b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent 1061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 1062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 1063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // detects there is an active non offloadable effect. 1064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 1065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 1066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the background. 1067b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent 1068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) || 1069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent !isNonOffloadableEffectEnabled()) { 1070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile = getProfileForDirectOutput(device, 1071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent samplingRate, 1072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent format, 1073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent channelMask, 1074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (audio_output_flags_t)flags); 1075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 10771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (profile != 0) { 10781f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = NULL; 1079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 10811f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 1082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && (profile == desc->mProfile)) { 1083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc = desc; 1084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // reuse direct output if currently open and configured with same parameters 1085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((samplingRate == outputDesc->mSamplingRate) && 1086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (format == outputDesc->mFormat) && 1087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (channelMask == outputDesc->mChannelMask)) { 1088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDirectOpenCount++; 1089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i)); 1090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutputs.keyAt(i); 1091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // close direct output if currently open and configured with different parameters 1095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc != NULL) { 10961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent closeOutput(outputDesc->mIoHandle); 1097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc = new AudioOutputDescriptor(profile); 1099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = device; 1100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency = 0; 1101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags); 1102cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 1103cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = samplingRate; 1104cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = channelMask; 1105cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = format; 110677cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk if (offloadInfo != NULL) { 110777cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk config.offload_info = *offloadInfo; 110877cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk } 1109cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status = mpClientInterface->openOutput(profile->mModule->mHandle, 1110cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &output, 1111cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 1112cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mDevice, 1113cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent String8(""), 1114cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mLatency, 1115cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFlags); 1116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // only accept an output with the requested parameters 1118cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status != NO_ERROR || 1119cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (samplingRate != 0 && samplingRate != config.sample_rate) || 1120cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (format != AUDIO_FORMAT_DEFAULT && format != config.format) || 1121cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (channelMask != 0 && channelMask != config.channel_mask)) { 1122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," 1123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "format %d %d, channelMask %04x %04x", output, samplingRate, 1124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, 1125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mChannelMask); 1126cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (output != AUDIO_IO_HANDLE_NONE) { 1127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 1128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1129a82797faddb37adb2d441737884576684c8515cbEric Laurent // fall back to mixer output if possible when the direct output could not be open 1130a82797faddb37adb2d441737884576684c8515cbEric Laurent if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE) { 1131a82797faddb37adb2d441737884576684c8515cbEric Laurent goto non_direct_output; 1132a82797faddb37adb2d441737884576684c8515cbEric Laurent } 1133cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent return AUDIO_IO_HANDLE_NONE; 1134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1135cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mSamplingRate = config.sample_rate; 1136cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mChannelMask = config.channel_mask; 1137cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFormat = config.format; 1138cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mRefCount[stream] = 0; 1139cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mStopTime[stream] = 0; 1140cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mDirectOpenCount = 1; 1141cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent 1142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t srcOutput = getOutputForEffect(); 1143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, outputDesc); 1144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 1145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dstOutput == output) { 1146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput); 1147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 1149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() returns new direct output %d", output); 1150b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 1151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 1152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1154b732cf5af93c33fa183769210ce9954521fb68cdEric Laurentnon_direct_output: 1155b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent 1156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ignoring channel mask due to downmix capability in mixer 1157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open a non direct output 1159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // for non direct outputs, only PCM is supported 1161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_linear_pcm(format)) { 1162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // get which output is suitable for the specified stream. The actual 1163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // routing change will happen when startOutput() will be called 1164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs); 1165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 11668838a3895c365d443ee22e169ccf45956780c081Eric Laurent // at this stage we should ignore the DIRECT flag as no direct output could be found earlier 11678838a3895c365d443ee22e169ccf45956780c081Eric Laurent flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT); 11688838a3895c365d443ee22e169ccf45956780c081Eric Laurent output = selectOutput(outputs, flags, format); 1169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d," 1171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); 1172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutput() returns output %d", output); 1174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 1176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1178e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs, 11798838a3895c365d443ee22e169ccf45956780c081Eric Laurent audio_output_flags_t flags, 11808838a3895c365d443ee22e169ccf45956780c081Eric Laurent audio_format_t format) 1181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // select one output among several that provide a path to a particular device or set of 1183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // devices (the list was previously build by getOutputsForDevice()). 1184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The priority is as follows: 1185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: the output with the highest number of requested policy flags 1186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: the primary output 1187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the first output in the list 1188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 0) { 1190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 1) { 1193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 1194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int maxCommonFlags = 0; 1197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputFlags = 0; 1198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputPrimary = 0; 1199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 12011f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); 1202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputDesc->isDuplicated()) { 12038838a3895c365d443ee22e169ccf45956780c081Eric Laurent // if a valid format is specified, skip output if not compatible 12048838a3895c365d443ee22e169ccf45956780c081Eric Laurent if (format != AUDIO_FORMAT_INVALID) { 12058838a3895c365d443ee22e169ccf45956780c081Eric Laurent if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { 12068838a3895c365d443ee22e169ccf45956780c081Eric Laurent if (format != outputDesc->mFormat) { 12078838a3895c365d443ee22e169ccf45956780c081Eric Laurent continue; 12088838a3895c365d443ee22e169ccf45956780c081Eric Laurent } 12098838a3895c365d443ee22e169ccf45956780c081Eric Laurent } else if (!audio_is_linear_pcm(format)) { 12108838a3895c365d443ee22e169ccf45956780c081Eric Laurent continue; 12118838a3895c365d443ee22e169ccf45956780c081Eric Laurent } 12128838a3895c365d443ee22e169ccf45956780c081Eric Laurent } 12138838a3895c365d443ee22e169ccf45956780c081Eric Laurent 12143b73df74357b33869b39a1d69427673c780bd805Eric Laurent int commonFlags = popcount(outputDesc->mProfile->mFlags & flags); 1215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (commonFlags > maxCommonFlags) { 1216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputFlags = outputs[i]; 1217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent maxCommonFlags = commonFlags; 1218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); 1219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 1221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputPrimary = outputs[i]; 1222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputFlags != 0) { 1227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputFlags; 1228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputPrimary != 0) { 1230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputPrimary; 1231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 1234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1236e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startOutput(audio_io_handle_t output, 12373b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream, 1238e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_session_t session) 1239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); 1241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 1242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startOutput() unknown output %d", output); 1244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1247d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi // cannot start playback of STREAM_TTS if any other output is being used 1248d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi uint32_t beaconMuteLatency = 0; 1249d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi if (stream == AUDIO_STREAM_TTS) { 1250d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi ALOGV("\t found BEACON stream"); 1251d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi if (isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) { 1252d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi return INVALID_OPERATION; 1253d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } else { 1254d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi beaconMuteLatency = handleEventForBeacon(STARTING_BEACON); 1255d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 1256d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } else { 1257d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi // some playback other than beacon starts 1258d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT); 1259d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 1260d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi 12611f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); 1262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // increment usage count for this stream on the requested output: 1264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // NOTE that the usage count is the same for duplicated output and hardware output which is 1265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // necessary for a correct control of hardware output routing by startOutput() and stopOutput() 1266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->changeRefCount(stream, 1); 1267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] == 1) { 1269275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent // starting an output being rerouted? 1270275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent audio_devices_t newDevice; 1271c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (outputDesc->mPolicyMix != NULL) { 1272275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX; 1273275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } else { 1274275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent newDevice = getNewOutputDevice(output, false /*fromCache*/); 1275275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 1276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent routing_strategy strategy = getStrategy(stream); 1277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool shouldWait = (strategy == STRATEGY_SONIFICATION) || 1278d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi (strategy == STRATEGY_SONIFICATION_RESPECTFUL) || 1279d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi (beaconMuteLatency > 0); 1280d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi uint32_t waitMs = beaconMuteLatency; 1281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force = false; 1282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 12831f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 1284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc != outputDesc) { 1285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force a device change if any other output is managed by the same hw 1286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // module and has a current device selection that differs from selected device. 1287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // In this case, the audio HAL must receive the new device selection so that it can 1288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // change the device currently selected by the other active output. 1289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->sharesHwModuleWith(desc) && 1290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->device() != newDevice) { 1291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force = true; 1292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // wait for audio on other active outputs to be presented when starting 1294d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi // a notification so that audio focus effect can propagate, or that a mute/unmute 1295d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi // event occurred for beacon 1296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t latency = desc->latency(); 1297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { 1298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent waitMs = latency; 1299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); 1303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle special case for sonification while in call 1305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 1306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleIncallSonification(stream, true, false); 1307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // apply volume rules for current stream and device if necessary 1310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 1311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].getVolumeIndex(newDevice), 1312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 1313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent newDevice); 1314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update the outputs if starting an output with a stream that can affect notification 1316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // routing 1317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleNotificationRoutingForStream(stream); 1318c722f30eef03e77054395ae122470cf8dba93937Eric Laurent 1319c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // Automatically enable the remote submix input when output is started on a re routing mix 1320c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // of type MIX_TYPE_RECORDERS 1321c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (audio_is_remote_submix_device(newDevice) && outputDesc->mPolicyMix != NULL && 1322c722f30eef03e77054395ae122470cf8dba93937Eric Laurent outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) { 1323c73ca6ef04136f28306784ad35f444538f081957Eric Laurent setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, 1324c722f30eef03e77054395ae122470cf8dba93937Eric Laurent AUDIO_POLICY_DEVICE_STATE_AVAILABLE, 1325c722f30eef03e77054395ae122470cf8dba93937Eric Laurent outputDesc->mPolicyMix->mRegistrationId); 1326c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } 1327c722f30eef03e77054395ae122470cf8dba93937Eric Laurent 13282cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent // force reevaluating accessibility routing when ringtone or alarm starts 13292cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent if (strategy == STRATEGY_SONIFICATION) { 13302cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY); 13312cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent } 13322cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent 1333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (waitMs > muteWaitMs) { 1334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent usleep((waitMs - muteWaitMs) * 2 * 1000); 1335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1341e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopOutput(audio_io_handle_t output, 13423b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream, 1343e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent audio_session_t session) 1344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); 1346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 1347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopOutput() unknown output %d", output); 1349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 13521f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); 1353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1354d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi // always handle stream stop, check which stream type is stopping 1355d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT); 1356d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi 1357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handle special case for sonification while in call 1358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 1359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleIncallSonification(stream, false, false); 1360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] > 0) { 1363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // decrement usage count of this stream on the output 1364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->changeRefCount(stream, -1); 1365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // store time at which the stream was stopped - see isStreamActive() 1366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream] == 0) { 1367c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // Automatically disable the remote submix input when output is stopped on a 1368c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // re routing mix of type MIX_TYPE_RECORDERS 1369c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (audio_is_remote_submix_device(outputDesc->mDevice) && 1370c722f30eef03e77054395ae122470cf8dba93937Eric Laurent outputDesc->mPolicyMix != NULL && 1371c722f30eef03e77054395ae122470cf8dba93937Eric Laurent outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) { 1372c73ca6ef04136f28306784ad35f444538f081957Eric Laurent setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, 1373c722f30eef03e77054395ae122470cf8dba93937Eric Laurent AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, 1374c722f30eef03e77054395ae122470cf8dba93937Eric Laurent outputDesc->mPolicyMix->mRegistrationId); 1375c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } 1376c722f30eef03e77054395ae122470cf8dba93937Eric Laurent 1377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStopTime[stream] = systemTime(); 13781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); 1379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // delay the device switch by twice the latency because stopOutput() is executed when 1380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the track stop() command is received and at that time the audio track buffer can 1381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // still contain data that needs to be drained. The latency only covers the audio HAL 1382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and kernel buffers. Also the latency does not always include additional delay in the 1383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // audio path (audio DSP, CODEC ...) 1384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); 1385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // force restoring the device selection on other active outputs if it differs from the 1387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // one being selected for this output 1388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(i); 13901f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 1391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (curOutput != output && 1392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->isActive() && 1393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->sharesHwModuleWith(desc) && 1394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (newDevice != desc->device())) { 1395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setOutputDevice(curOutput, 13961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent getNewOutputDevice(curOutput, false /*fromCache*/), 1397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent true, 1398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mLatency*2); 1399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update the outputs if stopping one with a stream that can affect notification routing 1402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent handleNotificationRoutingForStream(stream); 1403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 1406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopOutput() refcount is already 0 for output %d", output); 1407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1411e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentvoid AudioPolicyManager::releaseOutput(audio_io_handle_t output, 1412caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent audio_stream_type_t stream __unused, 1413caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent audio_session_t session __unused) 1414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseOutput() %d", output); 1416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(output); 1417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseOutput() releasing unknown output %d", output); 1419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 1423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int testIndex = testOutputIndex(output); 1424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (testIndex != 0) { 14251f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); 1426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isActive()) { 1427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 1428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(output); 1429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[testIndex] = 0; 1430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 1434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 14351f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(index); 14363b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { 1437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->mDirectOpenCount <= 0) { 1438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseOutput() invalid open count %d for output %d", 1439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mDirectOpenCount, output); 1440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (--desc->mDirectOpenCount == 0) { 1443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent closeOutput(output); 1444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // If effects where present on the output, audioflinger moved them to the primary 1445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // output by default: move them back to the appropriate output. 1446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t dstOutput = getOutputForEffect(); 1447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dstOutput != mPrimaryOutput) { 1448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput); 1449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1450b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 1451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1456caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurentstatus_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, 1457caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent audio_io_handle_t *input, 1458caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent audio_session_t session, 1459caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent uint32_t samplingRate, 1460caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent audio_format_t format, 1461caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent audio_channel_mask_t channelMask, 146297bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi audio_input_flags_t flags, 146397bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi input_type_t *inputType) 1464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1465caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x," 1466caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent "session %d, flags %#x", 1467caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent attr->source, samplingRate, format, channelMask, session, flags); 1468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1469caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent *input = AUDIO_IO_HANDLE_NONE; 147097bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi *inputType = API_INPUT_INVALID; 1471275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent audio_devices_t device; 1472275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent // handle legacy remote submix case where the address was not always specified 1473275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent String8 address = String8(""); 14745dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent bool isSoundTrigger = false; 1475c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent audio_source_t inputSource = attr->source; 1476c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent audio_source_t halInputSource; 1477c722f30eef03e77054395ae122470cf8dba93937Eric Laurent AudioMix *policyMix = NULL; 1478275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 1479c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent if (inputSource == AUDIO_SOURCE_DEFAULT) { 1480c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent inputSource = AUDIO_SOURCE_MIC; 1481c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent } 1482c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent halInputSource = inputSource; 1483c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent 1484c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX && 1485275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent strncmp(attr->tags, "addr=", strlen("addr=")) == 0) { 1486275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; 1487275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent address = String8(attr->tags + strlen("addr=")); 1488275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ssize_t index = mPolicyMixes.indexOfKey(address); 1489275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (index < 0) { 1490275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGW("getInputForAttr() no policy for address %s", address.string()); 1491275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return BAD_VALUE; 1492275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 1493c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (mPolicyMixes[index]->mMix.mMixType != MIX_TYPE_PLAYERS) { 1494c722f30eef03e77054395ae122470cf8dba93937Eric Laurent ALOGW("getInputForAttr() bad policy mix type for address %s", address.string()); 1495c722f30eef03e77054395ae122470cf8dba93937Eric Laurent return BAD_VALUE; 1496c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } 1497c722f30eef03e77054395ae122470cf8dba93937Eric Laurent policyMix = &mPolicyMixes[index]->mMix; 149897bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE; 1499275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } else { 1500c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent device = getDeviceAndMixForInputSource(inputSource, &policyMix); 1501275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (device == AUDIO_DEVICE_NONE) { 1502c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent ALOGW("getInputForAttr() could not find device for source %d", inputSource); 1503275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return BAD_VALUE; 1504275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 1505c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (policyMix != NULL) { 1506c722f30eef03e77054395ae122470cf8dba93937Eric Laurent address = policyMix->mRegistrationId; 150797bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi if (policyMix->mMixType == MIX_TYPE_RECORDERS) { 150897bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi // there is an external policy, but this input is attached to a mix of recorders, 150997bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi // meaning it receives audio injected into the framework, so the recorder doesn't 151097bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi // know about it and is therefore considered "legacy" 151197bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi *inputType = API_INPUT_LEGACY; 151297bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi } else { 151397bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi // recording a mix of players defined by an external policy, we're rerouting for 151497bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi // an external policy 151597bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE; 151697bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi } 1517c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } else if (audio_is_remote_submix_device(device)) { 1518c722f30eef03e77054395ae122470cf8dba93937Eric Laurent address = String8("0"); 151997bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi *inputType = API_INPUT_MIX_CAPTURE; 152097bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi } else { 152197bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi *inputType = API_INPUT_LEGACY; 1522c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } 1523275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent // adapt channel selection to input source 1524c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent switch (inputSource) { 1525275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 1526275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK; 1527275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 1528275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent case AUDIO_SOURCE_VOICE_DOWNLINK: 1529275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK; 1530275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 1531275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent case AUDIO_SOURCE_VOICE_CALL: 1532275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK; 1533275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 1534275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent default: 1535275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 1536275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 1537c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent if (inputSource == AUDIO_SOURCE_HOTWORD) { 1538275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ssize_t index = mSoundTriggerSessions.indexOfKey(session); 1539275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (index >= 0) { 1540275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent *input = mSoundTriggerSessions.valueFor(session); 1541275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent isSoundTrigger = true; 1542275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_HW_HOTWORD); 1543275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGV("SoundTrigger capture on session %d input %d", session, *input); 1544275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } else { 1545275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION; 1546275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 15475dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent } 15485dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent } 15495dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent 1550275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<IOProfile> profile = getInputProfile(device, address, 1551275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent samplingRate, format, channelMask, 1552275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent flags); 15531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (profile == 0) { 15545dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent //retry without flags 15555dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent audio_input_flags_t log_flags = flags; 15565dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent flags = AUDIO_INPUT_FLAG_NONE; 1557275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profile = getInputProfile(device, address, 1558275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent samplingRate, format, channelMask, 1559275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent flags); 15605dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent if (profile == 0) { 1561caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent ALOGW("getInputForAttr() could not find profile for device 0x%X, samplingRate %u," 1562caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent "format %#x, channelMask 0x%X, flags %#x", 15635dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent device, samplingRate, format, channelMask, log_flags); 1564caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent return BAD_VALUE; 15655dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent } 1566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mModule->mHandle == 0) { 1569caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent ALOGE("getInputForAttr(): HW module %s not opened", profile->mModule->mName); 1570caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent return NO_INIT; 1571cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent } 1572cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent 1573cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 1574cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = samplingRate; 1575cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = channelMask; 1576cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = format; 1577df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 1578cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status = mpClientInterface->openInput(profile->mModule->mHandle, 1579caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent input, 1580cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 1581cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &device, 1582fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi address, 15831c9c2cc4b170b79a83433749808e286eb0fcc449Eric Laurent halInputSource, 1584cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent flags); 1585cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent 1586cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent // only accept input with the exact requested set of parameters 1587caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent if (status != NO_ERROR || *input == AUDIO_IO_HANDLE_NONE || 1588cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (samplingRate != config.sample_rate) || 1589cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (format != config.format) || 1590cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent (channelMask != config.channel_mask)) { 1591caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent ALOGW("getInputForAttr() failed opening input: samplingRate %d, format %d, channelMask %x", 1592cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent samplingRate, format, channelMask); 1593caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent if (*input != AUDIO_IO_HANDLE_NONE) { 1594caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent mpClientInterface->closeInput(*input); 1595cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent } 1596caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent return BAD_VALUE; 1597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 15991f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile); 1600c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent inputDesc->mInputSource = inputSource; 1601cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent inputDesc->mRefCount = 0; 1602cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent inputDesc->mOpenRefCount = 1; 1603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mSamplingRate = samplingRate; 1604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mFormat = format; 1605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent inputDesc->mChannelMask = channelMask; 1606cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent inputDesc->mDevice = device; 1607c722f30eef03e77054395ae122470cf8dba93937Eric Laurent inputDesc->mSessions.add(session); 1608df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent inputDesc->mIsSoundTrigger = isSoundTrigger; 1609c722f30eef03e77054395ae122470cf8dba93937Eric Laurent inputDesc->mPolicyMix = policyMix; 1610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 161197bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi ALOGV("getInputForAttr() returns input type = %d", inputType); 161297bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi 1613caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent addInput(*input, inputDesc); 1614b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 1615caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent return NO_ERROR; 1616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16184dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentstatus_t AudioPolicyManager::startInput(audio_io_handle_t input, 16194dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent audio_session_t session) 1620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("startInput() input %d", input); 1622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("startInput() unknown input %d", input); 1625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 16271f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); 1628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1629c722f30eef03e77054395ae122470cf8dba93937Eric Laurent index = inputDesc->mSessions.indexOf(session); 16304dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent if (index < 0) { 16314dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent ALOGW("startInput() unknown session %d on input %d", session, input); 16324dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent return BAD_VALUE; 16334dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent } 16344dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent 163574a8e2533561f04029873446206ab407cd2e033bGlenn Kasten // virtual input devices are compatible with other input devices 163674a8e2533561f04029873446206ab407cd2e033bGlenn Kasten if (!isVirtualInputDevice(inputDesc->mDevice)) { 163774a8e2533561f04029873446206ab407cd2e033bGlenn Kasten 163874a8e2533561f04029873446206ab407cd2e033bGlenn Kasten // for a non-virtual input device, check if there is another (non-virtual) active input 1639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t activeInput = getActiveInput(); 164074a8e2533561f04029873446206ab407cd2e033bGlenn Kasten if (activeInput != 0 && activeInput != input) { 164174a8e2533561f04029873446206ab407cd2e033bGlenn Kasten 164274a8e2533561f04029873446206ab407cd2e033bGlenn Kasten // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed, 164374a8e2533561f04029873446206ab407cd2e033bGlenn Kasten // otherwise the active input continues and the new input cannot be started. 16441f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput); 1645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) { 164674a8e2533561f04029873446206ab407cd2e033bGlenn Kasten ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput); 1647c722f30eef03e77054395ae122470cf8dba93937Eric Laurent stopInput(activeInput, activeDesc->mSessions.itemAt(0)); 1648c722f30eef03e77054395ae122470cf8dba93937Eric Laurent releaseInput(activeInput, activeDesc->mSessions.itemAt(0)); 1649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 165074a8e2533561f04029873446206ab407cd2e033bGlenn Kasten ALOGE("startInput(%d) failed: other input %d already started", input, activeInput); 1651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 165674a8e2533561f04029873446206ab407cd2e033bGlenn Kasten if (inputDesc->mRefCount == 0) { 1657df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (activeInputsCount() == 0) { 1658df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent SoundTrigger::setCaptureState(true); 1659df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 166074a8e2533561f04029873446206ab407cd2e033bGlenn Kasten setInputDevice(input, getNewInputDevice(input), true /* force */); 1661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1662c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // automatically enable the remote submix output when input is started if not 1663c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // used by a policy mix of type MIX_TYPE_RECORDERS 166474a8e2533561f04029873446206ab407cd2e033bGlenn Kasten // For remote submix (a virtual device), we open only one input per capture request. 166574a8e2533561f04029873446206ab407cd2e033bGlenn Kasten if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1666c722f30eef03e77054395ae122470cf8dba93937Eric Laurent String8 address = String8(""); 1667c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (inputDesc->mPolicyMix == NULL) { 1668c722f30eef03e77054395ae122470cf8dba93937Eric Laurent address = String8("0"); 1669c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) { 1670c722f30eef03e77054395ae122470cf8dba93937Eric Laurent address = inputDesc->mPolicyMix->mRegistrationId; 1671c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } 1672c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (address != "") { 1673c73ca6ef04136f28306784ad35f444538f081957Eric Laurent setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 1674c722f30eef03e77054395ae122470cf8dba93937Eric Laurent AUDIO_POLICY_DEVICE_STATE_AVAILABLE, 1675c722f30eef03e77054395ae122470cf8dba93937Eric Laurent address); 1676c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } 167774a8e2533561f04029873446206ab407cd2e033bGlenn Kasten } 1678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); 1681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16826a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten inputDesc->mRefCount++; 1683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 16864dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentstatus_t AudioPolicyManager::stopInput(audio_io_handle_t input, 16874dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent audio_session_t session) 1688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("stopInput() input %d", input); 1690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopInput() unknown input %d", input); 1693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 16951f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); 1696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1697c722f30eef03e77054395ae122470cf8dba93937Eric Laurent index = inputDesc->mSessions.indexOf(session); 16984dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent if (index < 0) { 16994dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent ALOGW("stopInput() unknown session %d on input %d", session, input); 17004dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent return BAD_VALUE; 17014dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent } 17024dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent 1703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (inputDesc->mRefCount == 0) { 1704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("stopInput() input %d already stopped", input); 1705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 17066a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten } 17076a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten 17086a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten inputDesc->mRefCount--; 17096a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten if (inputDesc->mRefCount == 0) { 17106a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten 1711c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // automatically disable the remote submix output when input is stopped if not 1712c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // used by a policy mix of type MIX_TYPE_RECORDERS 1713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (audio_is_remote_submix_device(inputDesc->mDevice)) { 1714c722f30eef03e77054395ae122470cf8dba93937Eric Laurent String8 address = String8(""); 1715c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (inputDesc->mPolicyMix == NULL) { 1716c722f30eef03e77054395ae122470cf8dba93937Eric Laurent address = String8("0"); 1717c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) { 1718c722f30eef03e77054395ae122470cf8dba93937Eric Laurent address = inputDesc->mPolicyMix->mRegistrationId; 1719c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } 1720c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (address != "") { 1721c73ca6ef04136f28306784ad35f444538f081957Eric Laurent setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 1722c722f30eef03e77054395ae122470cf8dba93937Eric Laurent AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, 1723c722f30eef03e77054395ae122470cf8dba93937Eric Laurent address); 1724c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } 1725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 17271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent resetInputDevice(input); 1728df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 1729df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (activeInputsCount() == 0) { 1730df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent SoundTrigger::setCaptureState(false); 1731df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 1732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 17336a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten return NO_ERROR; 1734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 17364dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentvoid AudioPolicyManager::releaseInput(audio_io_handle_t input, 17374dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent audio_session_t session) 1738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseInput() %d", input); 1740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mInputs.indexOfKey(input); 1741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("releaseInput() releasing unknown input %d", input); 1743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 17456a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); 17466a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten ALOG_ASSERT(inputDesc != 0); 17474dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent 1748c722f30eef03e77054395ae122470cf8dba93937Eric Laurent index = inputDesc->mSessions.indexOf(session); 17494dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent if (index < 0) { 17504dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent ALOGW("releaseInput() unknown session %d on input %d", session, input); 17514dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent return; 17524dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent } 1753c722f30eef03e77054395ae122470cf8dba93937Eric Laurent inputDesc->mSessions.remove(session); 17546a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten if (inputDesc->mOpenRefCount == 0) { 17556a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten ALOGW("releaseInput() invalid open ref count %d", inputDesc->mOpenRefCount); 17566a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten return; 17576a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten } 17586a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten inputDesc->mOpenRefCount--; 17596a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten if (inputDesc->mOpenRefCount > 0) { 17606a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten ALOGV("releaseInput() exit > 0"); 17616a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten return; 17626a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten } 17636a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten 176405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent closeInput(input); 1765b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPortListUpdate(); 1766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("releaseInput() exit"); 1767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1769d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::closeAllInputs() { 177005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent bool patchRemoved = false; 177105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 1772d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for(size_t input_index = 0; input_index < mInputs.size(); input_index++) { 177305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index); 177405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 177505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent if (patch_index >= 0) { 177605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index); 177705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 177805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mAudioPatches.removeItemsAt(patch_index); 177905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent patchRemoved = true; 178005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent } 1781d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeInput(mInputs.keyAt(input_index)); 1782d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 1783d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mInputs.clear(); 17846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 178505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 178605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent if (patchRemoved) { 178705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 178805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent } 1789d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 1790d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 1791e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initStreamVolume(audio_stream_type_t stream, 1792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexMin, 1793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexMax) 1794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); 1796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (indexMin < 0 || indexMin >= indexMax) { 1797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax); 1798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 1799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexMin = indexMin; 1801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexMax = indexMax; 1802223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now 1803223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if (stream == AUDIO_STREAM_MUSIC) { 1804223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent mStreams[AUDIO_STREAM_ACCESSIBILITY].mIndexMin = indexMin; 1805223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent mStreams[AUDIO_STREAM_ACCESSIBILITY].mIndexMax = indexMax; 1806223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } 1807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1809e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream, 1810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 1811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 1812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { 1815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device)) { 1818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force max volume if stream cannot be muted 1822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; 1823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", 1825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, device, index); 1826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and 1828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // clear all device specific values 1829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexCur.clear(); 1831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].mIndexCur.add(device, index); 1833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 183431551f8dd625b8d40961e141d2913b0073f852abEric Laurent // update volume on all outputs whose current device is also selected by the same 183531551f8dd625b8d40961e141d2913b0073f852abEric Laurent // strategy as the device specified by the caller 183631551f8dd625b8d40961e141d2913b0073f852abEric Laurent audio_devices_t strategyDevice = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); 1837223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent 1838223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent 1839223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now 1840223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent audio_devices_t accessibilityDevice = AUDIO_DEVICE_NONE; 1841223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if (stream == AUDIO_STREAM_MUSIC) { 1842223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent mStreams[AUDIO_STREAM_ACCESSIBILITY].mIndexCur.add(device, index); 1843223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent accessibilityDevice = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, true /*fromCache*/); 1844223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } 1845223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if ((device != AUDIO_DEVICE_OUT_DEFAULT) && 1846223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent (device & (strategyDevice | accessibilityDevice)) == 0) { 184731551f8dd625b8d40961e141d2913b0073f852abEric Laurent return NO_ERROR; 184831551f8dd625b8d40961e141d2913b0073f852abEric Laurent } 1849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t status = NO_ERROR; 1850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 1851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t curDevice = 1852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForVolume(mOutputs.valueAt(i)->device()); 185331551f8dd625b8d40961e141d2913b0073f852abEric Laurent if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & strategyDevice) != 0)) { 1854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); 1855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volStatus != NO_ERROR) { 1856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = volStatus; 1857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1859223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & accessibilityDevice) != 0)) { 1860223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent status_t volStatus = checkAndSetVolume(AUDIO_STREAM_ACCESSIBILITY, 1861223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent index, mOutputs.keyAt(i), curDevice); 1862223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } 1863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return status; 1865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1867e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream, 1868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int *index, 1869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 1870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index == NULL) { 1872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!audio_is_output_device(device)) { 1875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 1876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to 1878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the strategy the stream belongs to. 1879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_OUT_DEFAULT) { 1880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); 1881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForVolume(device); 1883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent *index = mStreams[stream].getVolumeIndex(device); 1885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); 1886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1889e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutputForEffects( 1890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const SortedVector<audio_io_handle_t>& outputs) 1891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // select one output among several suitable for global effects. 1893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The priority is as follows: 1894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 1: An offloaded output. If the effect ends up not being offloadable, 1895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // AudioFlinger will invalidate the track and the offloaded output 1896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // will be closed causing the effect to be moved to a PCM output. 1897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: A deep buffer output 1898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 3: the first output in the list 1899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs.size() == 0) { 1901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 1902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputOffloaded = 0; 1905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t outputDeepBuffer = 0; 1906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 19081f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]); 1909d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags); 1910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 1911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputOffloaded = outputs[i]; 1912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) { 1914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDeepBuffer = outputs[i]; 1915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d", 1919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputOffloaded, outputDeepBuffer); 1920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputOffloaded != 0) { 1921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputOffloaded; 1922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDeepBuffer != 0) { 1924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputDeepBuffer; 1925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs[0]; 1928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1930e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc) 1931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // apply simple rule where global effects are attached to the same output as MUSIC streams 1933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19343b73df74357b33869b39a1d69427673c780bd805Eric Laurent routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC); 1935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); 1936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs); 1937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output = selectOutputForEffects(dstOutputs); 1939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getOutputForEffect() got output %d for fx %s flags %x", 1940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, (desc == NULL) ? "unspecified" : desc->name, (desc == NULL) ? 0 : desc->flags); 1941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return output; 1943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1945e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc, 1946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t io, 1947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t strategy, 1948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int session, 1949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int id) 1950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mOutputs.indexOfKey(io); 1952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent index = mInputs.indexOfKey(io); 1954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("registerEffect() unknown io %d", io); 1956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 1961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 1962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->name, desc->memoryUsage); 1963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsMemory += desc->memoryUsage; 1966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 1967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->name, io, strategy, session, id); 1968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 1969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19701f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = new EffectDescriptor(); 19711f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t)); 19721f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mIo = io; 19731f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mStrategy = (routing_strategy)strategy; 19741f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mSession = session; 19751f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mEnabled = false; 1976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19771f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mEffects.add(id, effectDesc); 1978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 1980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 1981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 1982e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::unregisterEffect(int id) 1983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 1984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mEffects.indexOfKey(id); 1985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 1986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() unknown effect ID %d", id); 1987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 1988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 1989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19901f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = mEffects.valueAt(index); 1991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19921f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent setEffectEnabled(effectDesc, false); 1993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 19941f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (mTotalEffectsMemory < effectDesc->mDesc.memoryUsage) { 1995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() memory %d too big for total %d", 19961f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.memoryUsage, mTotalEffectsMemory); 19971f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.memoryUsage = mTotalEffectsMemory; 1998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 19991f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mTotalEffectsMemory -= effectDesc->mDesc.memoryUsage; 2000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 20011f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.name, id, effectDesc->mDesc.memoryUsage, mTotalEffectsMemory); 2002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.removeItem(id); 2004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 2006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2008e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(int id, bool enabled) 2009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ssize_t index = mEffects.indexOfKey(id); 2011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (index < 0) { 2012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("unregisterEffect() unknown effect ID %d", id); 2013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 2014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return setEffectEnabled(mEffects.valueAt(index), enabled); 2017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 20191f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(const sp<EffectDescriptor>& effectDesc, bool enabled) 2020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 20211f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (enabled == effectDesc->mEnabled) { 2022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(%s) effect already %s", 2023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent enabled?"true":"false", enabled?"enabled":"disabled"); 2024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 2025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (enabled) { 20281f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (mTotalEffectsCpuLoad + effectDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 2029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 20301f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.name, (float)effectDesc->mDesc.cpuLoad/10); 2031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 2032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 20331f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mTotalEffectsCpuLoad += effectDesc->mDesc.cpuLoad; 2034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 2035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 20361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (mTotalEffectsCpuLoad < effectDesc->mDesc.cpuLoad) { 2037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 20381f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 20391f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 2040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 20411f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mTotalEffectsCpuLoad -= effectDesc->mDesc.cpuLoad; 2042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 2043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 20441f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mEnabled = enabled; 2045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 2046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2048e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isNonOffloadableEffectEnabled() 2049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 20511f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = mEffects.valueAt(i); 20521f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) && 20531f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) { 2054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d", 20551f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mDesc.name, effectDesc->mSession); 2056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 2057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2062e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 2063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 2065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 20661f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); 20673b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 2068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 2069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2074e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, 20753b73df74357b33869b39a1d69427673c780bd805Eric Laurent uint32_t inPastMs) const 2076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime = systemTime(); 2078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 20791f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); 2080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 20813b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 2082c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // do not consider re routing (when the output is going to a dynamic policy) 2083c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // as "remote playback" 2084c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (outputDesc->mPolicyMix == NULL) { 20851767df778e20c1395afc63b3a0479bd903e7b9f0Jean-Michel Trivi return true; 20861767df778e20c1395afc63b3a0479bd903e7b9f0Jean-Michel Trivi } 2087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2092e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isSourceActive(audio_source_t source) const 2093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 20951f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i); 2096a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent if (inputDescriptor->mRefCount == 0) { 2097a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent continue; 2098a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent } 2099a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent if (inputDescriptor->mInputSource == (int)source) { 2100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 2101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2102a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it 2103a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent // corresponds to an active capture triggered by a hardware hotword recognition 2104a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) && 2105a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent (inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) { 2106a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent // FIXME: we should not assume that the first session is the active one and keep 2107a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent // activity count per session. Same in startInput(). 2108a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent ssize_t index = mSoundTriggerSessions.indexOfKey(inputDescriptor->mSessions.itemAt(0)); 2109a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent if (index >= 0) { 2110a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent return true; 2111a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent } 2112a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent } 2113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2117275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// Register a list of custom mixes with their attributes and format. 2118275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When a mix is registered, corresponding input and output profiles are 2119275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// added to the remote submix hw module. The profile contains only the 2120275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// parameters (sampling rate, format...) specified by the mix. 2121275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// The corresponding input remote submix device is also connected. 2122275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// 2123275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When a remote submix device is connected, the address is checked to select the 2124275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// appropriate profile and the corresponding input or output stream is opened. 2125275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// 2126275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When capture starts, getInputForAttr() will: 2127275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// - 1 look for a mix matching the address passed in attribtutes tags if any 2128275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// - 2 if none found, getDeviceForInputSource() will: 2129275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// - 2.1 look for a mix matching the attributes source 2130275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// - 2.2 if none found, default to device selection by policy rules 2131275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// At this time, the corresponding output remote submix device is also connected 2132275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// and active playback use cases can be transferred to this mix if needed when reconnecting 2133275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// after AudioTracks are invalidated 2134275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// 2135275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When playback starts, getOutputForAttr() will: 2136275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// - 1 look for a mix matching the address passed in attribtutes tags if any 2137275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// - 2 if none found, look for a mix matching the attributes usage 2138275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// - 3 if none found, default to device and output selection by policy rules. 2139275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2140275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentstatus_t AudioPolicyManager::registerPolicyMixes(Vector<AudioMix> mixes) 2141275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{ 2142275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<HwModule> module; 2143275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 2144275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[i]->mName) == 0 && 2145275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mHwModules[i]->mHandle != 0) { 2146275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent module = mHwModules[i]; 2147275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 2148275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2149275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2150275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2151275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (module == 0) { 2152275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return INVALID_OPERATION; 2153275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2154275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2155275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGV("registerPolicyMixes() num mixes %d", mixes.size()); 2156275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2157275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t i = 0; i < mixes.size(); i++) { 2158275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent String8 address = mixes[i].mRegistrationId; 2159275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ssize_t index = mPolicyMixes.indexOfKey(address); 2160275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (index >= 0) { 2161275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGE("registerPolicyMixes(): mix for address %s already registered", address.string()); 2162275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent continue; 2163275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2164275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent audio_config_t outputConfig = mixes[i].mFormat; 2165275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent audio_config_t inputConfig = mixes[i].mFormat; 2166275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent // NOTE: audio flinger mixer does not support mono output: configure remote submix HAL in 2167275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent // stereo and let audio flinger do the channel conversion if needed. 2168275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent outputConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO; 2169275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent inputConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO; 2170275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent module->addOutputProfile(address, &outputConfig, 2171275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address); 2172275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent module->addInputProfile(address, &inputConfig, 2173275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent AUDIO_DEVICE_IN_REMOTE_SUBMIX, address); 2174275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<AudioPolicyMix> policyMix = new AudioPolicyMix(); 2175275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent policyMix->mMix = mixes[i]; 2176275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mPolicyMixes.add(address, policyMix); 2177c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (mixes[i].mMixType == MIX_TYPE_PLAYERS) { 2178c73ca6ef04136f28306784ad35f444538f081957Eric Laurent setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, 2179c722f30eef03e77054395ae122470cf8dba93937Eric Laurent AUDIO_POLICY_DEVICE_STATE_AVAILABLE, 2180c722f30eef03e77054395ae122470cf8dba93937Eric Laurent address.string()); 2181c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } else { 2182c73ca6ef04136f28306784ad35f444538f081957Eric Laurent setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 2183c722f30eef03e77054395ae122470cf8dba93937Eric Laurent AUDIO_POLICY_DEVICE_STATE_AVAILABLE, 2184c722f30eef03e77054395ae122470cf8dba93937Eric Laurent address.string()); 2185c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } 2186275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2187275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return NO_ERROR; 2188275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent} 2189275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2190275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentstatus_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes) 2191275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{ 2192275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<HwModule> module; 2193275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 2194275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[i]->mName) == 0 && 2195275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mHwModules[i]->mHandle != 0) { 2196275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent module = mHwModules[i]; 2197275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 2198275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2199275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2200275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2201275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (module == 0) { 2202275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return INVALID_OPERATION; 2203275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2204275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2205275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGV("unregisterPolicyMixes() num mixes %d", mixes.size()); 2206275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2207275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t i = 0; i < mixes.size(); i++) { 2208275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent String8 address = mixes[i].mRegistrationId; 2209275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ssize_t index = mPolicyMixes.indexOfKey(address); 2210275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (index < 0) { 2211275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGE("unregisterPolicyMixes(): mix for address %s not registered", address.string()); 2212275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent continue; 2213275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2214275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2215275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mPolicyMixes.removeItemsAt(index); 2216275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2217c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (getDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, address.string()) == 2218c722f30eef03e77054395ae122470cf8dba93937Eric Laurent AUDIO_POLICY_DEVICE_STATE_AVAILABLE) 2219c722f30eef03e77054395ae122470cf8dba93937Eric Laurent { 2220c73ca6ef04136f28306784ad35f444538f081957Eric Laurent setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, 2221c722f30eef03e77054395ae122470cf8dba93937Eric Laurent AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, 2222c722f30eef03e77054395ae122470cf8dba93937Eric Laurent address.string()); 2223c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } 2224275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2225275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) == 2226275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent AUDIO_POLICY_DEVICE_STATE_AVAILABLE) 2227275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent { 2228c73ca6ef04136f28306784ad35f444538f081957Eric Laurent setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 2229275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, 2230275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent address.string()); 2231275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2232275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent module->removeOutputProfile(address); 2233275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent module->removeInputProfile(address); 2234275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2235275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return NO_ERROR; 2236275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent} 2237275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 2238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2239e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::dump(int fd) 2240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 2242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 2243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 2244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); 2246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 2247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput); 2249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 2250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); 2251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 22523b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for communications %d\n", 22533b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]); 2254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 22553b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA]); 2256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 22573b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD]); 2258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 22593b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK]); 2260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 22613b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM]); 2262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 22637b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n", 22647b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO]); 22657b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang result.append(buffer); 2266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 22673a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, " Available output devices:\n"); 22683a4311c68348f728558e87b5db67d47605783890Eric Laurent result.append(buffer); 22693a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, result.string(), result.size()); 22703a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) { 22711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableOutputDevices[i]->dump(fd, 2, i); 22723a4311c68348f728558e87b5db67d47605783890Eric Laurent } 22733a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, "\n Available input devices:\n"); 22743a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, buffer, strlen(buffer)); 22753a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size(); i++) { 22761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableInputDevices[i]->dump(fd, 2, i); 22773a4311c68348f728558e87b5db67d47605783890Eric Laurent } 2278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 2280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 2282d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1); 2283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules[i]->dump(fd); 2285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nOutputs dump:\n"); 2288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 2290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); 2291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.valueAt(i)->dump(fd); 2293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nInputs dump:\n"); 2296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 2298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); 2299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputs.valueAt(i)->dump(fd); 2301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nStreams dump:\n"); 2304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, 2306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); 2307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2308beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn for (size_t i = 0; i < AUDIO_STREAM_CNT; i++) { 2309d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " %02zu ", i); 2310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[i].dump(fd); 2312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", 2315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); 2316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "Registered effects:\n"); 2319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 2321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); 2322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 2323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.valueAt(i)->dump(fd); 2324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 23264d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "\nAudio Patches:\n"); 23274d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent write(fd, buffer, strlen(buffer)); 23284d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent for (size_t i = 0; i < mAudioPatches.size(); i++) { 23294d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mAudioPatches[i]->dump(fd, 2, i); 23304d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } 2331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 2333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This function checks for the parameters which can be offloaded. 2336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This can be enhanced depending on the capability of the DSP and policy 2337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// of the system. 2338e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo) 2339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 2340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d," 2341d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent " BitRate=%u, duration=%" PRId64 " us, has_video=%d", 2342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate, offloadInfo.channel_mask, 2343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format, 2344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us, 2345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.has_video); 2346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check if offload has been disabled 2348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char propValue[PROPERTY_VALUE_MAX]; 2349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (property_get("audio.offload.disable", propValue, "0")) { 2350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (atoi(propValue) != 0) { 2351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("offload disabled by audio.offload.disable=%s", propValue ); 2352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check if stream type is music, then only allow offload as of now. 2357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC) 2358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: stream_type != MUSIC, returning false"); 2360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //TODO: enable audio offloading with video when ready 2364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.has_video) 2365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 2366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("isOffloadSupported: has_video == true, returning false"); 2367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //If duration is less than minimum value defined in property, return false 2371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (property_get("audio.offload.min.duration.secs", propValue, NULL)) { 2372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) { 2373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue); 2374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) { 2377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS); 2378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not allow offloading if one non offloadable effect is enabled. This prevents from 2382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // creating an offloaded track and tearing it down immediately after start when audioflinger 2383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // detects there is an active non offloadable effect. 2384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FIXME: We should check the audio session here but we do not have it in this context. 2385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // This may prevent offloading in rare situations where effects are left active by apps 2386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the background. 2387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isNonOffloadableEffectEnabled()) { 2388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 2389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 2390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 2391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // See if there is a profile to support this. 2392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // AUDIO_DEVICE_NONE 23931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */, 2394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.sample_rate, 2395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.format, 2396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent offloadInfo.channel_mask, 2397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD); 23981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT "); 23991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return (profile != 0); 2400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 2401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 24026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPorts(audio_port_role_t role, 24036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_type_t type, 24046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent unsigned int *num_ports, 24056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port *ports, 24066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent unsigned int *generation) 24076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 24086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (num_ports == NULL || (*num_ports != 0 && ports == NULL) || 24096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent generation == NULL) { 24106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 24116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports); 24136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (ports == NULL) { 24146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports = 0; 24156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 24176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t portsWritten = 0; 24186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t portsMax = *num_ports; 24196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports = 0; 24206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) { 24216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) { 24226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; 24236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i < mAvailableOutputDevices.size() && portsWritten < portsMax; i++) { 24246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]); 24256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports += mAvailableOutputDevices.size(); 24276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) { 24296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; 24306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i < mAvailableInputDevices.size() && portsWritten < portsMax; i++) { 24316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]); 24326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports += mAvailableInputDevices.size(); 24346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) { 24376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) { 24386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++) { 24396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mInputs[i]->toAudioPort(&ports[portsWritten++]); 24406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_ports += mInputs.size(); 24426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) { 244484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent size_t numOutputs = 0; 244584c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 244684c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent if (!mOutputs[i]->isDuplicated()) { 244784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent numOutputs++; 244884c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent if (portsWritten < portsMax) { 244984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent mOutputs[i]->toAudioPort(&ports[portsWritten++]); 245084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent } 245184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent } 24526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 245384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent *num_ports += numOutputs; 24546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *generation = curAudioPortGeneration(); 2457beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPorts() got %zu ports needed %d", portsWritten, *num_ports); 24586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 24596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 24606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 24616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused) 24626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 24636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 24646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 24656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 24661f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp<AudioPolicyManager::AudioOutputDescriptor> AudioPolicyManager::getOutputFromId( 24676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_handle_t id) const 24686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 24691f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = NULL; 24706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 24716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent outputDesc = mOutputs.valueAt(i); 24726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc->mId == id) { 24736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 24746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return outputDesc; 24776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 24786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 24791f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp<AudioPolicyManager::AudioInputDescriptor> AudioPolicyManager::getInputFromId( 24806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_handle_t id) const 24816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 24821f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = NULL; 24836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 24846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent inputDesc = mInputs.valueAt(i); 24856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (inputDesc->mId == id) { 24866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 24876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 24896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return inputDesc; 24906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 24916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 24921f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleForDevice( 24931f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent audio_devices_t device) const 24946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 24951f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp <HwModule> module; 24961f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 24976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 24986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (mHwModules[i]->mHandle == 0) { 24996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent continue; 25006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (audio_is_output_device(device)) { 25026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 25036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent { 25046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) { 25056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return mHwModules[i]; 25066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 25096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) { 25106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (mHwModules[i]->mInputProfiles[j]->mSupportedDevices.types() & 25116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent device & ~AUDIO_DEVICE_BIT_IN) { 25126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return mHwModules[i]; 25136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25171f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent return module; 25186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 25196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 25201f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentsp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleFromName(const char *name) const 25211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 25221f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp <HwModule> module; 25231f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 25241afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 25251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent { 25261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(mHwModules[i]->mName, name) == 0) { 25271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return mHwModules[i]; 25281afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 25291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 25301f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent return module; 25311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 25321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 2533c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurentaudio_devices_t AudioPolicyManager::availablePrimaryOutputDevices() 2534c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent{ 2535c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput); 2536c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types(); 2537c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent return devices & mAvailableOutputDevices.types(); 2538c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent} 2539c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 2540c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurentaudio_devices_t AudioPolicyManager::availablePrimaryInputDevices() 2541c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent{ 2542c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_module_handle_t primaryHandle = 2543c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent mOutputs.valueFor(mPrimaryOutput)->mProfile->mModule->mHandle; 2544c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent audio_devices_t devices = AUDIO_DEVICE_NONE; 2545c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size(); i++) { 2546c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mAvailableInputDevices[i]->mModule->mHandle == primaryHandle) { 2547c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent devices |= mAvailableInputDevices[i]->mDeviceType; 2548c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 2549c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 2550c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent return devices; 2551c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent} 25521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 25536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, 25546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *handle, 25556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent uid_t uid) 25566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 25576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch()"); 25586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 25596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (handle == NULL || patch == NULL) { 25606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 25616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 25626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks); 25636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2564874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX || 2565874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) { 2566874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return BAD_VALUE; 2567874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2568874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // only one source per audio patch supported for now 2569874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->num_sources > 1) { 25706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 25716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 2572874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 2573874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->sources[0].role != AUDIO_PORT_ROLE_SOURCE) { 25746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 25756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 2576874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent for (size_t i = 0; i < patch->num_sinks; i++) { 2577874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->sinks[i].role != AUDIO_PORT_ROLE_SINK) { 2578874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2579874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2580874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 25816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 25826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc; 25836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(*handle); 25846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 25856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch source id %d role %d type %d", patch->sources[0].id, 25866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sources[0].role, 25876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->sources[0].type); 2588874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent#if LOG_NDEBUG == 0 2589874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent for (size_t i = 0; i < patch->num_sinks; i++) { 2590874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent ALOGV("createAudioPatch sink %d: id %d role %d type %d", i, patch->sinks[i].id, 2591874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->sinks[i].role, 2592874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->sinks[i].type); 2593874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2594874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent#endif 25956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 25966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 25976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 25986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() mUidCached %d patchDesc->mUid %d uid %d", 25996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mUidCached, patchDesc->mUid, uid); 26006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) { 26016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 26026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 26036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 26046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *handle = 0; 26056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 26066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 26076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) { 26081f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id); 26096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc == NULL) { 26106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id); 26116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 26126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 261384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!outputDesc->isDuplicated(),"duplicated output %d in source in ports", 261484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent outputDesc->mIoHandle); 26156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0) { 26166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) { 26176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() source id differs for patch current id %d new id %d", 26186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch.sources[0].id, patch->sources[0].id); 26196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 26206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 26216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 2622874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent DeviceVector devices; 2623874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent for (size_t i = 0; i < patch->num_sinks; i++) { 2624874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // Only support mix to devices connection 2625874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // TODO add support for mix to mix connection 2626874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) { 2627874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent ALOGV("createAudioPatch() source mix but sink is not a device"); 2628874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2629874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2630874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent sp<DeviceDescriptor> devDesc = 2631874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id); 2632874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (devDesc == 0) { 2633874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent ALOGV("createAudioPatch() out device not found for id %d", patch->sinks[i].id); 2634874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return BAD_VALUE; 2635874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 26366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2637874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (!outputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType, 2638275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent devDesc->mAddress, 2639874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->sources[0].sample_rate, 2640874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent NULL, // updatedSamplingRate 2641874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->sources[0].format, 2642874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent patch->sources[0].channel_mask, 2643874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) { 2644874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent ALOGV("createAudioPatch() profile not supported for device %08x", 2645874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent devDesc->mDeviceType); 2646874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2647874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2648874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent devices.add(devDesc); 2649874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2650874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (devices.size() == 0) { 26516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 26526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 2653874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 26546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // TODO: reconfigure output format and channels here 26556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() setting device %08x on output %d", 2656874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent devices.types(), outputDesc->mIoHandle); 2657874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent setOutputDevice(outputDesc->mIoHandle, devices.types(), true, 0, handle); 26586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*handle); 26596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 26606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) { 26616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setOutputDevice() did not reuse the patch provided"); 26626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 26636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 26646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = uid; 26656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() success"); 26666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 26676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setOutputDevice() failed to create a patch"); 26686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 26696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 26706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) { 26716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { 26726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // input device to input mix connection 2673874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // only one sink supported when connecting an input device to a mix 2674874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->num_sinks > 1) { 2675874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2676874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 26771f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id); 26786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (inputDesc == NULL) { 26796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 26806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 26816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0) { 26826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) { 26836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 26846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 26856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 26866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<DeviceDescriptor> devDesc = 26876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices.getDeviceFromId(patch->sources[0].id); 26886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (devDesc == 0) { 26896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 26906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 26916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 269284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent if (!inputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType, 2693275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent devDesc->mAddress, 2694275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent patch->sinks[0].sample_rate, 2695275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent NULL, /*updatedSampleRate*/ 2696275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent patch->sinks[0].format, 2697275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent patch->sinks[0].channel_mask, 2698275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent // FIXME for the parameter type, 2699275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent // and the NONE 2700275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent (audio_output_flags_t) 27016a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten AUDIO_INPUT_FLAG_NONE)) { 27026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 27036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 27046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // TODO: reconfigure output format and channels here 27056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() setting device %08x on output %d", 270684c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent devDesc->mDeviceType, inputDesc->mIoHandle); 2707874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent setInputDevice(inputDesc->mIoHandle, devDesc->mDeviceType, true, handle); 27086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*handle); 27096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 27106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) { 27116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setInputDevice() did not reuse the patch provided"); 27126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 27136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 27146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = uid; 27156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() success"); 27166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 27176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() setInputDevice() failed to create a patch"); 27186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 27196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 27206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) { 27216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // device to device connection 27226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc != 0) { 2723874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) { 27246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 27256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 27266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 27276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<DeviceDescriptor> srcDeviceDesc = 27286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAvailableInputDevices.getDeviceFromId(patch->sources[0].id); 272958f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent if (srcDeviceDesc == 0) { 273058f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent return BAD_VALUE; 273158f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent } 2732874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 27336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent //update source and sink with our own data as the data passed in the patch may 27346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // be incomplete. 27356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_patch newPatch = *patch; 27366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]); 2737874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 2738874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent for (size_t i = 0; i < patch->num_sinks; i++) { 2739874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) { 2740874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent ALOGV("createAudioPatch() source device but one sink is not a device"); 2741874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2742874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2743874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 2744874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent sp<DeviceDescriptor> sinkDeviceDesc = 2745874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id); 2746874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (sinkDeviceDesc == 0) { 2747874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return BAD_VALUE; 2748874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2749874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]); 2750874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent 2751874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (srcDeviceDesc->mModule != sinkDeviceDesc->mModule) { 2752874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // only one sink supported when connected devices across HW modules 2753874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (patch->num_sinks > 1) { 275483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent return INVALID_OPERATION; 275583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent } 2756874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent SortedVector<audio_io_handle_t> outputs = 2757874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent getOutputsForDevice(sinkDeviceDesc->mDeviceType, 2758874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent mOutputs); 2759874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // if the sink device is reachable via an opened output stream, request to go via 2760874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent // this output stream by adding a second source to the patch description 27618838a3895c365d443ee22e169ccf45956780c081Eric Laurent audio_io_handle_t output = selectOutput(outputs, 27628838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_OUTPUT_FLAG_NONE, 27638838a3895c365d443ee22e169ccf45956780c081Eric Laurent AUDIO_FORMAT_INVALID); 2764874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (output != AUDIO_IO_HANDLE_NONE) { 2765874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 2766874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent if (outputDesc->isDuplicated()) { 2767874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent return INVALID_OPERATION; 2768874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 2769874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent outputDesc->toAudioPortConfig(&newPatch.sources[1], &patch->sources[0]); 2770874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent newPatch.num_sources = 2; 2771874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent } 277283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent } 27736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 27746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent // TODO: check from routing capabilities in config file and other conflicting patches 27756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 27766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 27776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 27786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent afPatchHandle = patchDesc->mAfPatchHandle; 27796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 27806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 27816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->createAudioPatch(&newPatch, 27826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &afPatchHandle, 27836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 0); 27846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("createAudioPatch() patch panel returned %d patchHandle %d", 27856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, afPatchHandle); 27866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (status == NO_ERROR) { 27876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 27886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 27896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &newPatch, uid); 27906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent addAudioPatch(patchDesc->mHandle, patchDesc); 27916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 27926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch = newPatch; 27936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 27946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mAfPatchHandle = afPatchHandle; 27956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *handle = patchDesc->mHandle; 27966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 2797b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 27986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 27996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("createAudioPatch() patch panel could not connect device patch, error %d", 28006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status); 28016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 28026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 28036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 28046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 28056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 28066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 28076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 28086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 28096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 28106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 28116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 28126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle, 28136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent uid_t uid) 28146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 28156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() patch %d", handle); 28166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 28176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(handle); 28186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 28196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 28206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 28216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 28226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 28236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() mUidCached %d patchDesc->mUid %d uid %d", 28246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mUidCached, patchDesc->mUid, uid); 28256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) { 28266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return INVALID_OPERATION; 28276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 28286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 28296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_patch *patch = &patchDesc->mPatch; 28306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = mUidCached; 28316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) { 28321f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id); 28336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc == NULL) { 28346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id); 28356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 28366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 28376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 28386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent setOutputDevice(outputDesc->mIoHandle, 28396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent getNewOutputDevice(outputDesc->mIoHandle, true /*fromCache*/), 28406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent true, 28416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 0, 28426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent NULL); 28436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) { 28446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { 28451f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id); 28466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (inputDesc == NULL) { 28476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id); 28486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 28496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 28506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent setInputDevice(inputDesc->mIoHandle, 28516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent getNewInputDevice(inputDesc->mIoHandle), 28526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent true, 28536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent NULL); 28546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) { 28556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = patchDesc->mAfPatchHandle; 28566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 28576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("releaseAudioPatch() patch panel returned %d patchHandle %d", 28586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, patchDesc->mAfPatchHandle); 28596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent removeAudioPatch(patchDesc->mHandle); 28606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 2861b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 28626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 28636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 28646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 28656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 28666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 28676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 28686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 28696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 28706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 28716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches, 28726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_patch *patches, 28736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent unsigned int *generation) 28746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 28756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (num_patches == NULL || (*num_patches != 0 && patches == NULL) || 28766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent generation == NULL) { 28776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return BAD_VALUE; 28786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 2879beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPatches() num_patches %d patches %p available patches %zu", 28806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_patches, patches, mAudioPatches.size()); 28816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patches == NULL) { 28826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_patches = 0; 28836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 28846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 28856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t patchesWritten = 0; 28866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent size_t patchesMax = *num_patches; 28876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; 28886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i < mAudioPatches.size() && patchesWritten < patchesMax; i++) { 28896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patches[patchesWritten] = mAudioPatches[i]->mPatch; 28906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patches[patchesWritten++].id = mAudioPatches[i]->mHandle; 2891beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPatches() patch %zu num_sources %d num_sinks %d", 28926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent i, mAudioPatches[i]->mPatch.num_sources, mAudioPatches[i]->mPatch.num_sinks); 28936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 28946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *num_patches = mAudioPatches.size(); 28956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 28966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *generation = curAudioPortGeneration(); 2897beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("listAudioPatches() got %zu patches needed %d", patchesWritten, *num_patches); 28986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 28996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 29006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2901e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config) 29026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 2903e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("setAudioPortConfig()"); 2904e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2905e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config == NULL) { 2906e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2907e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2908e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent ALOGV("setAudioPortConfig() on port handle %d", config->id); 2909e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent // Only support gain configuration for now 2910a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask != AUDIO_PORT_CONFIG_GAIN) { 2911a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return INVALID_OPERATION; 2912e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2913e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2914a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent sp<AudioPortConfig> audioPortConfig; 2915e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config->type == AUDIO_PORT_TYPE_MIX) { 2916e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config->role == AUDIO_PORT_ROLE_SOURCE) { 29171f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = getOutputFromId(config->id); 2918e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (outputDesc == NULL) { 2919e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2920e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 292184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!outputDesc->isDuplicated(), 292284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent "setAudioPortConfig() called on duplicated output %d", 292384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent outputDesc->mIoHandle); 2924a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig = outputDesc; 2925e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else if (config->role == AUDIO_PORT_ROLE_SINK) { 29261f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = getInputFromId(config->id); 2927e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (inputDesc == NULL) { 2928e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2929e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2930a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig = inputDesc; 2931e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 2932e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2933e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2934e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else if (config->type == AUDIO_PORT_TYPE_DEVICE) { 2935e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent sp<DeviceDescriptor> deviceDesc; 2936e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (config->role == AUDIO_PORT_ROLE_SOURCE) { 2937e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id); 2938e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else if (config->role == AUDIO_PORT_ROLE_SINK) { 2939e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id); 2940e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 2941e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2942e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2943e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent if (deviceDesc == NULL) { 2944e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2945e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2946a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig = deviceDesc; 2947e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } else { 2948e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return BAD_VALUE; 2949e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2950e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2951a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config backupConfig; 2952a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig); 2953a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status == NO_ERROR) { 2954a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config newConfig; 2955a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig->toAudioPortConfig(&newConfig, config); 2956a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status = mpClientInterface->setAudioPortConfig(&newConfig, 0); 2957e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2958a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 2959a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audioPortConfig->applyAudioPortConfig(&backupConfig); 2960e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 2961e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 2962e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent return status; 29636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 29646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 29656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentvoid AudioPolicyManager::clearAudioPatches(uid_t uid) 29666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 29670add0fd07401c507a77b37868f46a2ae587c30dfEric Laurent for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--) { 29686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i); 29696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid == uid) { 29700add0fd07401c507a77b37868f46a2ae587c30dfEric Laurent releaseAudioPatch(mAudioPatches.keyAt(i), uid); 29716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 29726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 29736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 29746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 2975df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentstatus_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session, 2976df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_io_handle_t *ioHandle, 2977df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_devices_t *device) 2978df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 2979df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent *session = (audio_session_t)mpClientInterface->newAudioUniqueId(); 2980df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId(); 2981c73ca6ef04136f28306784ad35f444538f081957Eric Laurent *device = getDeviceAndMixForInputSource(AUDIO_SOURCE_HOTWORD); 2982df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 2983df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mSoundTriggerSessions.add(*session, *ioHandle); 2984df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 2985df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return NO_ERROR; 2986df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 2987df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 2988df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentstatus_t AudioPolicyManager::releaseSoundTriggerSession(audio_session_t session) 2989df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 2990df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ssize_t index = mSoundTriggerSessions.indexOfKey(session); 2991df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (index < 0) { 2992df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGW("acquireSoundTriggerSession() session %d not registered", session); 2993df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return BAD_VALUE; 2994df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 2995df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 2996df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mSoundTriggerSessions.removeItem(session); 2997df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return NO_ERROR; 2998df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 2999df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 30006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::addAudioPatch(audio_patch_handle_t handle, 30016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const sp<AudioPatch>& patch) 30026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 30036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(handle); 30046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 30056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 30066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("addAudioPatch() patch %d already in", handle); 30076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return ALREADY_EXISTS; 30086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 30096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAudioPatches.add(handle, patch); 30106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("addAudioPatch() handle %d af handle %d num_sources %d num_sinks %d source handle %d" 30116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent "sink handle %d", 30126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent handle, patch->mAfPatchHandle, patch->mPatch.num_sources, patch->mPatch.num_sinks, 30136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patch->mPatch.sources[0].id, patch->mPatch.sinks[0].id); 30146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 30156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 30166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 30176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::removeAudioPatch(audio_patch_handle_t handle) 30186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 30196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(handle); 30206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 30216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 30226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGW("removeAudioPatch() patch %d not in", handle); 30236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return ALREADY_EXISTS; 30246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 30256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("removeAudioPatch() handle %d af handle %d", handle, 30266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAudioPatches.valueAt(index)->mAfPatchHandle); 30276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mAudioPatches.removeItemsAt(index); 30286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return NO_ERROR; 30296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 30306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 3031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 3032e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent// AudioPolicyManager 3033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---------------------------------------------------------------------------- 3034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30353a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::nextUniqueId() 30363a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 30373a4311c68348f728558e87b5db67d47605783890Eric Laurent return android_atomic_inc(&mNextUniqueId); 30383a4311c68348f728558e87b5db67d47605783890Eric Laurent} 30393a4311c68348f728558e87b5db67d47605783890Eric Laurent 30406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentuint32_t AudioPolicyManager::nextAudioPortGeneration() 30416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 30426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return android_atomic_inc(&mAudioPortGeneration); 30436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 30446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 3045e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) 3046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : 3047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 3048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent Thread(false), 3049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 3050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPrimaryOutput((audio_io_handle_t)0), 30513b73df74357b33869b39a1d69427673c780bd805Eric Laurent mPhoneState(AUDIO_MODE_NORMAL), 3052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 3053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), 30543a4311c68348f728558e87b5db67d47605783890Eric Laurent mA2dpSuspended(false), 30556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mSpeakerDrcEnabled(false), mNextUniqueId(1), 3056d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi mAudioPortGeneration(1), 3057d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi mBeaconMuteRefCount(0), 3058d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi mBeaconPlayingRefCount(0), 3059d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi mBeaconMuted(false) 3060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 30616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent mUidCached = getuid(); 3062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface = clientInterface; 3063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30643b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) { 30653b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[i] = AUDIO_POLICY_FORCE_NONE; 3066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDefaultOutputDevice = new DeviceDescriptor(String8(""), AUDIO_DEVICE_OUT_SPEAKER); 3069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { 3070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { 3071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("could not load audio policy configuration file, setting defaults"); 3072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent defaultAudioPolicyConfig(); 3073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 30753a4311c68348f728558e87b5db67d47605783890Eric Laurent // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices 3076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // must be done after reading the policy 3078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent initializeVolumeCurves(); 3079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open all output streams needed to access attached devices 30813a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types(); 30823a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN; 3083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) { 3084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 3085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 3086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("could not open HW module %s", mHwModules[i]->mName); 3087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 3088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open all output streams needed to access attached devices 3090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // except for direct output streams that are only opened when they are actually 3091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // required by an app. 30923a4311c68348f728558e87b5db67d47605783890Eric Laurent // This also validates mAvailableOutputDevices list 3093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 3094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 30951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j]; 3096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 30973a4311c68348f728558e87b5db67d47605783890Eric Laurent if (outProfile->mSupportedDevices.isEmpty()) { 30983a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName); 30993a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 31003a4311c68348f728558e87b5db67d47605783890Eric Laurent } 31013a4311c68348f728558e87b5db67d47605783890Eric Laurent 3102d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) { 3103d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent continue; 3104d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent } 310583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent audio_devices_t profileType = outProfile->mSupportedDevices.types(); 310683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if ((profileType & mDefaultOutputDevice->mDeviceType) != AUDIO_DEVICE_NONE) { 310783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent profileType = mDefaultOutputDevice->mDeviceType; 310883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent } else { 3109d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent // chose first device present in mSupportedDevices also part of 3110d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent // outputDeviceTypes 3111d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { 3112d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent profileType = outProfile->mSupportedDevices[k]->mDeviceType; 3113d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent if ((profileType & outputDeviceTypes) != 0) { 3114d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent break; 31153a4311c68348f728558e87b5db67d47605783890Eric Laurent } 3116d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent } 3117d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent } 3118d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent if ((profileType & outputDeviceTypes) == 0) { 3119d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent continue; 3120d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent } 3121d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile); 3122d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent 3123d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent outputDesc->mDevice = profileType; 3124d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 3125d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent config.sample_rate = outputDesc->mSamplingRate; 3126d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent config.channel_mask = outputDesc->mChannelMask; 3127d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent config.format = outputDesc->mFormat; 3128d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; 3129d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent status_t status = mpClientInterface->openOutput(outProfile->mModule->mHandle, 3130d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent &output, 3131d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent &config, 3132d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent &outputDesc->mDevice, 3133d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent String8(""), 3134d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent &outputDesc->mLatency, 3135d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent outputDesc->mFlags); 3136d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent 3137d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent if (status != NO_ERROR) { 3138d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent ALOGW("Cannot open output stream for device %08x on hw module %s", 3139d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent outputDesc->mDevice, 3140d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent mHwModules[i]->mName); 3141d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent } else { 3142d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent outputDesc->mSamplingRate = config.sample_rate; 3143d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent outputDesc->mChannelMask = config.channel_mask; 3144d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent outputDesc->mFormat = config.format; 3145d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent 3146d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { 3147d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType; 3148d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent ssize_t index = 3149d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]); 3150d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent // give a valid ID to an attached device once confirmed it is reachable 3151d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent if ((index >= 0) && (mAvailableOutputDevices[index]->mId == 0)) { 3152d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent mAvailableOutputDevices[index]->mId = nextUniqueId(); 3153d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent mAvailableOutputDevices[index]->mModule = mHwModules[i]; 3154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3156d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent if (mPrimaryOutput == 0 && 3157d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 3158d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent mPrimaryOutput = output; 3159d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent } 3160d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent addOutput(output, outputDesc); 3161d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent setOutputDevice(output, 3162d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent outputDesc->mDevice, 3163d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent true); 3164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 31663a4311c68348f728558e87b5db67d47605783890Eric Laurent // open input streams needed to access attached devices to validate 31673a4311c68348f728558e87b5db67d47605783890Eric Laurent // mAvailableInputDevices list 31683a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 31693a4311c68348f728558e87b5db67d47605783890Eric Laurent { 31701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j]; 31713a4311c68348f728558e87b5db67d47605783890Eric Laurent 31723a4311c68348f728558e87b5db67d47605783890Eric Laurent if (inProfile->mSupportedDevices.isEmpty()) { 31733a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName); 31743a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 31753a4311c68348f728558e87b5db67d47605783890Eric Laurent } 3176d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent // chose first device present in mSupportedDevices also part of 3177d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent // inputDeviceTypes 3178d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent audio_devices_t profileType = AUDIO_DEVICE_NONE; 3179d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { 3180d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent profileType = inProfile->mSupportedDevices[k]->mDeviceType; 3181d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent if (profileType & inputDeviceTypes) { 3182d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent break; 3183d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent } 3184d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent } 3185d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent if ((profileType & inputDeviceTypes) == 0) { 3186d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent continue; 3187d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent } 3188d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile); 3189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3190d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent inputDesc->mInputSource = AUDIO_SOURCE_MIC; 3191d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent inputDesc->mDevice = profileType; 3192d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent 3193fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi // find the address 3194fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType); 3195fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi // the inputs vector must be of size 1, but we don't want to crash here 3196fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress 3197fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi : String8(""); 3198fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi ALOGV(" for input device 0x%x using address %s", profileType, address.string()); 3199fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!"); 3200fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi 3201d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 3202d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent config.sample_rate = inputDesc->mSamplingRate; 3203d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent config.channel_mask = inputDesc->mChannelMask; 3204d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent config.format = inputDesc->mFormat; 3205d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; 3206d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent status_t status = mpClientInterface->openInput(inProfile->mModule->mHandle, 3207d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent &input, 3208d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent &config, 3209d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent &inputDesc->mDevice, 3210fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi address, 3211d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent AUDIO_SOURCE_MIC, 3212d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent AUDIO_INPUT_FLAG_NONE); 3213d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent 3214d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent if (status == NO_ERROR) { 3215d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { 3216d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType; 3217d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent ssize_t index = 3218d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]); 3219d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent // give a valid ID to an attached device once confirmed it is reachable 3220d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent if ((index >= 0) && (mAvailableInputDevices[index]->mId == 0)) { 3221d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent mAvailableInputDevices[index]->mId = nextUniqueId(); 3222d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent mAvailableInputDevices[index]->mModule = mHwModules[i]; 32233a4311c68348f728558e87b5db67d47605783890Eric Laurent } 32243a4311c68348f728558e87b5db67d47605783890Eric Laurent } 3225d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent mpClientInterface->closeInput(input); 3226d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent } else { 3227d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent ALOGW("Cannot open input stream for device %08x on hw module %s", 3228d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent inputDesc->mDevice, 3229d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent mHwModules[i]->mName); 32303a4311c68348f728558e87b5db67d47605783890Eric Laurent } 32313a4311c68348f728558e87b5db67d47605783890Eric Laurent } 32323a4311c68348f728558e87b5db67d47605783890Eric Laurent } 32333a4311c68348f728558e87b5db67d47605783890Eric Laurent // make sure all attached devices have been allocated a unique ID 32343a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableOutputDevices.size();) { 32353a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableOutputDevices[i]->mId == 0) { 32361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mDeviceType); 32373a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.remove(mAvailableOutputDevices[i]); 32383a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 32393a4311c68348f728558e87b5db67d47605783890Eric Laurent } 32403a4311c68348f728558e87b5db67d47605783890Eric Laurent i++; 32413a4311c68348f728558e87b5db67d47605783890Eric Laurent } 32423a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mAvailableInputDevices.size();) { 32433a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableInputDevices[i]->mId == 0) { 32441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mDeviceType); 32453a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.remove(mAvailableInputDevices[i]); 32463a4311c68348f728558e87b5db67d47605783890Eric Laurent continue; 32473a4311c68348f728558e87b5db67d47605783890Eric Laurent } 32483a4311c68348f728558e87b5db67d47605783890Eric Laurent i++; 32493a4311c68348f728558e87b5db67d47605783890Eric Laurent } 32503a4311c68348f728558e87b5db67d47605783890Eric Laurent // make sure default device is reachable 32513a4311c68348f728558e87b5db67d47605783890Eric Laurent if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) { 32521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mDeviceType); 32533a4311c68348f728558e87b5db67d47605783890Eric Laurent } 3254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 3256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 3258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 3260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mPrimaryOutput != 0) { 3261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 3262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"), 0); 3263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 3264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestDevice = AUDIO_DEVICE_OUT_SPEAKER; 3266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestSamplingRate = 44100; 32673b73df74357b33869b39a1d69427673c780bd805Eric Laurent mTestFormat = AUDIO_FORMAT_PCM_16_BIT; 32683b73df74357b33869b39a1d69427673c780bd805Eric Laurent mTestChannels = AUDIO_CHANNEL_OUT_STEREO; 3269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestLatencyMs = 0; 3270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput = 0; 3271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = false; 3272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 3273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestOutputs[i] = 0; 3274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 3277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 3278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 3279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent run(buffer, ANDROID_PRIORITY_AUDIO); 3280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 3282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3284e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::~AudioPolicyManager() 3285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 3287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent exit(); 3288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 3289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 3290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(mOutputs.keyAt(i)); 3291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 3293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeInput(mInputs.keyAt(i)); 3294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 32953a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.clear(); 32963a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.clear(); 32971f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mOutputs.clear(); 32981f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mInputs.clear(); 32991f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mHwModules.clear(); 3300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3302e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::initCheck() 3303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; 3305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST 3308e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::threadLoop() 3309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("entering threadLoop()"); 3311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (!exitPending()) 3312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 command; 3314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int valueInt; 3315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 value; 3316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent Mutex::Autolock _l(mLock); 3318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mWaitWorkCV.waitRelative(mLock, milliseconds(50)); 3319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent command = mpClientInterface->getParameters(0, String8("test_cmd_policy")); 3321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param = AudioParameter(command); 3322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR && 3324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent valueInt != 0) { 3325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("Test command %s received", command.string()); 3326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 target; 3327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("target"), target) != NO_ERROR) { 3328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent target = "Manager"; 3329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) { 3331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_output")); 3332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurOutput = valueInt; 3333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) { 3335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_direct")); 3336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "false") { 3337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = false; 3338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "true") { 3339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDirectOutput = true; 3340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) { 3343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_input")); 3344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestInput = valueInt; 3345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) { 3348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_format")); 33493b73df74357b33869b39a1d69427673c780bd805Eric Laurent int format = AUDIO_FORMAT_INVALID; 3350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "PCM 16 bits") { 33513b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_PCM_16_BIT; 3352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "PCM 8 bits") { 33533b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_PCM_8_BIT; 3354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "Compressed MP3") { 33553b73df74357b33869b39a1d69427673c780bd805Eric Laurent format = AUDIO_FORMAT_MP3; 3356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 33573b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (format != AUDIO_FORMAT_INVALID) { 3358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 3359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestFormat = format; 3360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 3361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 3362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("format"), format); 3363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 3364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) { 3368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_channels")); 3369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int channels = 0; 3370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (value == "Channels Stereo") { 33723b73df74357b33869b39a1d69427673c780bd805Eric Laurent channels = AUDIO_CHANNEL_OUT_STEREO; 3373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (value == "Channels Mono") { 33743b73df74357b33869b39a1d69427673c780bd805Eric Laurent channels = AUDIO_CHANNEL_OUT_MONO; 3375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (channels != 0) { 3377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 3378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestChannels = channels; 3379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 3380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 3381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("channels"), channels); 3382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 3383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) { 3387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_sampleRate")); 3388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (valueInt >= 0 && valueInt <= 96000) { 3389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int samplingRate = valueInt; 3390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (target == "Manager") { 3391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mTestSamplingRate = samplingRate; 3392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (mTestOutputs[mCurOutput] != 0) { 3393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputParam = AudioParameter(); 3394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputParam.addInt(String8("sampling_rate"), samplingRate); 3395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString()); 3396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { 3401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.remove(String8("test_cmd_policy_reopen")); 3402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 34031f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput); 3404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(mPrimaryOutput); 3405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; 3407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(mPrimaryOutput); 3409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 34101f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL); 3411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; 3412cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 3413cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = outputDesc->mSamplingRate; 3414cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = outputDesc->mChannelMask; 3415cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = outputDesc->mFormat; 3416cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status = mpClientInterface->openOutput(moduleHandle, 3417cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &mPrimaryOutput, 3418cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 3419cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mDevice, 3420cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent String8(""), 3421cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &outputDesc->mLatency, 3422cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFlags); 3423cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status != NO_ERROR) { 3424cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent ALOGE("Failed to reopen hardware output stream, " 3425cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent "samplingRate: %d, format %d, channels %d", 3426cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); 3427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3428cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mSamplingRate = config.sample_rate; 3429cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mChannelMask = config.channel_mask; 3430cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent outputDesc->mFormat = config.format; 3431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter outputCmd = AudioParameter(); 3432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputCmd.addInt(String8("set_id"), 0); 3433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); 3434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(mPrimaryOutput, outputDesc); 3435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(0, String8("test_cmd_policy=")); 3440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 3443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3445e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::exit() 3446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AutoMutex _l(mLock); 3449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent requestExit(); 3450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mWaitWorkCV.signal(); 3451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent requestExitAndWait(); 3453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3455e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::testOutputIndex(audio_io_handle_t output) 3456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 3458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (output == mTestOutputs[i]) return i; 3459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 3461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST 3463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- 3465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 34661f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc) 3467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 34681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mIoHandle = output; 34691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mId = nextUniqueId(); 34701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mOutputs.add(output, outputDesc); 34716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 3472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 34741f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc) 3475d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 34761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mIoHandle = input; 34771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mId = nextUniqueId(); 34781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mInputs.add(input, inputDesc); 34796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 3480d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 3481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 34820fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivivoid AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/, 34833190e67d5c80c1e39e3be91784110af1180cd182keunyoung const audio_devices_t device /*in*/, 34840fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi const String8 address /*in*/, 34850fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi SortedVector<audio_io_handle_t>& outputs /*out*/) { 34863190e67d5c80c1e39e3be91784110af1180cd182keunyoung sp<DeviceDescriptor> devDesc = 34873190e67d5c80c1e39e3be91784110af1180cd182keunyoung desc->mProfile->mSupportedDevices.getDevice(device, address); 34883190e67d5c80c1e39e3be91784110af1180cd182keunyoung if (devDesc != 0) { 34893190e67d5c80c1e39e3be91784110af1180cd182keunyoung ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s", 34903190e67d5c80c1e39e3be91784110af1180cd182keunyoung desc->mIoHandle, address.string()); 34913190e67d5c80c1e39e3be91784110af1180cd182keunyoung outputs.add(desc->mIoHandle); 34920fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 34930fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi} 34940fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi 3495f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivistatus_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> devDesc, 34963b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_policy_dev_state_t state, 3497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t>& outputs, 34983a4311c68348f728558e87b5db67d47605783890Eric Laurent const String8 address) 3499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3500f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi audio_devices_t device = devDesc->mDeviceType; 35011f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc; 3502f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi // erase all current sample rates, formats and channel masks 3503f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi devDesc->clearCapabilities(); 3504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 35053b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { 3506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // first list already open outputs that can be routed to this device 3507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 3508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(i); 35093a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) { 35100fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (!deviceDistinguishesOnAddress(device)) { 35110fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i)); 35120fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi outputs.add(mOutputs.keyAt(i)); 35130fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } else { 35140fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV(" checking address match due to device 0x%x", device); 35153190e67d5c80c1e39e3be91784110af1180cd182keunyoung findIoHandlesByAddress(desc, device, address, outputs); 35160fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 3517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // then look for output profiles that can be routed to this device 35201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent SortedVector< sp<IOProfile> > profiles; 3521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 3522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 3524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 3525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 3527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3528275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j]; 3529275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (profile->mSupportedDevices.types() & device) { 3530275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (!deviceDistinguishesOnAddress(device) || 3531275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent address == profile->mSupportedDevices[0]->mAddress) { 3532275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profiles.add(profile); 3533275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i); 3534275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 3535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 35390fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV(" found %d profiles, %d outputs", profiles.size(), outputs.size()); 35400fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi 3541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profiles.isEmpty() && outputs.isEmpty()) { 3542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 3543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 3544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // open outputs for matching profiles if needed. Direct outputs are also opened to 3547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 3548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 35491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = profiles[profile_index]; 3550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // nothing to do if one output is already opened for this profile 3552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent size_t j; 35530fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi for (j = 0; j < outputs.size(); j++) { 35540fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi desc = mOutputs.valueFor(outputs.itemAt(j)); 3555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!desc->isDuplicated() && desc->mProfile == profile) { 3556f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi // matching profile: save the sample rates, format and channel masks supported 3557f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi // by the profile in our device descriptor 3558f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi devDesc->importAudioPort(profile); 3559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 3560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 35620fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (j != outputs.size()) { 3563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 3564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 356683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ALOGV("opening output for device %08x with params %s profile %p", 356783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent device, address.string(), profile.get()); 3568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = new AudioOutputDescriptor(profile); 3569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc->mDevice = device; 3570cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 3571cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = desc->mSamplingRate; 3572cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = desc->mChannelMask; 3573cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = desc->mFormat; 3574cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.sample_rate = desc->mSamplingRate; 3575cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.channel_mask = desc->mChannelMask; 3576cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.format = desc->mFormat; 3577cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; 3578cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status = mpClientInterface->openOutput(profile->mModule->mHandle, 3579cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &output, 3580cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 3581cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &desc->mDevice, 3582cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent address, 3583cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &desc->mLatency, 3584cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mFlags); 3585cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status == NO_ERROR) { 3586cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mSamplingRate = config.sample_rate; 3587cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mChannelMask = config.channel_mask; 3588cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mFormat = config.format; 3589cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent 3590d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where the out_set_parameters() for card & device gets called 35913a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!address.isEmpty()) { 3592cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent char *param = audio_device_address_to_parameter(device, address); 3593cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent mpClientInterface->setParameters(output, String8(param)); 3594cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent free(param); 3595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3597d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where we step through and resolve any "dynamic" fields 3598d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 reply; 3599d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char *value; 3600d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 3601d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 3602d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 36030fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice() supported sampling rates %s", 3604d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 3605d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3606d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 36071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadSamplingRates(value + 1); 3608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3609d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3610d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 3611d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 3612d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 36130fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice() supported formats %s", 3614d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 3615d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3616d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 36171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadFormats(value + 1); 3618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3619d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3620d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 3621d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(output, 3622d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 36230fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice() supported channel masks %s", 3624d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 3625d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3626d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 36271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadOutChannels(value + 1); 3628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3629d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3630d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (((profile->mSamplingRates[0] == 0) && 3631d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mSamplingRates.size() < 2)) || 3632d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) && 3633d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mFormats.size() < 2)) || 3634d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mChannelMasks[0] == 0) && 3635d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent (profile->mChannelMasks.size() < 2))) { 36360fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGW("checkOutputsForDevice() missing param"); 3637d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 3638cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent output = AUDIO_IO_HANDLE_NONE; 36391e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else if (profile->mSamplingRates[0] == 0 || profile->mFormats[0] == 0 || 36401e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent profile->mChannelMasks[0] == 0) { 3641d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 3642cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = profile->pickSamplingRate(); 3643cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = profile->pickChannelMask(); 3644cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = profile->pickFormat(); 3645cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.sample_rate = config.sample_rate; 3646cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.channel_mask = config.channel_mask; 3647cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.offload_info.format = config.format; 3648cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status = mpClientInterface->openOutput(profile->mModule->mHandle, 3649cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &output, 3650cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 3651cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &desc->mDevice, 3652cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent address, 3653cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &desc->mLatency, 3654cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mFlags); 3655cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status == NO_ERROR) { 3656cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mSamplingRate = config.sample_rate; 3657cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mChannelMask = config.channel_mask; 3658cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mFormat = config.format; 3659cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent } else { 3660cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent output = AUDIO_IO_HANDLE_NONE; 3661cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent } 3662d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3663d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3664cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (output != AUDIO_IO_HANDLE_NONE) { 3665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent addOutput(output, desc); 3666275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (deviceDistinguishesOnAddress(device) && address != "0") { 3667275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ssize_t index = mPolicyMixes.indexOfKey(address); 3668275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (index >= 0) { 3669275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mPolicyMixes[index]->mOutput = desc; 3670c722f30eef03e77054395ae122470cf8dba93937Eric Laurent desc->mPolicyMix = &mPolicyMixes[index]->mMix; 3671275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } else { 3672275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGE("checkOutputsForDevice() cannot find policy for address %s", 3673275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent address.string()); 3674275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 3675c722f30eef03e77054395ae122470cf8dba93937Eric Laurent } else if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { 3676c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // no duplicated output for direct outputs and 3677c722f30eef03e77054395ae122470cf8dba93937Eric Laurent // outputs used by dynamic policy mixes 3678cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE; 3679d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3680d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // set initial stream volume for device 3681d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent applyStreamVolumes(output, device, 0, true); 3682d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3683d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent //TODO: configure audio effect output stage here 3684d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3685d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // open a duplicating output thread for the new output and the primary output 3686d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent duplicatedOutput = mpClientInterface->openDuplicateOutput(output, 3687d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mPrimaryOutput); 3688cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) { 3689d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // add duplicated output descriptor 3690cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent sp<AudioOutputDescriptor> dupOutputDesc = 3691cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent new AudioOutputDescriptor(NULL); 3692d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); 3693d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mOutput2 = mOutputs.valueFor(output); 3694d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mSamplingRate = desc->mSamplingRate; 3695d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mFormat = desc->mFormat; 3696d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mChannelMask = desc->mChannelMask; 3697d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent dupOutputDesc->mLatency = desc->mLatency; 3698d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addOutput(duplicatedOutput, dupOutputDesc); 3699d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent applyStreamVolumes(duplicatedOutput, device, 0, true); 3700d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 3701d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkOutputsForDevice() could not open dup output for %d and %d", 3702d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mPrimaryOutput, output); 3703d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeOutput(output); 3704d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mOutputs.removeItem(output); 37056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 3706cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent output = AUDIO_IO_HANDLE_NONE; 3707d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3710cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent } else { 3711cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent output = AUDIO_IO_HANDLE_NONE; 3712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3713cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (output == AUDIO_IO_HANDLE_NONE) { 3714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice() could not open output for device %x", device); 3715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profiles.removeAt(profile_index); 3716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile_index--; 3717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 3718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(output); 3719f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi devDesc->importAudioPort(profile); 3720f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi 37210fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (deviceDistinguishesOnAddress(device)) { 37220fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)", 37230fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi device, address.string()); 37240fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi setOutputDevice(output, device, true/*force*/, 0/*delay*/, 37250fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi NULL/*patch handle*/, address.string()); 37260fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 3727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputsForDevice(): adding output %d", output); 3728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profiles.isEmpty()) { 3732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("checkOutputsForDevice(): No output available for device %04x", device); 3733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return BAD_VALUE; 3734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3735d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { // Disconnect 3736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check if one opened output is not needed any more after disconnecting one device 3737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 3738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent desc = mOutputs.valueAt(i); 37390fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (!desc->isDuplicated()) { 3740275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent // exact match on device 3741275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (deviceDistinguishesOnAddress(device) && 3742275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent (desc->mProfile->mSupportedDevices.types() == device)) { 37433190e67d5c80c1e39e3be91784110af1180cd182keunyoung findIoHandlesByAddress(desc, device, address, outputs); 3744275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } else if (!(desc->mProfile->mSupportedDevices.types() 37450fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi & mAvailableOutputDevices.types())) { 37460fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi ALOGV("checkOutputsForDevice(): disconnecting adding output %d", 37470fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi mOutputs.keyAt(i)); 37480fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi outputs.add(mOutputs.keyAt(i)); 37490fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 3750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3752d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Clear any profiles associated with the disconnected device. 3753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 3754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 3755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 3756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 3757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 3759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 37601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j]; 3761d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSupportedDevices.types() & device) { 3762d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkOutputsForDevice(): " 3763d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent "clearing direct output profile %zu on module %zu", j, i); 3764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mSamplingRates[0] == 0) { 3765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.clear(); 3766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(0); 3767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 3769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.clear(); 3770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 3771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile->mChannelMasks[0] == 0) { 3773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.clear(); 3774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(0); 3775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 3781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 3782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3783d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentstatus_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, 3784d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent audio_policy_dev_state_t state, 3785d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent SortedVector<audio_io_handle_t>& inputs, 3786d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent const String8 address) 3787d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 37881f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> desc; 3789d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { 3790d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // first list already open inputs that can be routed to this device 3791d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 3792d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 3793d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (desc->mProfile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) { 3794d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index)); 3795d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(mInputs.keyAt(input_index)); 3796d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3797d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3798d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3799d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // then look for input profiles that can be routed to this device 38001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent SortedVector< sp<IOProfile> > profiles; 3801d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++) 3802d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent { 3803d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_idx]->mHandle == 0) { 3804d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 3805d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3806d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t profile_index = 0; 3807d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index < mHwModules[module_idx]->mInputProfiles.size(); 3808d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index++) 3809d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent { 3810275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<IOProfile> profile = mHwModules[module_idx]->mInputProfiles[profile_index]; 3811275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 3812275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (profile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) { 3813275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (!deviceDistinguishesOnAddress(device) || 3814275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent address == profile->mSupportedDevices[0]->mAddress) { 3815275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profiles.add(profile); 3816275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGV("checkInputsForDevice(): adding profile %zu from module %zu", 3817275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profile_index, module_idx); 3818275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 3819d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3820d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3821d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3822d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3823d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profiles.isEmpty() && inputs.isEmpty()) { 3824d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 3825d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return BAD_VALUE; 3826d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3827d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3828d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // open inputs for matching profiles if needed. Direct inputs are also opened to 3829d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // query for dynamic parameters and will be closed later by setDeviceConnectionState() 3830d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { 3831d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 38321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = profiles[profile_index]; 3833d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // nothing to do if one input is already opened for this profile 3834d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent size_t input_index; 3835d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (input_index = 0; input_index < mInputs.size(); input_index++) { 3836d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 3837d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (desc->mProfile == profile) { 3838d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent break; 3839d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3840d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3841d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input_index != mInputs.size()) { 3842d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 3843d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3844d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3845d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("opening input for device 0x%X with params %s", device, address.string()); 3846d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = new AudioInputDescriptor(profile); 3847d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc->mDevice = device; 3848cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 3849cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.sample_rate = desc->mSamplingRate; 3850cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.channel_mask = desc->mChannelMask; 3851cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent config.format = desc->mFormat; 3852cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; 3853cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent status_t status = mpClientInterface->openInput(profile->mModule->mHandle, 3854cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &input, 3855cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &config, 3856cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent &desc->mDevice, 3857cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent address, 3858cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent AUDIO_SOURCE_MIC, 3859cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent AUDIO_INPUT_FLAG_NONE /*FIXME*/); 3860d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3861cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (status == NO_ERROR) { 3862cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mSamplingRate = config.sample_rate; 3863cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mChannelMask = config.channel_mask; 3864cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent desc->mFormat = config.format; 3865d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3866d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (!address.isEmpty()) { 3867cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent char *param = audio_device_address_to_parameter(device, address); 3868cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent mpClientInterface->setParameters(input, String8(param)); 3869cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent free(param); 3870d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3871d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3872d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Here is where we step through and resolve any "dynamic" fields 3873d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 reply; 3874d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char *value; 3875d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 3876d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 3877d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); 3878d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup sampling rates %s", 3879d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 3880d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3881d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 38821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadSamplingRates(value + 1); 3883d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3884d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3885d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 3886d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 3887d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); 3888d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string()); 3889d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3890d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 38911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadFormats(value + 1); 3892d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3893d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3894d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 3895d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply = mpClientInterface->getParameters(input, 3896d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); 3897d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice() direct input sup channel masks %s", 3898d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent reply.string()); 3899d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent value = strpbrk((char *)reply.string(), "="); 3900d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (value != NULL) { 39011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent profile->loadInChannels(value + 1); 3902d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3903d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3904d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) || 3905d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) || 3906d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) { 3907d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice() direct input missing param"); 3908d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mpClientInterface->closeInput(input); 3909cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent input = AUDIO_IO_HANDLE_NONE; 3910d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3911d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3912d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (input != 0) { 3913d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent addInput(input, desc); 3914d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3915d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // endif input != 0 3916d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3917cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent if (input == AUDIO_IO_HANDLE_NONE) { 3918d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice() could not open input for device 0x%X", device); 3919d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profiles.removeAt(profile_index); 3920d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index--; 3921d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 3922d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(input); 3923d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): adding input %d", input); 3924d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3925d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end scan profiles 3926d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3927d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profiles.isEmpty()) { 3928d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGW("checkInputsForDevice(): No input available for device 0x%X", device); 3929d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return BAD_VALUE; 3930d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3931d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else { 3932d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Disconnect 3933d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // check if one opened input is not needed any more after disconnecting one device 3934d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { 3935d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent desc = mInputs.valueAt(input_index); 3936ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types() & 3937ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent ~AUDIO_DEVICE_BIT_IN)) { 3938d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV("checkInputsForDevice(): disconnecting adding input %d", 3939d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent mInputs.keyAt(input_index)); 3940d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent inputs.add(mInputs.keyAt(input_index)); 3941d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3942d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3943d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // Clear any profiles associated with the disconnected device. 3944d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) { 3945d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (mHwModules[module_index]->mHandle == 0) { 3946d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent continue; 3947d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3948d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t profile_index = 0; 3949d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index < mHwModules[module_index]->mInputProfiles.size(); 3950d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index++) { 39511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index]; 3952ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent if (profile->mSupportedDevices.types() & device & ~AUDIO_DEVICE_BIT_IN) { 3953beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu", 3954d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile_index, module_index); 3955d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mSamplingRates[0] == 0) { 3956d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mSamplingRates.clear(); 3957d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mSamplingRates.add(0); 3958d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3959d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) { 3960d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mFormats.clear(); 3961d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mFormats.add(AUDIO_FORMAT_DEFAULT); 3962d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3963d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent if (profile->mChannelMasks[0] == 0) { 3964d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mChannelMasks.clear(); 3965d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent profile->mChannelMasks.add(0); 3966d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3967d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3968d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3969d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 3970d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } // end disconnect 3971d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3972d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent return NO_ERROR; 3973d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 3974d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3975d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 3976e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::closeOutput(audio_io_handle_t output) 3977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 3978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("closeOutput(%d)", output); 3979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 39801f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 3981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc == NULL) { 3982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("closeOutput() unknown output %d", output); 3983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 3984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 3985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 3986275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t i = 0; i < mPolicyMixes.size(); i++) { 3987275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (mPolicyMixes[i]->mOutput == outputDesc) { 3988275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mPolicyMixes[i]->mOutput.clear(); 3989275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 3990275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 3991275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 3992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // look for duplicated outputs connected to the output being removed. 3993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 39941f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i); 3995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dupOutputDesc->isDuplicated() && 3996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (dupOutputDesc->mOutput1 == outputDesc || 3997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent dupOutputDesc->mOutput2 == outputDesc)) { 39981f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc2; 3999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (dupOutputDesc->mOutput1 == outputDesc) { 4000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc2 = dupOutputDesc->mOutput2; 4001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc2 = dupOutputDesc->mOutput1; 4003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // As all active tracks on duplicated output will be deleted, 4005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and as they were also referenced on the other output, the reference 4006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // count for their stream type must be adjusted accordingly on 4007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the other output. 40083b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int j = 0; j < AUDIO_STREAM_CNT; j++) { 4009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int refCount = dupOutputDesc->mRefCount[j]; 40103b73df74357b33869b39a1d69427673c780bd805Eric Laurent outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount); 4011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i); 4013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); 4014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(duplicatedOutput); 4016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(duplicatedOutput); 4017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 402005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent nextAudioPortGeneration(); 402105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 402205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); 402305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent if (index >= 0) { 402405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 402505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 402605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mAudioPatches.removeItemsAt(index); 402705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 402805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent } 402905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 4030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param; 4031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent param.add(String8("closing"), String8("true")); 4032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setParameters(output, param.toString()); 4033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->closeOutput(output); 4035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.removeItem(output); 4036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 403705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent} 403805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 403905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurentvoid AudioPolicyManager::closeInput(audio_io_handle_t input) 404005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent{ 404105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent ALOGV("closeInput(%d)", input); 404205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 404305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); 404405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent if (inputDesc == NULL) { 404505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent ALOGW("closeInput() unknown input %d", input); 404605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent return; 404705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent } 404805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 40496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 405005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 405105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 405205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent if (index >= 0) { 405305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 405405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 405505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mAudioPatches.removeItemsAt(index); 405605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 405705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent } 405805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent 405905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mpClientInterface->closeInput(input); 406005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent mInputs.removeItem(input); 4061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4063e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device, 40641f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > openOutputs) 4065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> outputs; 4067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getOutputsForDevice() device %04x", device); 4069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < openOutputs.size(); i++) { 4070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("output %d isDuplicated=%d device=%04x", 4071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices()); 4072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) { 4073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i)); 4074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputs.add(openOutputs.keyAt(i)); 4075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return outputs; 4078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4080e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, 4081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t>& outputs2) 4082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs1.size() != outputs2.size()) { 4084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < outputs1.size(); i++) { 4087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputs1[i] != outputs2[i]) { 4088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 4089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 4092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4094e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy) 4095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); 4097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); 4098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs); 4099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); 4100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4101fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi // also take into account external policy-related changes: add all outputs which are 4102fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi // associated with policies in the "before" and "after" output vectors 4103fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi ALOGVV("checkOutputForStrategy(): policy related outputs"); 4104fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) { 4105fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi const sp<AudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i); 4106fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi if (desc != 0 && desc->mPolicyMix != NULL) { 4107fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi srcOutputs.add(desc->mIoHandle); 4108fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi ALOGVV(" previous outputs: adding %d", desc->mIoHandle); 4109fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi } 4110fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi } 4111fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi for (size_t i = 0 ; i < mOutputs.size() ; i++) { 4112fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi const sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 4113fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi if (desc != 0 && desc->mPolicyMix != NULL) { 4114fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi dstOutputs.add(desc->mIoHandle); 4115fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi ALOGVV(" new outputs: adding %d", desc->mIoHandle); 4116fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi } 4117fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi } 4118fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi 4119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!vectorsEqual(srcOutputs,dstOutputs)) { 4120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", 4121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent strategy, srcOutputs[0], dstOutputs[0]); 4122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute strategy while moving tracks from one output to another 4123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < srcOutputs.size(); i++) { 41241f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]); 4125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->isStrategyActive(strategy)) { 4126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(strategy, true, srcOutputs[i]); 4127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); 4128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Move effects associated to this strategy from previous output to new output 4132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strategy == STRATEGY_MEDIA) { 4133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs); 4134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SortedVector<audio_io_handle_t> moved; 4135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 41361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<EffectDescriptor> effectDesc = mEffects.valueAt(i); 41371f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (effectDesc->mSession == AUDIO_SESSION_OUTPUT_MIX && 41381f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mIo != fxOutput) { 41391f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (moved.indexOf(effectDesc->mIo) < 0) { 4140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkOutputForStrategy() moving effect %d to output %d", 4141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mEffects.keyAt(i), fxOutput); 41421f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo, 4143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent fxOutput); 41441f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent moved.add(effectDesc->mIo); 4145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 41461f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent effectDesc->mIo = fxOutput; 4147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Move tracks associated to this strategy from previous output to new output 41513b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 4152223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if (i == AUDIO_STREAM_PATCH) { 4153223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent continue; 4154223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } 41553b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (getStrategy((audio_stream_type_t)i) == strategy) { 41563b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->invalidateStream((audio_stream_type_t)i); 4157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4162e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForAllStrategies() 4163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4164966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund if (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) 4165966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 4166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_PHONE); 4167966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund if (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) 4168966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE); 4169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION); 4170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 4171223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent checkOutputForStrategy(STRATEGY_ACCESSIBILITY); 4172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_MEDIA); 4173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_DTMF); 4174223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent checkOutputForStrategy(STRATEGY_REROUTING); 4175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4177e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getA2dpOutput() 4178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 41801f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); 4181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 4182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutputs.keyAt(i); 4183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 4187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4189e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkA2dpSuspend() 4190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t a2dpOutput = getA2dpOutput(); 4192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (a2dpOutput == 0) { 41933a4311c68348f728558e87b5db67d47605783890Eric Laurent mA2dpSuspended = false; 4194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 4195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 41973a4311c68348f728558e87b5db67d47605783890Eric Laurent bool isScoConnected = 4198ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent ((mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET & 4199ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent ~AUDIO_DEVICE_BIT_IN) != 0) || 4200ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_ALL_SCO) != 0); 4201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // suspend A2DP output if: 4202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (NOT already suspended) && 4203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ((SCO device is connected && 4204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (forced usage for communication || for record is SCO))) || 4205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (phone state is ringing || in call) 4206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 4207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // restore A2DP output if: 4208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (Already suspended) && 4209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // ((SCO device is NOT connected || 4210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (forced usage NOT for communication && NOT for record is SCO))) && 4211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // (phone state is NOT ringing && NOT in call) 4212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 4213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mA2dpSuspended) { 42143a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((!isScoConnected || 42153b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO) && 42163b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] != AUDIO_POLICY_FORCE_BT_SCO))) && 42173b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mPhoneState != AUDIO_MODE_IN_CALL) && 42183b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mPhoneState != AUDIO_MODE_RINGTONE))) { 4219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->restoreOutput(a2dpOutput); 4221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mA2dpSuspended = false; 4222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 42243a4311c68348f728558e87b5db67d47605783890Eric Laurent if ((isScoConnected && 42253b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) || 42263b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO))) || 42273b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((mPhoneState == AUDIO_MODE_IN_CALL) || 42283b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mPhoneState == AUDIO_MODE_RINGTONE))) { 4229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->suspendOutput(a2dpOutput); 4231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mA2dpSuspended = true; 4232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 42361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentaudio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, bool fromCache) 4237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = AUDIO_DEVICE_NONE; 4239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 42401f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 42416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 42426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); 42436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 42446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 42456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached) { 42466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("getNewOutputDevice() device %08x forced by patch %d", 42476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent outputDesc->device(), outputDesc->mPatchHandle); 42486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return outputDesc->device(); 42496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 42506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 42516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 4252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // check the following by order of priority to request a routing change if necessary: 4253966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund // 1: the strategy enforced audible is active and enforced on the output: 4254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy enforced audible 4255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // 2: we are in call or the strategy phone is active on the output: 4256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy phone 4257966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund // 3: the strategy for enforced audible is active but not enforced on the output: 4258966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund // use the device for strategy enforced audible 4259966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund // 4: the strategy sonification is active on the output: 4260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy sonification 4261966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund // 5: the strategy "respectful" sonification is active on the output: 4262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy "respectful" sonification 4263223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent // 6: the strategy accessibility is active on the output: 4264223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent // use device for strategy accessibility 4265223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent // 7: the strategy media is active on the output: 4266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy media 4267223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent // 8: the strategy DTMF is active on the output: 4268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // use device for strategy DTMF 4269223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output: 4270d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi // use device for strategy t-t-s 4271966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE) && 4272966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { 4273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 4274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (isInCall() || 4275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->isStrategyActive(STRATEGY_PHONE)) { 4276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); 4277966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund } else if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { 4278966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); 4279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) { 4280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); 4281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { 4282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); 4283223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_ACCESSIBILITY)) { 4284223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache); 4285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { 4286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); 4287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { 4288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); 4289d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } else if (outputDesc->isStrategyActive(STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) { 4290d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache); 4291223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } else if (outputDesc->isStrategyActive(STRATEGY_REROUTING)) { 4292223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache); 4293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 42951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("getNewOutputDevice() selected device %x", device); 42961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return device; 42971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 42981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 42991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentaudio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input) 43001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 43011f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); 43026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 43036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 43046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 43056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); 43066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchDesc->mUid != mUidCached) { 43076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ALOGV("getNewInputDevice() device %08x forced by patch %d", 43086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent inputDesc->mDevice, inputDesc->mPatchHandle); 43096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return inputDesc->mDevice; 43106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 43116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 43126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 4313c73ca6ef04136f28306784ad35f444538f081957Eric Laurent audio_devices_t device = getDeviceAndMixForInputSource(inputDesc->mInputSource); 43141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 43151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("getNewInputDevice() selected device %x", device); 4316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 4317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4319e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) { 4320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (uint32_t)getStrategy(stream); 4321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4323e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) { 4324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // By checking the range of stream before calling getStrategy, we avoid 4325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE 4326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and then return STRATEGY_MEDIA, but we want to return the empty set. 4327223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) { 43286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return AUDIO_DEVICE_NONE; 43296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 43306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_devices_t devices; 43316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent AudioPolicyManager::routing_strategy strategy = getStrategy(stream); 43326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent devices = getDeviceForStrategy(strategy, true /*fromCache*/); 43336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs); 43346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < outputs.size(); i++) { 43351f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); 43366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (outputDesc->isStrategyActive(strategy)) { 43376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent devices = outputDesc->device(); 43386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 43396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 4340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 434111c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund 434211c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it 434311c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund and doesn't really need to.*/ 434411c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) { 434511c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund devices |= AUDIO_DEVICE_OUT_SPEAKER; 434611c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund devices &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE; 434711c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund } 434811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund 4349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return devices; 4350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4352e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy( 43533b73df74357b33869b39a1d69427673c780bd805Eric Laurent audio_stream_type_t stream) { 4354223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent 4355223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH"); 4356223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent 4357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // stream to strategy mapping 4358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (stream) { 43593b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_VOICE_CALL: 43603b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_BLUETOOTH_SCO: 4361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_PHONE; 43623b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_RING: 43633b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_ALARM: 4364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_SONIFICATION; 43653b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_NOTIFICATION: 4366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_SONIFICATION_RESPECTFUL; 43673b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_DTMF: 4368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_DTMF; 4369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 4370223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent ALOGE("unknown stream type %d", stream); 43713b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_SYSTEM: 4372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs 4373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while key clicks are played produces a poor result 43743b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_MUSIC: 4375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_MEDIA; 43763b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_ENFORCED_AUDIBLE: 4377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return STRATEGY_ENFORCED_AUDIBLE; 4378d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi case AUDIO_STREAM_TTS: 4379d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi return STRATEGY_TRANSMITTED_THROUGH_SPEAKER; 4380223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent case AUDIO_STREAM_ACCESSIBILITY: 4381223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent return STRATEGY_ACCESSIBILITY; 4382223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent case AUDIO_STREAM_REROUTING: 4383223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent return STRATEGY_REROUTING; 4384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 43875bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviuint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) { 43885bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // flags to strategy mapping 4389d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) { 4390d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi return (uint32_t) STRATEGY_TRANSMITTED_THROUGH_SPEAKER; 4391d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 43925bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { 43935bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_ENFORCED_AUDIBLE; 43945bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 43955bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 43965bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // usage to strategy mapping 43975bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi switch (attr->usage) { 439829e6cecdd8562700ab625c5645ddd6a7753789f1Eric Laurent case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: 439929e6cecdd8562700ab625c5645ddd6a7753789f1Eric Laurent if (isStreamActive(AUDIO_STREAM_RING) || isStreamActive(AUDIO_STREAM_ALARM)) { 440029e6cecdd8562700ab625c5645ddd6a7753789f1Eric Laurent return (uint32_t) STRATEGY_SONIFICATION; 440129e6cecdd8562700ab625c5645ddd6a7753789f1Eric Laurent } 440229e6cecdd8562700ab625c5645ddd6a7753789f1Eric Laurent if (isInCall()) { 440329e6cecdd8562700ab625c5645ddd6a7753789f1Eric Laurent return (uint32_t) STRATEGY_PHONE; 440429e6cecdd8562700ab625c5645ddd6a7753789f1Eric Laurent } 44050f78eabb733e1413d7febd00c0bad0f0add02314Eric Laurent return (uint32_t) STRATEGY_ACCESSIBILITY; 440629e6cecdd8562700ab625c5645ddd6a7753789f1Eric Laurent 44075bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_MEDIA: 44085bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_GAME: 44095bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 44105bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_SONIFICATION: 44115bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_MEDIA; 44125bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 44135bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION: 44145bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_PHONE; 44155bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 44165bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: 44175bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_DTMF; 44185bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 44195bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ALARM: 44205bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: 44215bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_SONIFICATION; 44225bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 44235bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION: 44245bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: 44255bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: 44265bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: 44275bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_EVENT: 44285bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_SONIFICATION_RESPECTFUL; 44295bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 44305bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_UNKNOWN: 44315bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi default: 44325bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return (uint32_t) STRATEGY_MEDIA; 44335bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 44345bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi} 44355bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 4436e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) { 4437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(stream) { 44383b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_STREAM_MUSIC: 4439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); 4440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent updateDevicesAndOutputs(); 4441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 4443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4447d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivibool AudioPolicyManager::isAnyOutputActive(audio_stream_type_t streamToIgnore) { 4448d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { 4449d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi if (s == (size_t) streamToIgnore) { 4450d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi continue; 4451d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4452d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi for (size_t i = 0; i < mOutputs.size(); i++) { 4453d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); 4454d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi if (outputDesc->mRefCount[s] != 0) { 4455d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi return true; 4456d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4457d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4458d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4459d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi return false; 4460d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi} 4461d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi 4462d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Triviuint32_t AudioPolicyManager::handleEventForBeacon(int event) { 4463d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi switch(event) { 4464d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi case STARTING_OUTPUT: 4465d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi mBeaconMuteRefCount++; 4466d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi break; 4467d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi case STOPPING_OUTPUT: 4468d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi if (mBeaconMuteRefCount > 0) { 4469d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi mBeaconMuteRefCount--; 4470d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4471d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi break; 4472d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi case STARTING_BEACON: 4473d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi mBeaconPlayingRefCount++; 4474d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi break; 4475d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi case STOPPING_BEACON: 4476d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi if (mBeaconPlayingRefCount > 0) { 4477d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi mBeaconPlayingRefCount--; 4478d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4479d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi break; 4480d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4481d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi 4482d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi if (mBeaconMuteRefCount > 0) { 4483d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi // any playback causes beacon to be muted 4484d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi return setBeaconMute(true); 4485d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } else { 4486d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi // no other playback: unmute when beacon starts playing, mute when it stops 4487d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi return setBeaconMute(mBeaconPlayingRefCount == 0); 4488d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4489d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi} 4490d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi 4491d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Triviuint32_t AudioPolicyManager::setBeaconMute(bool mute) { 4492d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi ALOGV("setBeaconMute(%d) mBeaconMuteRefCount=%d mBeaconPlayingRefCount=%d", 4493d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi mute, mBeaconMuteRefCount, mBeaconPlayingRefCount); 4494d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi // keep track of muted state to avoid repeating mute/unmute operations 4495d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi if (mBeaconMuted != mute) { 4496d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi // mute/unmute AUDIO_STREAM_TTS on all outputs 4497d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi ALOGV("\t muting %d", mute); 4498d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi uint32_t maxLatency = 0; 4499d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi for (size_t i = 0; i < mOutputs.size(); i++) { 4500d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 4501d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi setStreamMute(AUDIO_STREAM_TTS, mute/*on*/, 4502d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi desc->mIoHandle, 4503d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi 0 /*delay*/, AUDIO_DEVICE_NONE); 4504d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi const uint32_t latency = desc->latency() * 2; 4505d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi if (latency > maxLatency) { 4506d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi maxLatency = latency; 4507d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4508d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4509d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi mBeaconMuted = mute; 4510d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi return maxLatency; 4511d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4512d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi return 0; 4513d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi} 4514d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi 4515e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, 4516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool fromCache) 4517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 4519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (fromCache) { 4521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x", 4522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent strategy, mDeviceForStrategy[strategy]); 4523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mDeviceForStrategy[strategy]; 4524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 45253a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types(); 4526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (strategy) { 4527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4528d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi case STRATEGY_TRANSMITTED_THROUGH_SPEAKER: 4529d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 4530d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi if (!device) { 4531d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi ALOGE("getDeviceForStrategy() no device found for "\ 4532d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi "STRATEGY_TRANSMITTED_THROUGH_SPEAKER"); 4533d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi } 4534d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi break; 4535d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi 4536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_SONIFICATION_RESPECTFUL: 4537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 4538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 45393b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC, 4540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 4541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while media is playing on a remote device, use the the sonification behavior. 4542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Note that we test this usecase before testing if media is playing because 4543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the isStreamActive() method only informs about the activity of a stream, not 4544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if it's for local playback. Note also that we use the same delay between both tests 4545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 454611c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund //user "safe" speaker if available instead of normal speaker to avoid triggering 454711c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund //other acoustic safety mechanisms for notification 454811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) 454911c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund device = AUDIO_DEVICE_OUT_SPEAKER_SAFE; 45503b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { 4551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // while media is playing (or has recently played), use the same device 4552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 4553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 4554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when media is not playing anymore, fall back on the sonification behavior 4555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); 455611c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund //user "safe" speaker if available instead of normal speaker to avoid triggering 455711c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund //other acoustic safety mechanisms for notification 455811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) 455911c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund device = AUDIO_DEVICE_OUT_SPEAKER_SAFE; 4560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_DTMF: 4565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isInCall()) { 4566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when off call, DTMF strategy follows the same rules as MEDIA strategy 4567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); 4568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when in call, DTMF and PHONE strategies follow the same rules 4571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 4572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_PHONE: 4574c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // Force use of only devices on primary output if: 4575c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // - in call AND 4576c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // - cannot route from voice call RX OR 4577c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // - audio HAL version is < 3.0 and TX device is on the primary HW module 4578c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (mPhoneState == AUDIO_MODE_IN_CALL) { 4579c73ca6ef04136f28306784ad35f444538f081957Eric Laurent audio_devices_t txDevice = 4580c73ca6ef04136f28306784ad35f444538f081957Eric Laurent getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION); 4581c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); 4582c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (((mAvailableInputDevices.types() & 4583c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) || 4584c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent (((txDevice & availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN) != 0) && 4585961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen (hwOutputDesc->getAudioPort()->mModule->mHalVersion < 4586c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent AUDIO_DEVICE_API_VERSION_3_0))) { 4587c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent availableOutputDeviceTypes = availablePrimaryOutputDevices(); 4588c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 4589c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 4590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // for phone strategy, we first consider the forced use and then the available devices by order 4591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // of priority 45923b73df74357b33869b39a1d69427673c780bd805Eric Laurent switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) { 45933b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_BT_SCO: 4594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (!isInCall() || strategy != STRATEGY_DTMF) { 45953a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 4596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 45983a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 4599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46003a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; 4601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if SCO device is requested but no SCO device is available, fall back to default case 4603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 4604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: // FORCE_NONE 4606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP 46073a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!isInCall() && 46083b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 460929e6cecdd8562700ab625c5645ddd6a7753789f1Eric Laurent (getA2dpOutput() != 0)) { 46103a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 4611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46123a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 4613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 46153a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 4616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46173a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET; 4618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4619c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 4620c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (device) break; 46213b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mPhoneState != AUDIO_MODE_IN_CALL) { 46223a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 4623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46243a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 4625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46263a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 4627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46283a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 4629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 46313a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE; 4632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 4634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); 4636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 46393b73df74357b33869b39a1d69427673c780bd805Eric Laurent case AUDIO_POLICY_FORCE_SPEAKER: 4640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to 4641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // A2DP speaker when forcing to speaker output 46423a4311c68348f728558e87b5db67d47605783890Eric Laurent if (!isInCall() && 46433b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 464429e6cecdd8562700ab625c5645ddd6a7753789f1Eric Laurent (getA2dpOutput() != 0)) { 46453a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 4646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4648cd71a69d922eab2929faf8f5652fcd1b9a29cbe8Eric Laurent if (!isInCall()) { 46493a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 4650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46513a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 4652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46533a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 4654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46553a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 4656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46573a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 4658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 4659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4660ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_LINE; 4661ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund if (device) break; 46623a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 4663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 46641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 4665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); 4667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_SONIFICATION: 4673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by 4675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // handleIncallSonification(). 4676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isInCall()) { 4677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); 4678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 4681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_ENFORCED_AUDIBLE: 4683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION 4684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // except: 4685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - when in call where it doesn't default to STRATEGY_PHONE behavior 4686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - in countries where not enforced in which case it follows STRATEGY_MEDIA 4687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((strategy == STRATEGY_SONIFICATION) || 46893b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) { 46903a4311c68348f728558e87b5db67d47605783890Eric Laurent device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 4691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); 4693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // The second device used for sonification is the same as the device used by media strategy 4696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // FALL THROUGH 4697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4698223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent // FIXME: STRATEGY_ACCESSIBILITY and STRATEGY_REROUTING follow STRATEGY_MEDIA for now 4699223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent case STRATEGY_ACCESSIBILITY: 4700066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent if (strategy == STRATEGY_ACCESSIBILITY) { 4701066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent // do not route accessibility prompts to a digital output currently configured with a 4702066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent // compressed format as they would likely not be mixed and dropped. 4703066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent for (size_t i = 0; i < mOutputs.size(); i++) { 4704066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); 4705066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent audio_devices_t devices = desc->device() & 4706066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC); 4707066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) && 4708066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent devices != AUDIO_DEVICE_NONE) { 4709066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent availableOutputDeviceTypes = availableOutputDeviceTypes & ~devices; 4710066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent } 4711066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent } 4712066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent } 4713066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent // FALL THROUGH 4714066ceecf4c6ed5ce26c5ddf00d7d9097d560b7a2Eric Laurent 4715223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent case STRATEGY_REROUTING: 4716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case STRATEGY_MEDIA: { 4717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device2 = AUDIO_DEVICE_NONE; 4718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strategy != STRATEGY_SONIFICATION) { 4719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no sonification on remote submix (e.g. WFD) 4720275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) { 4721275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; 4722275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 4723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 47253b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && 472629e6cecdd8562700ab625c5645ddd6a7753789f1Eric Laurent (getA2dpOutput() != 0)) { 47273a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; 4728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 47293a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 4730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 47323a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 4733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4735327cb70dcbf3a1f1679aeafaaa62d8532abea86dHochi Huang if ((device2 == AUDIO_DEVICE_NONE) && 4736327cb70dcbf3a1f1679aeafaaa62d8532abea86dHochi Huang (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) { 4737327cb70dcbf3a1f1679aeafaaa62d8532abea86dHochi Huang device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 4738327cb70dcbf3a1f1679aeafaaa62d8532abea86dHochi Huang } 4739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 47403a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; 4741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4742ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund if ((device2 == AUDIO_DEVICE_NONE)) { 4743ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_LINE; 4744ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund } 4745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 47463a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET; 4747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 47493a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY; 4750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 47523a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; 4753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 47553a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; 4756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { 4758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no sonification on aux digital (e.g. HDMI) 47593a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL; 4760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device2 == AUDIO_DEVICE_NONE) && 47623b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) { 47633a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; 4764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device2 == AUDIO_DEVICE_NONE) { 47663a4311c68348f728558e87b5db67d47605783890Eric Laurent device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; 4767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4768839e4f33906b650140b578d42d6a51300f26703cJungshik Jang int device3 = AUDIO_DEVICE_NONE; 4769839e4f33906b650140b578d42d6a51300f26703cJungshik Jang if (strategy == STRATEGY_MEDIA) { 47707b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang // ARC, SPDIF and AUX_LINE can co-exist with others. 47710c94309d3c6db555b57f2e2e2dc3a0a2676ac6b7Jungshik Jang device3 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_HDMI_ARC; 47720c94309d3c6db555b57f2e2e2dc3a0a2676ac6b7Jungshik Jang device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPDIF); 47737b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_LINE); 4774839e4f33906b650140b578d42d6a51300f26703cJungshik Jang } 4775839e4f33906b650140b578d42d6a51300f26703cJungshik Jang 4776839e4f33906b650140b578d42d6a51300f26703cJungshik Jang device2 |= device3; 4777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or 4778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise 4779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device |= device2; 4780839e4f33906b650140b578d42d6a51300f26703cJungshik Jang 47817b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang // If hdmi system audio mode is on, remove speaker out of output list. 47827b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang if ((strategy == STRATEGY_MEDIA) && 47837b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] == 47847b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) { 47857b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang device &= ~AUDIO_DEVICE_OUT_SPEAKER; 47867b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang } 47877b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang 4788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device) break; 47891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent device = mDefaultOutputDevice->mDeviceType; 4790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 4791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); 4792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } break; 4794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 4796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); 4797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 4798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); 4801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 4802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4804e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::updateDevicesAndOutputs() 4805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_STRATEGIES; i++) { 4807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 4808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mPreviousOutputs = mOutputs; 4810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 48121f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentuint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc, 4813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t prevDevice, 4814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t delayMs) 4815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute/unmute strategies using an incompatible device combination 4817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if muting, wait for the audio in pcm buffer to be drained before proceeding 4818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if unmuting, unmute only after the specified delay 4819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isDuplicated()) { 4820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 4821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs = 0; 4824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device = outputDesc->device(); 48253b73df74357b33869b39a1d69427673c780bd805Eric Laurent bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2); 4826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 4828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); 482931551f8dd625b8d40961e141d2913b0073f852abEric Laurent curDevice = curDevice & outputDesc->mProfile->mSupportedDevices.types(); 4830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool mute = shouldMute && (curDevice & device) && (curDevice != device); 4831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool doMute = false; 4832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mute && !outputDesc->mStrategyMutedByDevice[i]) { 4834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent doMute = true; 4835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = true; 4836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){ 4837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent doMute = true; 4838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mStrategyMutedByDevice[i] = false; 4839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 484099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (doMute) { 4841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mOutputs.size(); j++) { 48421f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j); 4843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // skip output if it does not share any device with current output 4844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((desc->supportedDevices() & outputDesc->supportedDevices()) 4845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent == AUDIO_DEVICE_NONE) { 4846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 4847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t curOutput = mOutputs.keyAt(j); 4849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", 4850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mute ? "muting" : "unmuting", i, curDevice, curOutput); 4851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); 4852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (desc->isStrategyActive((routing_strategy)i)) { 485399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (mute) { 485499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // FIXME: should not need to double latency if volume could be applied 485599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // immediately by the audioflinger mixer. We must account for the delay 485699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // between now and the next time the audioflinger thread for this output 485799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // will process a buffer (which corresponds to one buffer size, 485899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // usually 1/2 or 1/4 of the latency). 485999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (muteWaitMs < desc->latency() * 2) { 486099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs = desc->latency() * 2; 4861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 486899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // temporary mute output if device selection changes to avoid volume bursts due to 486999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // different per device volumes 487099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (outputDesc->isActive() && (device != prevDevice)) { 487199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (muteWaitMs < outputDesc->latency() * 2) { 487299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs = outputDesc->latency() * 2; 487399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 487499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent for (size_t i = 0; i < NUM_STRATEGIES; i++) { 487599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent if (outputDesc->isStrategyActive((routing_strategy)i)) { 48761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setStrategyMute((routing_strategy)i, true, outputDesc->mIoHandle); 487799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent // do tempMute unmute after twice the mute wait time 48781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent setStrategyMute((routing_strategy)i, false, outputDesc->mIoHandle, 487999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent muteWaitMs *2, device); 488099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 488199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 488299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent } 488399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent 4884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // wait for the PCM output buffers to empty before proceeding with the rest of the command 4885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (muteWaitMs > delayMs) { 4886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs -= delayMs; 4887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent usleep(muteWaitMs * 1000); 4888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 4889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 4891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 4892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4893e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output, 4894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 4895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force, 48966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent int delayMs, 48970fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi audio_patch_handle_t *patchHandle, 48980fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi const char* address) 4899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 4900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); 49011f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 4902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AudioParameter param; 4903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t muteWaitMs; 4904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->isDuplicated()) { 49061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent muteWaitMs = setOutputDevice(outputDesc->mOutput1->mIoHandle, device, force, delayMs); 49071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent muteWaitMs += setOutputDevice(outputDesc->mOutput2->mIoHandle, device, force, delayMs); 4908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 4909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current 4911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // output profile 4912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device != AUDIO_DEVICE_NONE) && 49133a4311c68348f728558e87b5db67d47605783890Eric Laurent ((device & outputDesc->mProfile->mSupportedDevices.types()) == 0)) { 4914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 4915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // filter devices according to output selected 49183a4311c68348f728558e87b5db67d47605783890Eric Laurent device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices.types()); 4919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t prevDevice = outputDesc->mDevice; 4921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() prevDevice %04x", prevDevice); 4923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device != AUDIO_DEVICE_NONE) { 4925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mDevice = device; 4926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); 4928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Do not change the routing if: 4930b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent // the requested device is AUDIO_DEVICE_NONE 4931b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent // OR the requested device is the same as current device 4932b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent // AND force is not specified 4933b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent // AND the output is connected by a valid audio patch. 4934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Doing this check here allows the caller to call setOutputDevice() without conditions 4935b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force && 4936b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent outputDesc->mPatchHandle != 0) { 4937b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent ALOGV("setOutputDevice() setting same device %04x or null device for output %d", 4938b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent device, output); 4939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 4940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 4941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 4942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setOutputDevice() changing device"); 49431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 4944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do the routing 49451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (device == AUDIO_DEVICE_NONE) { 49466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent resetOutputDevice(output, delayMs, NULL); 49471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 49480fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi DeviceVector deviceList = (address == NULL) ? 49490fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi mAvailableOutputDevices.getDevicesFromType(device) 49500fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi : mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address)); 49511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (!deviceList.isEmpty()) { 49521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_patch patch; 49531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->toAudioPortConfig(&patch.sources[0]); 49541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sources = 1; 49551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks = 0; 49561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) { 49571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]); 49581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks++; 49591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 49606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 49616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) { 49626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 49636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 49646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); 49656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 49666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc; 49676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 49686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 49696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 49706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent afPatchHandle = patchDesc->mAfPatchHandle; 49716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 49726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 49731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = mpClientInterface->createAudioPatch(&patch, 49746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &afPatchHandle, 49756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent delayMs); 49761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d" 49771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent "num_sources %d num_sinks %d", 49786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, afPatchHandle, patch.num_sources, patch.num_sinks); 49791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (status == NO_ERROR) { 49806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 49816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 49826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &patch, mUidCached); 49836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent addAudioPatch(patchDesc->mHandle, patchDesc); 49846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 49856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch = patch; 49866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 49876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mAfPatchHandle = afPatchHandle; 49886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = mUidCached; 49896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 49906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *patchHandle = patchDesc->mHandle; 49916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 49926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent outputDesc->mPatchHandle = patchDesc->mHandle; 49936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 4994b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 49951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 49961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 4997f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu 4998f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu // inform all input as well 4999f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu for (size_t i = 0; i < mInputs.size(); i++) { 5000f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i); 5001f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu if (!isVirtualInputDevice(inputDescriptor->mDevice)) { 5002f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu AudioParameter inputCmd = AudioParameter(); 5003f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu ALOGV("%s: inform input %d of device:%d", __func__, 5004f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu inputDescriptor->mIoHandle, device); 5005f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu inputCmd.addInt(String8(AudioParameter::keyRouting),device); 5006f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu mpClientInterface->setParameters(inputDescriptor->mIoHandle, 5007f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu inputCmd.toString(), 5008f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu delayMs); 5009f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu } 5010f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu } 50111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 5012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // update stream volumes according to new device 5014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent applyStreamVolumes(output, device, delayMs); 5015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return muteWaitMs; 5017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 50191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output, 50206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent int delayMs, 50216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *patchHandle) 50221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 50231f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 50246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 50256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 50266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 50276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 50286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); 50296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 50306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 50311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return INVALID_OPERATION; 50321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 50336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index); 50346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, delayMs); 50351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status); 50361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent outputDesc->mPatchHandle = 0; 50376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent removeAudioPatch(patchDesc->mHandle); 50386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 5039b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 50401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 50411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 50421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 50431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::setInputDevice(audio_io_handle_t input, 50441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t device, 50456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent bool force, 50466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *patchHandle) 50471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 50481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 50491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 50501f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); 50511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) { 50521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mDevice = device; 50531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 50541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device); 50551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (!deviceList.isEmpty()) { 50561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_patch patch; 50571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->toAudioPortConfig(&patch.sinks[0]); 5058daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent // AUDIO_SOURCE_HOTWORD is for internal use only: 5059daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent // handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL 5060df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD && 5061df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent !inputDesc->mIsSoundTrigger) { 5062daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION; 5063daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent } 50641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sinks = 1; 50651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent //only one input device for now 50661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]); 50671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent patch.num_sources = 1; 50686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 50696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) { 50706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 50716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 50726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 50736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 50746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc; 50756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE; 50766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index >= 0) { 50776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = mAudioPatches.valueAt(index); 50786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent afPatchHandle = patchDesc->mAfPatchHandle; 50796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 50806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 50811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = mpClientInterface->createAudioPatch(&patch, 50826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &afPatchHandle, 50831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 0); 50841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d", 50856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status, afPatchHandle); 50861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (status == NO_ERROR) { 50876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 50886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(), 50896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent &patch, mUidCached); 50906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent addAudioPatch(patchDesc->mHandle, patchDesc); 50916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 50926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mPatch = patch; 50936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 50946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mAfPatchHandle = afPatchHandle; 50956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent patchDesc->mUid = mUidCached; 50966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 50976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent *patchHandle = patchDesc->mHandle; 50986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 50996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent inputDesc->mPatchHandle = patchDesc->mHandle; 51006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 5101b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 51021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 51061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 51071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 51086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input, 51096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_patch_handle_t *patchHandle) 51101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 51111f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); 51126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent ssize_t index; 51136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (patchHandle) { 51146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(*patchHandle); 51156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } else { 51166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); 51176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 51186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (index < 0) { 51191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return INVALID_OPERATION; 51201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 51216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index); 51226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0); 51231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("resetInputDevice() releaseAudioPatch returned %d", status); 51241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent inputDesc->mPatchHandle = 0; 51256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent removeAudioPatch(patchDesc->mHandle); 51266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent nextAudioPortGeneration(); 5127b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent mpClientInterface->onAudioPatchListUpdate(); 51281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 51291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 51301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 51311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device, 5132275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent String8 address, 5133cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten uint32_t& samplingRate, 5134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_format_t format, 51356a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten audio_channel_mask_t channelMask, 5136cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten audio_input_flags_t flags) 5137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Choose an input profile based on the requested capture parameters: select the first available 5139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // profile supporting all requested parameters. 5140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mHwModules.size(); i++) 5142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 5143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mHwModules[i]->mHandle == 0) { 5144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent continue; 5145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 5147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { 51481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j]; 5149d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent // profile->log(); 5150275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (profile->isCompatibleProfile(device, address, samplingRate, 5151cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten &samplingRate /*updatedSamplingRate*/, 5152cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten format, channelMask, (audio_output_flags_t) flags)) { 5153275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 5154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return profile; 5155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NULL; 5159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5161c73ca6ef04136f28306784ad35f444538f081957Eric Laurent 5162c73ca6ef04136f28306784ad35f444538f081957Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource, 5163c722f30eef03e77054395ae122470cf8dba93937Eric Laurent AudioMix **policyMix) 5164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 51653a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & 51663a4311c68348f728558e87b5db67d47605783890Eric Laurent ~AUDIO_DEVICE_BIT_IN; 5167275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 5168275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t i = 0; i < mPolicyMixes.size(); i++) { 5169275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (mPolicyMixes[i]->mMix.mMixType != MIX_TYPE_RECORDERS) { 5170275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent continue; 5171275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 5172275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t j = 0; j < mPolicyMixes[i]->mMix.mCriteria.size(); j++) { 5173275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if ((RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET == mPolicyMixes[i]->mMix.mCriteria[j].mRule && 5174275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mPolicyMixes[i]->mMix.mCriteria[j].mAttr.mSource == inputSource) || 5175275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent (RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET == mPolicyMixes[i]->mMix.mCriteria[j].mRule && 5176275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mPolicyMixes[i]->mMix.mCriteria[j].mAttr.mSource != inputSource)) { 5177275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { 5178c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (policyMix != NULL) { 5179c722f30eef03e77054395ae122470cf8dba93937Eric Laurent *policyMix = &mPolicyMixes[i]->mMix; 5180275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 5181275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return AUDIO_DEVICE_IN_REMOTE_SUBMIX; 5182275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 5183275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 5184275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 5185275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 5186275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 5187275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 5188c73ca6ef04136f28306784ad35f444538f081957Eric Laurent return getDeviceForInputSource(inputSource); 5189c73ca6ef04136f28306784ad35f444538f081957Eric Laurent} 5190c73ca6ef04136f28306784ad35f444538f081957Eric Laurent 5191c73ca6ef04136f28306784ad35f444538f081957Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource) 5192c73ca6ef04136f28306784ad35f444538f081957Eric Laurent{ 5193c73ca6ef04136f28306784ad35f444538f081957Eric Laurent uint32_t device = AUDIO_DEVICE_NONE; 5194c73ca6ef04136f28306784ad35f444538f081957Eric Laurent audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & 5195c73ca6ef04136f28306784ad35f444538f081957Eric Laurent ~AUDIO_DEVICE_BIT_IN; 5196c73ca6ef04136f28306784ad35f444538f081957Eric Laurent 5197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch (inputSource) { 5198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_UPLINK: 51993a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { 5200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 5201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5203c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 5204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_DEFAULT: 5206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_MIC: 520741b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) { 520841b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP; 5209dc136ffee31f21da3b31240f8a22d4d08a658d0dEric Laurent } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) && 5210dc136ffee31f21da3b31240f8a22d4d08a658d0dEric Laurent (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) { 5211dc136ffee31f21da3b31240f8a22d4d08a658d0dEric Laurent device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 5212c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { 5213c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_WIRED_HEADSET; 5214c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { 5215c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_USB_DEVICE; 5216c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 5217c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 521841b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood } 5219c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 5220c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 5221c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent case AUDIO_SOURCE_VOICE_COMMUNICATION: 5222c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // Allow only use of devices on primary input if in call and HAL does not support routing 5223c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // to voice call path. 5224c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if ((mPhoneState == AUDIO_MODE_IN_CALL) && 5225c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent (mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) { 5226c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent availableDeviceTypes = availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN; 5227c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 5228c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 5229c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) { 5230c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent case AUDIO_POLICY_FORCE_BT_SCO: 5231c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // if SCO device is requested but no SCO device is available, fall back to default case 5232c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 5233c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 5234c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 5235c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 5236c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent // FALL THROUGH 5237c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 5238c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent default: // FORCE_NONE 5239c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { 5240c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_WIRED_HEADSET; 5241c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { 5242c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_USB_DEVICE; 5243c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 5244c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 5245c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 5246c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 5247c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent 5248c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent case AUDIO_POLICY_FORCE_SPEAKER: 5249c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) { 5250c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_BACK_MIC; 5251c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 5252c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 5253c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 5254c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 5255c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent } 5256c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent break; 525741b0e2421a0cf8dc22f224ea078678d7db651bdaMike Lockwood 5258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_RECOGNITION: 5259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_HOTWORD: 52603b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO && 52613a4311c68348f728558e87b5db67d47605783890Eric Laurent availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 5262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; 52633a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { 5264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_WIRED_HEADSET; 5265d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { 5266d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent device = AUDIO_DEVICE_IN_USB_DEVICE; 52673a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 5268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 5269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_CAMCORDER: 52723a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) { 5273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BACK_MIC; 52743a4311c68348f728558e87b5db67d47605783890Eric Laurent } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { 5275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_BUILTIN_MIC; 5276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_DOWNLINK: 5279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_VOICE_CALL: 52803a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { 5281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_VOICE_CALL; 5282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_SOURCE_REMOTE_SUBMIX: 52853a4311c68348f728558e87b5db67d47605783890Eric Laurent if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { 5286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; 5287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5289327cb70dcbf3a1f1679aeafaaa62d8532abea86dHochi Huang case AUDIO_SOURCE_FM_TUNER: 5290327cb70dcbf3a1f1679aeafaaa62d8532abea86dHochi Huang if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) { 5291327cb70dcbf3a1f1679aeafaaa62d8532abea86dHochi Huang device = AUDIO_DEVICE_IN_FM_TUNER; 5292327cb70dcbf3a1f1679aeafaaa62d8532abea86dHochi Huang } 5293327cb70dcbf3a1f1679aeafaaa62d8532abea86dHochi Huang break; 5294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 5295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); 5296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent break; 5297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); 5299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 5300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5302e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device) 5303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & AUDIO_DEVICE_BIT_IN) != 0) { 5305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device &= ~AUDIO_DEVICE_BIT_IN; 5306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) 5307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 5308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 5310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 53120fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivibool AudioPolicyManager::deviceDistinguishesOnAddress(audio_devices_t device) { 5313275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return ((device & APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL & ~AUDIO_DEVICE_BIT_IN) != 0); 53140fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi} 53150fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi 5316e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs) 5317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 53191f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioInputDescriptor> input_descriptor = mInputs.valueAt(i); 5320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((input_descriptor->mRefCount > 0) 5321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) { 5322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mInputs.keyAt(i); 5323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0; 5326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5328df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentuint32_t AudioPolicyManager::activeInputsCount() const 5329df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 5330df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent uint32_t count = 0; 5331df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 5332df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent const sp<AudioInputDescriptor> desc = mInputs.valueAt(i); 5333df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (desc->mRefCount > 0) { 5334a34c9ce292ea984e92d8f70d2c056e5372c4f452Eric Laurent count++; 5335df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 5336df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 5337df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return count; 5338df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 5339df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 5340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5341e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device) 5342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 5344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this happens when forcing a route update and no track is active on an output. 5345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // In this case the returned category is not important. 5346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 53473b73df74357b33869b39a1d69427673c780bd805Eric Laurent } else if (popcount(device) > 1) { 5348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Multiple device selection is either: 5349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - speaker + one other device: give priority to speaker in this case. 5350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - one A2DP device + another device: happens with duplicated output. In this case 5351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // retain the device on the A2DP output as the other must not correspond to an active 5352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // selection if not the speaker. 5353a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang // - HDMI-CEC system audio mode only output: give priority to available item in order. 5354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device & AUDIO_DEVICE_OUT_SPEAKER) { 5355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_SPEAKER; 5356a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang } else if (device & AUDIO_DEVICE_OUT_HDMI_ARC) { 5357a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang device = AUDIO_DEVICE_OUT_HDMI_ARC; 5358a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang } else if (device & AUDIO_DEVICE_OUT_AUX_LINE) { 5359a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang device = AUDIO_DEVICE_OUT_AUX_LINE; 5360a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang } else if (device & AUDIO_DEVICE_OUT_SPDIF) { 5361a1f9917243caafd1da5fa743c6fda1d0614ed167Jungshik Jang device = AUDIO_DEVICE_OUT_SPDIF; 5362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); 5364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 536711c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund /*SPEAKER_SAFE is an alias of SPEAKER for purposes of volume control*/ 536811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund if (device == AUDIO_DEVICE_OUT_SPEAKER_SAFE) 536911c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund device = AUDIO_DEVICE_OUT_SPEAKER; 537011c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund 53713b73df74357b33869b39a1d69427673c780bd805Eric Laurent ALOGW_IF(popcount(device) != 1, 5372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent "getDeviceForVolume() invalid device combination: %08x", 5373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device); 5374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 5376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5378e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device) 5379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent switch(getDeviceForVolume(device)) { 5381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 5382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_EARPIECE; 5383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 5384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 5385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: 5386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: 5387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: 5388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 5389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_HEADSET; 5390ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund case AUDIO_DEVICE_OUT_LINE: 5391ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund case AUDIO_DEVICE_OUT_AUX_DIGITAL: 5392ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund /*USB? Remote submix?*/ 5393ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund return DEVICE_CATEGORY_EXT_MEDIA; 5394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 5395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: 5396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: 5397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_USB_ACCESSORY: 5398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_USB_DEVICE: 5399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent case AUDIO_DEVICE_OUT_REMOTE_SUBMIX: 5400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent default: 5401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return DEVICE_CATEGORY_SPEAKER; 5402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5405223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent/* static */ 5406e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, 5407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int indexInUi) 5408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device_category deviceCategory = getDeviceCategory(device); 5410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; 5411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // the volume index in the UI is relative to the min and max volume indices for this stream type 5413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int nbSteps = 1 + curve[VOLMAX].mIndex - 5414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[VOLMIN].mIndex; 5415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / 5416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (streamDesc.mIndexMax - streamDesc.mIndexMin); 5417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // find what part of the curve this index volume belongs to, or if it's out of bounds 5419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int segment = 0; 5420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volIdx < curve[VOLMIN].mIndex) { // out of bounds 5421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 0.0f; 5422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx < curve[VOLKNEE1].mIndex) { 5423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 0; 5424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx < curve[VOLKNEE2].mIndex) { 5425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 1; 5426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (volIdx <= curve[VOLMAX].mIndex) { 5427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent segment = 2; 5428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { // out of bounds 5429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return 1.0f; 5430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // linear interpolation in the attenuation table in dB 5433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float decibels = curve[segment].mDBAttenuation + 5434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((float)(volIdx - curve[segment].mIndex)) * 5435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ( (curve[segment+1].mDBAttenuation - 5436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mDBAttenuation) / 5437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((float)(curve[segment+1].mIndex - 5438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mIndex)) ); 5439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) 5441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", 5443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mIndex, volIdx, 5444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment+1].mIndex, 5445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment].mDBAttenuation, 5446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent decibels, 5447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent curve[segment+1].mDBAttenuation, 5448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent amplification); 5449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return amplification; 5451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5453e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 5454e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultVolumeCurve[AudioPolicyManager::VOLCNT] = { 5455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} 5456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 5457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5458e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 5459e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { 5460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} 5461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 5462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5463e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 5464ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund AudioPolicyManager::sExtMediaSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 5465ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund {1, -58.0f}, {20, -40.0f}, {60, -21.0f}, {100, -10.0f} 5466ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund}; 5467ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund 5468ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklundconst AudioPolicyManager::VolumeCurvePoint 5469e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { 5470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} 5471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 5472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5473e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 5474ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi AudioPolicyManager::sSpeakerMediaVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 547598c6043e089743355bb6686176877f2ba5125213Jean-Michel Trivi {1, -55.0f}, {20, -43.0f}, {86, -12.0f}, {100, 0.0f} 5476ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi}; 5477ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi 5478ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Triviconst AudioPolicyManager::VolumeCurvePoint 5479e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = { 5480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} 5481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 5482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5483e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 5484e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 5485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f} 5486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 5487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks 5489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets. 5490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java). 5491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset. 5492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5493e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 5494e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 5495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f} 5496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 5497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5498e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 5499e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT] = { 5500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f} 5501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 5502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5503e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 5504e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { 5505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f} 5506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 5507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5508e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 5509e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { 5510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f} 5511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 5512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5513e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 5514e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent AudioPolicyManager::sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { 5515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f} 5516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 5517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5518e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint 5519d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi AudioPolicyManager::sLinearVolumeCurve[AudioPolicyManager::VOLCNT] = { 5520d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi {0, -96.0f}, {33, -68.0f}, {66, -34.0f}, {100, 0.0f} 5521d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi}; 5522d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi 5523d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Triviconst AudioPolicyManager::VolumeCurvePoint 5524d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi AudioPolicyManager::sSilentVolumeCurve[AudioPolicyManager::VOLCNT] = { 5525d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi {0, -96.0f}, {1, -96.0f}, {2, -96.0f}, {100, -96.0f} 5526d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi}; 5527d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi 5528d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Triviconst AudioPolicyManager::VolumeCurvePoint 5529223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent AudioPolicyManager::sFullScaleVolumeCurve[AudioPolicyManager::VOLCNT] = { 5530223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent {0, 0.0f}, {1, 0.0f}, {2, 0.0f}, {100, 0.0f} 5531223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent}; 5532223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent 5533223fd5c9738e9665e495904d37d4632414b68c1eEric Laurentconst AudioPolicyManager::VolumeCurvePoint 5534e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT] 5535e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent [AudioPolicyManager::DEVICE_CATEGORY_CNT] = { 5536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_VOICE_CALL 5537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 5538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5539ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5540ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 5542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_SYSTEM 5543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 5544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5545ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5546ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 5548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_RING 5549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 5550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5551ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5552ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 5554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_MUSIC 5555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 5556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5557ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5558ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 5560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_ALARM 5561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 5562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5563ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5564ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 5566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_NOTIFICATION 5567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET 5568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5569ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5570ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 5572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_BLUETOOTH_SCO 5573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET 5574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5575ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5576ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 5578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_ENFORCED_AUDIBLE 5579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 5580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5581ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5582ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 5584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_DTMF 5585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET 5586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5587ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5588ac29afacbb34b92f1948188e5353fce5a252ccb3Jon Eklund sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 5590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent { // AUDIO_STREAM_TTS 5591d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi // "Transmitted Through Speaker": always silent except on DEVICE_CATEGORY_SPEAKER 5592d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi sSilentVolumeCurve, // DEVICE_CATEGORY_HEADSET 5593d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi sLinearVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5594d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi sSilentVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5595d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi sSilentVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent }, 5597223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent { // AUDIO_STREAM_ACCESSIBILITY 5598223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET 5599223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5600223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5601223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5602223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent }, 5603223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent { // AUDIO_STREAM_REROUTING 5604223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET 5605223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5606223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5607223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sFullScaleVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5608223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent }, 5609223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent { // AUDIO_STREAM_PATCH 5610223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET 5611223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER 5612223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE 5613223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sFullScaleVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA 5614223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent }, 5615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; 5616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5617e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initializeVolumeCurves() 5618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 5620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { 5621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[i].mVolumeCurve[j] = 5622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sVolumeProfiles[i][j]; 5623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Check availability of DRC on speaker path: if available, override some of the speaker curves 5627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mSpeakerDrcEnabled) { 5628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 5629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sDefaultSystemVolumeCurveDrc; 5630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 5631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 5632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 5633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 5634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 5635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sSpeakerSonificationVolumeCurveDrc; 5636ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi mStreams[AUDIO_STREAM_MUSIC].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 5637ccd8e4a9da4d0bcc2c715452c5a18fabb23f86acJean-Michel Trivi sSpeakerMediaVolumeCurveDrc; 5638223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent mStreams[AUDIO_STREAM_ACCESSIBILITY].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = 5639223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent sSpeakerMediaVolumeCurveDrc; 5640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5643e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::computeVolume(audio_stream_type_t stream, 5644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 5645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 5646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 5647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float volume = 1.0; 56491f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 5650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent StreamDescriptor &streamDesc = mStreams[stream]; 5651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 5653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = outputDesc->device(); 5654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume = volIndexToAmpl(device, streamDesc, index); 5657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if a headset is connected, apply the following rules to ring tones and notifications 5659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // to avoid sound level bursts in user's ears: 5660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - always attenuate ring tones and notifications volume by 6dB 5661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - if music is playing, always limit the volume to current music volume, 5662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // with a minimum threshold at -36dB so that notification is always perceived. 56633b73df74357b33869b39a1d69427673c780bd805Eric Laurent const routing_strategy stream_strategy = getStrategy(stream); 5664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | 5665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 5666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADSET | 5667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) && 5668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((stream_strategy == STRATEGY_SONIFICATION) 5669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) 56703b73df74357b33869b39a1d69427673c780bd805Eric Laurent || (stream == AUDIO_STREAM_SYSTEM) 5671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) && 56723b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) && 5673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent streamDesc.mCanBeMuted) { 5674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; 5675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // when the phone is ringing we must consider that music could have been paused just before 5676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // by the music application and behave as if music was active if the last music track was 5677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // just stopped 56783b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || 5679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLimitRingtoneVolume) { 5680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/); 56813b73df74357b33869b39a1d69427673c780bd805Eric Laurent float musicVol = computeVolume(AUDIO_STREAM_MUSIC, 56823b73df74357b33869b39a1d69427673c780bd805Eric Laurent mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice), 5683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 5684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent musicDevice); 5685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? 5686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent musicVol : SONIFICATION_HEADSET_VOLUME_MIN; 5687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volume > minVol) { 5688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent volume = minVol; 5689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); 5690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return volume; 5695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5697e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream, 5698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int index, 5699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 5700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 5701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 5702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force) 5703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not change actual stream volume if the stream is muted 5706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { 5707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkAndSetVolume() stream %d muted count %d", 5708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, mOutputs.valueFor(output)->mMuteCount[stream]); 5709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 5710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // do not change in call volume if bluetooth is connected and vice versa 57133b73df74357b33869b39a1d69427673c780bd805Eric Laurent if ((stream == AUDIO_STREAM_VOICE_CALL && 57143b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) || 57153b73df74357b33869b39a1d69427673c780bd805Eric Laurent (stream == AUDIO_STREAM_BLUETOOTH_SCO && 57163b73df74357b33869b39a1d69427673c780bd805Eric Laurent mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO)) { 5717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", 57183b73df74357b33869b39a1d69427673c780bd805Eric Laurent stream, mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]); 5719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return INVALID_OPERATION; 5720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float volume = computeVolume(stream, index, output, device); 5723275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent // unit gain if rerouting to external policy 5724275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) { 5725275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ssize_t index = mOutputs.indexOfKey(output); 5726275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (index >= 0) { 5727275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); 5728c722f30eef03e77054395ae122470cf8dba93937Eric Laurent if (outputDesc->mPolicyMix != NULL) { 5729275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGV("max gain when rerouting for output=%d", output); 5730275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent volume = 1.0f; 5731275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 5732275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 5733275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 5734275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 5735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // We actually change the volume if: 5736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the float value returned by computeVolume() changed 5737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // - the force flag is set 5738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || 5739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force) { 5740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputs.valueFor(output)->mCurVolume[stream] = volume; 5741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); 5742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 5743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // enabled 57443b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_BLUETOOTH_SCO) { 57453b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs); 5746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 57473b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->setStreamVolume(stream, volume, output, delayMs); 5748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 57503b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_VOICE_CALL || 57513b73df74357b33869b39a1d69427673c780bd805Eric Laurent stream == AUDIO_STREAM_BLUETOOTH_SCO) { 5752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent float voiceVolume; 5753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // Force voice volume to max for bluetooth SCO as volume is managed by the headset 57543b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (stream == AUDIO_STREAM_VOICE_CALL) { 5755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; 5756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent voiceVolume = 1.0; 5758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { 5761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->setVoiceVolume(voiceVolume, delayMs); 5762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mLastVoiceVolume = voiceVolume; 5763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 5767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5769e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output, 5770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device, 5771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 5772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool force) 5773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("applyStreamVolumes() for output %d and device %x", output, device); 5775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 57763b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 5777223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if (stream == AUDIO_STREAM_PATCH) { 5778223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent continue; 5779223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } 57803b73df74357b33869b39a1d69427673c780bd805Eric Laurent checkAndSetVolume((audio_stream_type_t)stream, 5781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStreams[stream].getVolumeIndex(device), 5782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 5783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, 5784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs, 5785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent force); 5786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5789e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStrategyMute(routing_strategy strategy, 5790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool on, 5791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 5792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 5793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 5794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); 57963b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { 5797223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if (stream == AUDIO_STREAM_PATCH) { 5798223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent continue; 5799223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } 58003b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (getStrategy((audio_stream_type_t)stream) == strategy) { 58013b73df74357b33869b39a1d69427673c780bd805Eric Laurent setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device); 5802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5806e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStreamMute(audio_stream_type_t stream, 5807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent bool on, 5808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_io_handle_t output, 5809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int delayMs, 5810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent audio_devices_t device) 5811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent StreamDescriptor &streamDesc = mStreams[stream]; 58131f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); 5814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (device == AUDIO_DEVICE_NONE) { 5815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = outputDesc->device(); 5816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x", 5819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, on, output, outputDesc->mMuteCount[stream], device); 5820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (on) { 5822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mMuteCount[stream] == 0) { 5823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (streamDesc.mCanBeMuted && 58243b73df74357b33869b39a1d69427673c780bd805Eric Laurent ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) || 58253b73df74357b33869b39a1d69427673c780bd805Eric Laurent (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) { 5826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 0, output, device, delayMs); 5827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored 5830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent outputDesc->mMuteCount[stream]++; 5831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mMuteCount[stream] == 0) { 5833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("setStreamMute() unmuting non muted stream!"); 5834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 5835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (--outputDesc->mMuteCount[stream] == 0) { 5837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent checkAndSetVolume(stream, 5838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent streamDesc.getVolumeIndex(device), 5839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent output, 5840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device, 5841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent delayMs); 5842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5846e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream, 58473b73df74357b33869b39a1d69427673c780bd805Eric Laurent bool starting, bool stateChange) 5848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if the stream pertains to sonification strategy and we are in call we must 5850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // mute the stream if it is low visibility. If it is high visibility, we must play a tone 5851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // in the device used for phone strategy and play the tone if the selected device does not 5852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // interfere with the device used for phone strategy 5853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as 5854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // many times as there are active tracks on the output 58553b73df74357b33869b39a1d69427673c780bd805Eric Laurent const routing_strategy stream_strategy = getStrategy(stream); 5856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((stream_strategy == STRATEGY_SONIFICATION) || 5857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { 58581f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput); 5859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", 5860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent stream, starting, outputDesc->mDevice, stateChange); 5861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->mRefCount[stream]) { 5862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent int muteCount = 1; 5863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (stateChange) { 5864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent muteCount = outputDesc->mRefCount[stream]; 5865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 58663b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (audio_is_low_visibility(stream)) { 5867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); 5868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < muteCount; i++) { 5869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 5870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() high visibility"); 5873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (outputDesc->device() & 5874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) { 5875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount); 5876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < muteCount; i++) { 5877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent setStreamMute(stream, starting, mPrimaryOutput); 5878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (starting) { 58813b73df74357b33869b39a1d69427673c780bd805Eric Laurent mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION, 58823b73df74357b33869b39a1d69427673c780bd805Eric Laurent AUDIO_STREAM_VOICE_CALL); 5883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mpClientInterface->stopTone(); 5885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5891e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isInCall() 5892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return isStateInCall(mPhoneState); 5894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5896e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStateInCall(int state) { 58973b73df74357b33869b39a1d69427673c780bd805Eric Laurent return ((state == AUDIO_MODE_IN_CALL) || 58983b73df74357b33869b39a1d69427673c780bd805Eric Laurent (state == AUDIO_MODE_IN_COMMUNICATION)); 5899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5901e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsCpuLoad() 5902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return MAX_EFFECTS_CPU_LOAD; 5904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5906e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsMemory() 5907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return MAX_EFFECTS_MEMORY; 5909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 59116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 5912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioOutputDescriptor class implementation 5913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5914e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor( 59151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const sp<IOProfile>& profile) 59161f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent : mId(0), mIoHandle(0), mLatency(0), 5917c722f30eef03e77054395ae122470cf8dba93937Eric Laurent mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), 5918275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mPatchHandle(0), 5919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0) 5920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // clear usage count for all stream types 59223b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 5923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[i] = 0; 5924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCurVolume[i] = -1.0; 5925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mMuteCount[i] = 0; 5926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStopTime[i] = 0; 5927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (int i = 0; i < NUM_STRATEGIES; i++) { 5929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mStrategyMutedByDevice[i] = false; 5930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (profile != NULL) { 59325dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent mFlags = (audio_output_flags_t)profile->mFlags; 59331e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mSamplingRate = profile->pickSamplingRate(); 59341e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mFormat = profile->pickFormat(); 59351e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mChannelMask = profile->pickChannelMask(); 5936a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (profile->mGains.size() > 0) { 5937a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent profile->mGains[0]->getDefaultConfig(&mGain); 5938a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 5939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5942e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::device() const 5943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 5945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 5946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mDevice; 5948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5951e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::AudioOutputDescriptor::latency() 5952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 5954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 5955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mLatency; 5957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5960e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith( 59611f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<AudioOutputDescriptor> outputDesc) 5962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 5964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 5965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (outputDesc->isDuplicated()){ 5966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2); 5967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 5968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (mProfile->mModule == outputDesc->mProfile->mModule); 5969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5972e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 59733b73df74357b33869b39a1d69427673c780bd805Eric Laurent int delta) 5974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // forward usage count change to attached outputs 5976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 5977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput1->changeRefCount(stream, delta); 5978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutput2->changeRefCount(stream, delta); 5979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((delta + (int)mRefCount[stream]) < 0) { 59813b73df74357b33869b39a1d69427673c780bd805Eric Laurent ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", 59823b73df74357b33869b39a1d69427673c780bd805Eric Laurent delta, stream, mRefCount[stream]); 5983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[stream] = 0; 5984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 5985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mRefCount[stream] += delta; 5987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 5988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5990e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::supportedDevices() 5991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 5992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (isDuplicated()) { 5993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 5994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else { 59953a4311c68348f728558e87b5db67d47605783890Eric Laurent return mProfile->mSupportedDevices.types() ; 5996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 5997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 5998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 5999e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isActive(uint32_t inPastMs) const 6000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return isStrategyActive(NUM_STRATEGIES, inPastMs); 6002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6004e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy, 6005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t inPastMs, 6006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime) const 6007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((sysTime == 0) && (inPastMs != 0)) { 6009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime = systemTime(); 6010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 60113b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 6012223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if (i == AUDIO_STREAM_PATCH) { 6013223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent continue; 6014223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } 60153b73df74357b33869b39a1d69427673c780bd805Eric Laurent if (((getStrategy((audio_stream_type_t)i) == strategy) || 6016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (NUM_STRATEGIES == strategy)) && 60173b73df74357b33869b39a1d69427673c780bd805Eric Laurent isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) { 6018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 6019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 6022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6024e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, 6025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t inPastMs, 6026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent nsecs_t sysTime) const 6027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mRefCount[stream] != 0) { 6029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 6030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (inPastMs == 0) { 6032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 6033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (sysTime == 0) { 6035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent sysTime = systemTime(); 6036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 6038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return true; 6039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 6041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 60431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::toAudioPortConfig( 60446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port_config *dstConfig, 60456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const struct audio_port_config *srcConfig) const 60466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 604784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle); 604884c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent 60496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 60501f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 60516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (srcConfig != NULL) { 605284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent dstConfig->config_mask |= srcConfig->config_mask; 60536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 60541f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 60551f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 60561f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->id = mId; 60571f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->role = AUDIO_PORT_ROLE_SOURCE; 60581f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->type = AUDIO_PORT_TYPE_MIX; 60596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle; 60606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.mix.handle = mIoHandle; 60616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 60621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 60631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 60641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::toAudioPort( 60651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_port *port) const 60661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 606784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle); 60681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mProfile->toAudioPort(port); 60691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 60706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent toAudioPortConfig(&port->active_config); 60716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent port->ext.mix.hw_module = mProfile->mModule->mHandle; 60721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.handle = mIoHandle; 60731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.latency_class = 60741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL; 60751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 6076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6077e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd) 6078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 6080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 6081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 6082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 60834d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, " ID: %d\n", mId); 60844d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 6085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 6086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 6088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 6090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 6092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 6094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Devices %08x\n", device()); 6096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 6098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 60993b73df74357b33869b39a1d69427673c780bd805Eric Laurent for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 61003b73df74357b33869b39a1d69427673c780bd805Eric Laurent snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", 61013b73df74357b33869b39a1d69427673c780bd805Eric Laurent i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 6102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 6105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 6107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioInputDescriptor class implementation 6110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 61111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile) 61121f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent : mId(0), mIoHandle(0), 6113c722f30eef03e77054395ae122470cf8dba93937Eric Laurent mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), mPatchHandle(0), mRefCount(0), 6114df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile), mIsSoundTrigger(false) 6115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 61163a4311c68348f728558e87b5db67d47605783890Eric Laurent if (profile != NULL) { 61171e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mSamplingRate = profile->pickSamplingRate(); 61181e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mFormat = profile->pickFormat(); 61191e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mChannelMask = profile->pickChannelMask(); 6120a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (profile->mGains.size() > 0) { 6121a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent profile->mGains[0]->getDefaultConfig(&mGain); 6122a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 61233a4311c68348f728558e87b5db67d47605783890Eric Laurent } 6124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 61261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioInputDescriptor::toAudioPortConfig( 61276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port_config *dstConfig, 61286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const struct audio_port_config *srcConfig) const 61296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 613084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(mProfile != 0, 613184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent "toAudioPortConfig() called on input with null profile %d", mIoHandle); 61326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 61331f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 61346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (srcConfig != NULL) { 613584c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent dstConfig->config_mask |= srcConfig->config_mask; 61366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 61371f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 61381f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 61391f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 61401f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->id = mId; 61411f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->role = AUDIO_PORT_ROLE_SINK; 61421f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->type = AUDIO_PORT_TYPE_MIX; 614362aaabb3905c61bb7acd6037414c206240a31c32Eric Laurent dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle; 614462aaabb3905c61bb7acd6037414c206240a31c32Eric Laurent dstConfig->ext.mix.handle = mIoHandle; 614562aaabb3905c61bb7acd6037414c206240a31c32Eric Laurent dstConfig->ext.mix.usecase.source = mInputSource; 61461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 61471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 61481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioInputDescriptor::toAudioPort( 61491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent struct audio_port *port) const 61501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 615184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle); 615284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent 61531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mProfile->toAudioPort(port); 61541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 61556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent toAudioPortConfig(&port->active_config); 61566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent port->ext.mix.hw_module = mProfile->mModule->mHandle; 61571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.handle = mIoHandle; 61581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL; 61591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 61601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 6161e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioInputDescriptor::dump(int fd) 6162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 6164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 6165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 6166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 61674d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, " ID: %d\n", mId); 61684d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 6169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 6170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Format: %d\n", mFormat); 6172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 6174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Devices %08x\n", mDevice); 6176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); 6178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 61796a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten snprintf(buffer, SIZE, " Open Ref Count %d\n", mOpenRefCount); 61806a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten result.append(buffer); 61816a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten 6182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 6183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 6185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- StreamDescriptor class implementation 6188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6189e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::StreamDescriptor::StreamDescriptor() 6190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 6191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); 6193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6195e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::StreamDescriptor::getVolumeIndex(audio_devices_t device) 6196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6197e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent device = AudioPolicyManager::getDeviceForVolume(device); 6198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT 6199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mIndexCur.indexOfKey(device) < 0) { 6200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT; 6201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return mIndexCur.valueFor(device); 6203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6205e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::StreamDescriptor::dump(int fd) 6206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 6208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 6209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 6210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%s %02d %02d ", 6212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); 6213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mIndexCur.size(); i++) { 6215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, "%04x : %02d, ", 6216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.keyAt(i), 6217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mIndexCur.valueAt(i)); 6218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append("\n"); 6221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 6223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- EffectDescriptor class implementation 6226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6227e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::EffectDescriptor::dump(int fd) 6228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 6230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 6231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 6232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " I/O: %d\n", mIo); 6234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 6236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Session: %d\n", mSession); 6238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 6240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 6242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 6244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 6246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 62481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- HwModule class implementation 6249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6250e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::HwModule(const char *name) 6251eb108a4622825688b02d7afc981014d149913cd8Eric Laurent : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), 6252eb108a4622825688b02d7afc981014d149913cd8Eric Laurent mHalVersion(AUDIO_DEVICE_API_VERSION_MIN), mHandle(0) 6253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6256e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::~HwModule() 6257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 62593a4311c68348f728558e87b5db67d47605783890Eric Laurent mOutputProfiles[i]->mSupportedDevices.clear(); 6260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 62623a4311c68348f728558e87b5db67d47605783890Eric Laurent mInputProfiles[i]->mSupportedDevices.clear(); 6263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free((void *)mName); 6265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 62671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::HwModule::loadInput(cnode *root) 62681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 62691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 62701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 62711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SINK, this); 62721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 62731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 62741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 62751afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadSamplingRates((char *)node->value); 62761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 62771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadFormats((char *)node->value); 62781afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 62791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadInChannels((char *)node->value); 62801afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 62811afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.loadDevicesFromName((char *)node->value, 62821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices); 62835dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent } else if (strcmp(node->name, FLAGS_TAG) == 0) { 62845dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent profile->mFlags = parseInputFlagNames((char *)node->value); 62851afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAINS_TAG) == 0) { 62861afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadGains(node); 62871afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 62881afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 62891afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 62901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSupportedDevices.isEmpty(), 62911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported devices"); 62921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 62931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported channel masks"); 62941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 62951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported sampling rates"); 62961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mFormats.size() == 0, 62971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadInput() invalid supported formats"); 62981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (!profile->mSupportedDevices.isEmpty() && 62991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mChannelMasks.size() != 0) && 63001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mSamplingRates.size() != 0) && 63011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mFormats.size() != 0)) { 63021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63031afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadInput() adding input Supported Devices %04x", 63041afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.types()); 63051afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63061afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mInputProfiles.add(profile); 63071afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return NO_ERROR; 63081afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 63091afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return BAD_VALUE; 63101afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63111afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 63121afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63131afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::HwModule::loadOutput(cnode *root) 63141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 63151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 63161afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SOURCE, this); 63181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 63201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) { 63211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadSamplingRates((char *)node->value); 63221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, FORMATS_TAG) == 0) { 63231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadFormats((char *)node->value); 63241afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 63251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadOutChannels((char *)node->value); 63261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, DEVICES_TAG) == 0) { 63271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.loadDevicesFromName((char *)node->value, 63281afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices); 63291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, FLAGS_TAG) == 0) { 63305dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent profile->mFlags = parseOutputFlagNames((char *)node->value); 63311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAINS_TAG) == 0) { 63321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->loadGains(node); 63331afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63341afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 63351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSupportedDevices.isEmpty(), 63371afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported devices"); 63381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mChannelMasks.size() == 0, 63391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported channel masks"); 63401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mSamplingRates.size() == 0, 63411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported sampling rates"); 63421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW_IF(profile->mFormats.size() == 0, 63431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent "loadOutput() invalid supported formats"); 63441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (!profile->mSupportedDevices.isEmpty() && 63451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mChannelMasks.size() != 0) && 63461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mSamplingRates.size() != 0) && 63471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (profile->mFormats.size() != 0)) { 63481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x", 63501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile->mSupportedDevices.types(), profile->mFlags); 63511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mOutputProfiles.add(profile); 63531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return NO_ERROR; 63541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 63551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return BAD_VALUE; 63561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 63581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::HwModule::loadDevice(cnode *root) 63601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 63611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 63621afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63631afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent audio_devices_t type = AUDIO_DEVICE_NONE; 63641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 63651afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, DEVICE_TYPE) == 0) { 63661afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent type = parseDeviceNames((char *)node->value); 63671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent break; 63681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 63701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (type == AUDIO_DEVICE_NONE || 63721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (!audio_is_input_device(type) && !audio_is_output_device(type))) { 63731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGW("loadDevice() bad type %08x", type); 63741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return BAD_VALUE; 63751afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> deviceDesc = new DeviceDescriptor(String8(root->name), type); 63771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->mModule = this; 63781afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = root->first_child; 63801afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 63811afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, DEVICE_ADDRESS) == 0) { 63821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->mAddress = String8((char *)node->value); 63831afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, CHANNELS_TAG) == 0) { 63841afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (audio_is_input_device(type)) { 63851afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->loadInChannels((char *)node->value); 63861afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 63871afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->loadOutChannels((char *)node->value); 63881afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63891afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAINS_TAG) == 0) { 63901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->loadGains(node); 63911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 63931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 63941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadDevice() adding device name %s type %08x address %s", 63961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent deviceDesc->mName.string(), type, deviceDesc->mAddress.string()); 63971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 63981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices.add(deviceDesc); 63991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 64001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return NO_ERROR; 64011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 64021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 6403275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentstatus_t AudioPolicyManager::HwModule::addOutputProfile(String8 name, const audio_config_t *config, 6404275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent audio_devices_t device, String8 address) 6405275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{ 6406275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SOURCE, this); 6407275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6408275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profile->mSamplingRates.add(config->sample_rate); 6409275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profile->mChannelMasks.add(config->channel_mask); 6410275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profile->mFormats.add(config->format); 6411275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6412275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); 6413275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent devDesc->mAddress = address; 6414275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profile->mSupportedDevices.add(devDesc); 6415275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6416275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mOutputProfiles.add(profile); 6417275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6418275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return NO_ERROR; 6419275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent} 6420275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6421275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentstatus_t AudioPolicyManager::HwModule::removeOutputProfile(String8 name) 6422275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{ 6423275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 6424275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (mOutputProfiles[i]->mName == name) { 6425275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mOutputProfiles.removeAt(i); 6426275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 6427275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 6428275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 6429275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6430275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return NO_ERROR; 6431275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent} 6432275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6433275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentstatus_t AudioPolicyManager::HwModule::addInputProfile(String8 name, const audio_config_t *config, 6434275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent audio_devices_t device, String8 address) 6435275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{ 6436275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SINK, this); 6437275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6438275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profile->mSamplingRates.add(config->sample_rate); 6439275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profile->mChannelMasks.add(config->channel_mask); 6440275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profile->mFormats.add(config->format); 6441275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6442275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); 6443275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent devDesc->mAddress = address; 6444275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent profile->mSupportedDevices.add(devDesc); 6445275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6446275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGV("addInputProfile() name %s rate %d mask 0x08", name.string(), config->sample_rate, config->channel_mask); 6447275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6448275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mInputProfiles.add(profile); 6449275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6450275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return NO_ERROR; 6451275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent} 6452275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6453275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentstatus_t AudioPolicyManager::HwModule::removeInputProfile(String8 name) 6454275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{ 6455275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 6456275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (mInputProfiles[i]->mName == name) { 6457275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent mInputProfiles.removeAt(i); 6458275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 6459275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 6460275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 6461275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6462275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent return NO_ERROR; 6463275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent} 6464275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6465275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent 6466e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::HwModule::dump(int fd) 6467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 6468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 6469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 6470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 6471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 6472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - name: %s\n", mName); 6473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 6475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 6476eb108a4622825688b02d7afc981014d149913cd8Eric Laurent snprintf(buffer, SIZE, " - version: %u.%u\n", mHalVersion >> 8, mHalVersion & 0xFF); 6477eb108a4622825688b02d7afc981014d149913cd8Eric Laurent result.append(buffer); 6478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, result.string(), result.size()); 6479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mOutputProfiles.size()) { 6480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, " - outputs:\n", strlen(" - outputs:\n")); 6481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mOutputProfiles.size(); i++) { 6482d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " output %zu:\n", i); 6483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 6484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mOutputProfiles[i]->dump(fd); 6485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (mInputProfiles.size()) { 6488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, " - inputs:\n", strlen(" - inputs:\n")); 6489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent for (size_t i = 0; i < mInputProfiles.size(); i++) { 6490d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent snprintf(buffer, SIZE, " input %zu:\n", i); 6491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent write(fd, buffer, strlen(buffer)); 6492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mInputProfiles[i]->dump(fd); 6493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 6494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 64951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mDeclaredDevices.size()) { 64961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, " - devices:\n", strlen(" - devices:\n")); 64971afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mDeclaredDevices.size(); i++) { 64981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeclaredDevices[i]->dump(fd, 4, i); 64991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 65001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 6501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 6502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 65031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- AudioPort class implementation 65041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 6505a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 6506a121f90f388343dc48793cbc7eb899aba42e7664Eric LaurentAudioPolicyManager::AudioPort::AudioPort(const String8& name, audio_port_type_t type, 6507a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent audio_port_role_t role, const sp<HwModule>& module) : 65085dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent mName(name), mType(type), mRole(role), mModule(module), mFlags(0) 6509a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 6510a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mUseInChannelMask = ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) || 6511a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK)); 6512a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 6513a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 65141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const 65151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 65161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->role = mRole; 65171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->type = mType; 65181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent unsigned int i; 65191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) { 6520f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (mSamplingRates[i] != 0) { 6521f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi port->sample_rates[i] = mSamplingRates[i]; 6522f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 65231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 65241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_sample_rates = i; 65251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) { 6526f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (mChannelMasks[i] != 0) { 6527f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi port->channel_masks[i] = mChannelMasks[i]; 6528f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 65291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 65301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_channel_masks = i; 65311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) { 6532f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (mFormats[i] != 0) { 6533f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi port->formats[i] = mFormats[i]; 6534f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 65351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 65361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->num_formats = i; 6537e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 6538beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size()); 6539e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent 6540e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) { 6541e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent port->gains[i] = mGains[i]->mGain; 6542e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent } 6543e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent port->num_gains = i; 65441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 65451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 6546f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivivoid AudioPolicyManager::AudioPort::importAudioPort(const sp<AudioPort> port) { 6547f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t k = 0 ; k < port->mSamplingRates.size() ; k++) { 6548f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi const uint32_t rate = port->mSamplingRates.itemAt(k); 6549f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (rate != 0) { // skip "dynamic" rates 6550f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi bool hasRate = false; 6551f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t l = 0 ; l < mSamplingRates.size() ; l++) { 6552f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (rate == mSamplingRates.itemAt(l)) { 6553f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi hasRate = true; 6554f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi break; 6555f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6556f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6557f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (!hasRate) { // never import a sampling rate twice 6558f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mSamplingRates.add(rate); 6559f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6560f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6561f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6562f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t k = 0 ; k < port->mChannelMasks.size() ; k++) { 6563f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi const audio_channel_mask_t mask = port->mChannelMasks.itemAt(k); 6564f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (mask != 0) { // skip "dynamic" masks 6565f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi bool hasMask = false; 6566f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t l = 0 ; l < mChannelMasks.size() ; l++) { 6567f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (mask == mChannelMasks.itemAt(l)) { 6568f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi hasMask = true; 6569f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi break; 6570f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6571f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6572f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (!hasMask) { // never import a channel mask twice 6573f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mChannelMasks.add(mask); 6574f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6575f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6576f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6577f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t k = 0 ; k < port->mFormats.size() ; k++) { 6578f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi const audio_format_t format = port->mFormats.itemAt(k); 6579f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (format != 0) { // skip "dynamic" formats 6580f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi bool hasFormat = false; 6581f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi for (size_t l = 0 ; l < mFormats.size() ; l++) { 6582f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (format == mFormats.itemAt(l)) { 6583f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi hasFormat = true; 6584f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi break; 6585f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6586f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6587f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi if (!hasFormat) { // never import a channel mask twice 6588f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mFormats.add(format); 6589f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6590f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 6591f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi } 659223fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang for (size_t k = 0 ; k < port->mGains.size() ; k++) { 659323fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang sp<AudioGain> gain = port->mGains.itemAt(k); 659423fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang if (gain != 0) { 659523fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang bool hasGain = false; 659623fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang for (size_t l = 0 ; l < mGains.size() ; l++) { 659723fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang if (gain == mGains.itemAt(l)) { 659823fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang hasGain = true; 659923fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang break; 660023fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang } 660123fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang } 660223fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang if (!hasGain) { // never import a gain twice 660323fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang mGains.add(gain); 660423fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang } 660523fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang } 660623fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang } 6607f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi} 6608f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi 6609f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivivoid AudioPolicyManager::AudioPort::clearCapabilities() { 6610f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mChannelMasks.clear(); 6611f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mFormats.clear(); 6612f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi mSamplingRates.clear(); 661323fe3c0a05fcb619eeb5b0c2ece02cdadab2df6eHochi Huang mGains.clear(); 6614f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi} 66151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadSamplingRates(char *name) 66171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 66181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent char *str = strtok(name, "|"); 66191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling 66211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // rates should be read from the output stream after it is opened for the first time 66221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 66231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mSamplingRates.add(0); 66241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 66251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 66261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 66281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent uint32_t rate = atoi(str); 66291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (rate != 0) { 66301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadSamplingRates() adding rate %d", rate); 66311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mSamplingRates.add(rate); 66321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 66331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 66341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 66351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 66361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadFormats(char *name) 66381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 66391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent char *str = strtok(name, "|"); 66401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mFormats indicates the supported formats 66421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // should be read from the output stream after it is opened for the first time 66431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 66441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFormats.add(AUDIO_FORMAT_DEFAULT); 66451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 66461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 66471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 66491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable, 66501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 66511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 66521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (format != AUDIO_FORMAT_DEFAULT) { 66531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mFormats.add(format); 66541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 66551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 66561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 66571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 66581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadInChannels(char *name) 66601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 66611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const char *str = strtok(name, "|"); 66621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadInChannels() %s", name); 66641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 66661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(0); 66671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 66681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 66691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 66711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_channel_mask_t channelMask = 66721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 66731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 66741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 66751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (channelMask != 0) { 66761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadInChannels() adding channelMask %04x", channelMask); 66771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(channelMask); 66781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 66791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 66801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 66811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 66821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadOutChannels(char *name) 66841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 66851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const char *str = strtok(name, "|"); 66861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadOutChannels() %s", name); 66881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // by convention, "0' in the first entry in mChannelMasks indicates the supported channel 66901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent // masks should be read from the output stream after it is opened for the first time 66911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 66921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(0); 66931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 66941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 66951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 66961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent while (str != NULL) { 66971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_channel_mask_t channelMask = 66981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 66991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 67001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str); 67011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (channelMask != 0) { 67021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mChannelMasks.add(channelMask); 67031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 67041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent str = strtok(NULL, "|"); 67051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 67061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return; 67071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 67081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 67091afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentaudio_gain_mode_t AudioPolicyManager::AudioPort::loadGainMode(char *name) 67101afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 67111afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const char *str = strtok(name, "|"); 67121afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 67131afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadGainMode() %s", name); 67141afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent audio_gain_mode_t mode = 0; 67151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (str != NULL) { 67161afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mode |= (audio_gain_mode_t)stringToEnum(sGainModeNameToEnumTable, 67171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sGainModeNameToEnumTable), 67181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent str); 67191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent str = strtok(NULL, "|"); 67201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 67211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return mode; 67221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 67231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 6724a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentvoid AudioPolicyManager::AudioPort::loadGain(cnode *root, int index) 67251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 67261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 67271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 6728a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent sp<AudioGain> gain = new AudioGain(index, mUseInChannelMask); 67291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 67301afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 67311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strcmp(node->name, GAIN_MODE) == 0) { 67321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.mode = loadGainMode((char *)node->value); 67331afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_CHANNELS) == 0) { 6734a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mUseInChannelMask) { 67351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.channel_mask = 67361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, 67371afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sInChannelsNameToEnumTable), 67381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (char *)node->value); 67391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 67401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.channel_mask = 67411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable, 67421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sOutChannelsNameToEnumTable), 67431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent (char *)node->value); 67441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 67451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MIN_VALUE) == 0) { 67461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.min_value = atoi((char *)node->value); 67471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MAX_VALUE) == 0) { 67481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.max_value = atoi((char *)node->value); 67491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_DEFAULT_VALUE) == 0) { 67501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.default_value = atoi((char *)node->value); 67511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_STEP_VALUE) == 0) { 67521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.step_value = atoi((char *)node->value); 67531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MIN_RAMP_MS) == 0) { 67541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.min_ramp_ms = atoi((char *)node->value); 67551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else if (strcmp(node->name, GAIN_MAX_RAMP_MS) == 0) { 67561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.max_ramp_ms = atoi((char *)node->value); 67571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 67581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 67591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 67601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 67611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadGain() adding new gain mode %08x channel mask %08x min mB %d max mB %d", 67621afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent gain->mGain.mode, gain->mGain.channel_mask, gain->mGain.min_value, gain->mGain.max_value); 67631afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 67641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (gain->mGain.mode == 0) { 67651afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return; 67661afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 67671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mGains.add(gain); 67681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 67691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 67701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::AudioPort::loadGains(cnode *root) 67711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 67721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node = root->first_child; 6773a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent int index = 0; 67741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 67751afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadGains() loading gain %s", node->name); 6776a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent loadGain(node, index++); 67771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 67781afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 67791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 67801afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 6781cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kastenstatus_t AudioPolicyManager::AudioPort::checkExactSamplingRate(uint32_t samplingRate) const 6782a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 67830daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent if (mSamplingRates.isEmpty()) { 67840daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent return NO_ERROR; 67850daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent } 67860daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent 6787a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i ++) { 6788a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mSamplingRates[i] == samplingRate) { 6789a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 6790a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6791a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6792a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 6793a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 6794a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 6795cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kastenstatus_t AudioPolicyManager::AudioPort::checkCompatibleSamplingRate(uint32_t samplingRate, 6796cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten uint32_t *updatedSamplingRate) const 6797cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten{ 67980daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent if (mSamplingRates.isEmpty()) { 67990daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent return NO_ERROR; 68000daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent } 68010daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent 6802cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // Search for the closest supported sampling rate that is above (preferred) 6803cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // or below (acceptable) the desired sampling rate, within a permitted ratio. 6804cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // The sampling rates do not need to be sorted in ascending order. 6805cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten ssize_t maxBelow = -1; 6806cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten ssize_t minAbove = -1; 6807cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten uint32_t candidate; 6808cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten for (size_t i = 0; i < mSamplingRates.size(); i++) { 6809cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten candidate = mSamplingRates[i]; 6810cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (candidate == samplingRate) { 6811cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (updatedSamplingRate != NULL) { 6812cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten *updatedSamplingRate = candidate; 6813cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6814cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return NO_ERROR; 6815cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6816cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // candidate < desired 6817cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (candidate < samplingRate) { 6818cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (maxBelow < 0 || candidate > mSamplingRates[maxBelow]) { 6819cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten maxBelow = i; 6820cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6821cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // candidate > desired 6822cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } else { 6823cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (minAbove < 0 || candidate < mSamplingRates[minAbove]) { 6824cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten minAbove = i; 6825cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6826cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6827cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6828cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // This uses hard-coded knowledge about AudioFlinger resampling ratios. 6829cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // TODO Move these assumptions out. 6830cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten static const uint32_t kMaxDownSampleRatio = 6; // beyond this aliasing occurs 6831cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten static const uint32_t kMaxUpSampleRatio = 256; // beyond this sample rate inaccuracies occur 6832cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // due to approximation by an int32_t of the 6833cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // phase increments 6834cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // Prefer to down-sample from a higher sampling rate, as we get the desired frequency spectrum. 6835cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (minAbove >= 0) { 6836cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten candidate = mSamplingRates[minAbove]; 6837cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (candidate / kMaxDownSampleRatio <= samplingRate) { 6838cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (updatedSamplingRate != NULL) { 6839cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten *updatedSamplingRate = candidate; 6840cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6841cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return NO_ERROR; 6842cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6843cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6844cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // But if we have to up-sample from a lower sampling rate, that's OK. 6845cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (maxBelow >= 0) { 6846cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten candidate = mSamplingRates[maxBelow]; 6847cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (candidate * kMaxUpSampleRatio >= samplingRate) { 6848cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (updatedSamplingRate != NULL) { 6849cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten *updatedSamplingRate = candidate; 6850cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6851cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return NO_ERROR; 6852cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6853cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6854cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // leave updatedSamplingRate unmodified 6855cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return BAD_VALUE; 6856cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten} 6857cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 6858cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kastenstatus_t AudioPolicyManager::AudioPort::checkExactChannelMask(audio_channel_mask_t channelMask) const 6859a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 68600daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent if (mChannelMasks.isEmpty()) { 68610daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent return NO_ERROR; 68620daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent } 68630daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent 6864cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten for (size_t i = 0; i < mChannelMasks.size(); i++) { 6865a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mChannelMasks[i] == channelMask) { 6866a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 6867a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6868a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6869a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 6870a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 6871a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 6872cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kastenstatus_t AudioPolicyManager::AudioPort::checkCompatibleChannelMask(audio_channel_mask_t channelMask) 6873cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten const 6874cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten{ 68750daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent if (mChannelMasks.isEmpty()) { 68760daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent return NO_ERROR; 68770daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent } 68780daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent 6879cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK; 6880cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten for (size_t i = 0; i < mChannelMasks.size(); i ++) { 6881cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // FIXME Does not handle multi-channel automatic conversions yet 6882cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten audio_channel_mask_t supported = mChannelMasks[i]; 6883cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (supported == channelMask) { 6884cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return NO_ERROR; 6885cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6886cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isRecordThread) { 6887cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // This uses hard-coded knowledge that AudioFlinger can silently down-mix and up-mix. 6888cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // FIXME Abstract this out to a table. 6889cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (((supported == AUDIO_CHANNEL_IN_FRONT_BACK || supported == AUDIO_CHANNEL_IN_STEREO) 6890cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten && channelMask == AUDIO_CHANNEL_IN_MONO) || 6891cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten (supported == AUDIO_CHANNEL_IN_MONO && (channelMask == AUDIO_CHANNEL_IN_FRONT_BACK 6892cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten || channelMask == AUDIO_CHANNEL_IN_STEREO))) { 6893cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return NO_ERROR; 6894cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6895cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6896cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 6897cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return BAD_VALUE; 6898cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten} 6899cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 6900a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioPort::checkFormat(audio_format_t format) const 6901a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 69020daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent if (mFormats.isEmpty()) { 69030daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent return NO_ERROR; 69040daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent } 69050daea39f02fb1ba60a7b351bb5859e407f9f090bEric Laurent 6906a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < mFormats.size(); i ++) { 6907a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mFormats[i] == format) { 6908a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 6909a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6910a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 6911a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 6912a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 6913a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 69141e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 69151e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentuint32_t AudioPolicyManager::AudioPort::pickSamplingRate() const 69161e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 69171e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // special case for uninitialized dynamic profile 69181e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mSamplingRates.size() == 1 && mSamplingRates[0] == 0) { 69191e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return 0; 69201e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 69211e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 6922828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // For direct outputs, pick minimum sampling rate: this helps ensuring that the 6923828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // channel count / sampling rate combination chosen will be supported by the connected 6924828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // sink 6925828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && 6926828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) { 6927828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent uint32_t samplingRate = UINT_MAX; 6928828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent for (size_t i = 0; i < mSamplingRates.size(); i ++) { 6929828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if ((mSamplingRates[i] < samplingRate) && (mSamplingRates[i] > 0)) { 6930828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent samplingRate = mSamplingRates[i]; 6931828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6932828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6933828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent return (samplingRate == UINT_MAX) ? 0 : samplingRate; 6934828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6935828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent 69361e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t samplingRate = 0; 69371e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t maxRate = MAX_MIXER_SAMPLING_RATE; 69381e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 69391e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // For mixed output and inputs, use max mixer sampling rates. Do not 69401e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // limit sampling rate otherwise 6941828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if (mType != AUDIO_PORT_TYPE_MIX) { 69421e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent maxRate = UINT_MAX; 69431e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 69441e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; i < mSamplingRates.size(); i ++) { 69451e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((mSamplingRates[i] > samplingRate) && (mSamplingRates[i] <= maxRate)) { 69461e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent samplingRate = mSamplingRates[i]; 69471e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 69481e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 69491e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return samplingRate; 69501e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 69511e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 69521e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentaudio_channel_mask_t AudioPolicyManager::AudioPort::pickChannelMask() const 69531e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 69541e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // special case for uninitialized dynamic profile 69551e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mChannelMasks.size() == 1 && mChannelMasks[0] == 0) { 69561e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return AUDIO_CHANNEL_NONE; 69571e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 69581e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent audio_channel_mask_t channelMask = AUDIO_CHANNEL_NONE; 6959828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent 6960828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // For direct outputs, pick minimum channel count: this helps ensuring that the 6961828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // channel count / sampling rate combination chosen will be supported by the connected 6962828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent // sink 6963828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && 6964828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) { 6965828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent uint32_t channelCount = UINT_MAX; 6966828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent for (size_t i = 0; i < mChannelMasks.size(); i ++) { 6967828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent uint32_t cnlCount; 6968828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if (mUseInChannelMask) { 6969828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]); 6970828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } else { 6971828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]); 6972828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6973828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if ((cnlCount < channelCount) && (cnlCount > 0)) { 6974828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent channelMask = mChannelMasks[i]; 6975828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent channelCount = cnlCount; 6976828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6977828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6978828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent return channelMask; 6979828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent } 6980828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent 69811e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t channelCount = 0; 69821e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t maxCount = MAX_MIXER_CHANNEL_COUNT; 69831e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 69841e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // For mixed output and inputs, use max mixer channel count. Do not 69851e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // limit channel count otherwise 6986828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent if (mType != AUDIO_PORT_TYPE_MIX) { 69871e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent maxCount = UINT_MAX; 69881e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 69891e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; i < mChannelMasks.size(); i ++) { 69901e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent uint32_t cnlCount; 69911e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mUseInChannelMask) { 69921e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]); 69931e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 69941e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]); 69951e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 69961e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((cnlCount > channelCount) && (cnlCount <= maxCount)) { 69971e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent channelMask = mChannelMasks[i]; 6998828bcffa0d5f73461c6c1ba4ef6d3da704c27b7eEric Laurent channelCount = cnlCount; 69991e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70001e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70011e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return channelMask; 70021e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 70031e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 70049a60538b9ee2b097770dcd378281b31f4218ae56Andy Hung/* format in order of increasing preference */ 70051e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentconst audio_format_t AudioPolicyManager::AudioPort::sPcmFormatCompareTable[] = { 70061e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent AUDIO_FORMAT_DEFAULT, 70071e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent AUDIO_FORMAT_PCM_16_BIT, 7008a204994e7dd7dab931297176c66b5d3b82e2c90bEric Laurent AUDIO_FORMAT_PCM_8_24_BIT, 70091e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent AUDIO_FORMAT_PCM_24_BIT_PACKED, 7010a204994e7dd7dab931297176c66b5d3b82e2c90bEric Laurent AUDIO_FORMAT_PCM_32_BIT, 70119a60538b9ee2b097770dcd378281b31f4218ae56Andy Hung AUDIO_FORMAT_PCM_FLOAT, 70121e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent}; 70131e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 70141e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentint AudioPolicyManager::AudioPort::compareFormats(audio_format_t format1, 70151e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent audio_format_t format2) 70161e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 70171e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // NOTE: AUDIO_FORMAT_INVALID is also considered not PCM and will be compared equal to any 70181e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // compressed format and better than any PCM format. This is by design of pickFormat() 70191e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (!audio_is_linear_pcm(format1)) { 70201e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (!audio_is_linear_pcm(format2)) { 70211e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return 0; 70221e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70231e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return 1; 70241e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70251e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (!audio_is_linear_pcm(format2)) { 70261e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return -1; 70271e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70281e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 70291e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent int index1 = -1, index2 = -1; 70301e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; 70311e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent (i < ARRAY_SIZE(sPcmFormatCompareTable)) && ((index1 == -1) || (index2 == -1)); 70321e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent i ++) { 70331e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (sPcmFormatCompareTable[i] == format1) { 70341e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent index1 = i; 70351e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70361e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (sPcmFormatCompareTable[i] == format2) { 70371e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent index2 = i; 70381e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70391e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70401e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // format1 not found => index1 < 0 => format2 > format1 70411e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // format2 not found => index2 < 0 => format2 < format1 70421e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return index1 - index2; 70431e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 70441e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 70451e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurentaudio_format_t AudioPolicyManager::AudioPort::pickFormat() const 70461e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent{ 70471e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // special case for uninitialized dynamic profile 70481e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (mFormats.size() == 1 && mFormats[0] == 0) { 70491e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return AUDIO_FORMAT_DEFAULT; 70501e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70511e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 70521e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent audio_format_t format = AUDIO_FORMAT_DEFAULT; 70539a60538b9ee2b097770dcd378281b31f4218ae56Andy Hung audio_format_t bestFormat = 70549a60538b9ee2b097770dcd378281b31f4218ae56Andy Hung AudioPolicyManager::AudioPort::sPcmFormatCompareTable[ 70559a60538b9ee2b097770dcd378281b31f4218ae56Andy Hung ARRAY_SIZE(AudioPolicyManager::AudioPort::sPcmFormatCompareTable) - 1]; 70561e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // For mixed output and inputs, use best mixer output format. Do not 70571e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent // limit format otherwise 70581e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((mType != AUDIO_PORT_TYPE_MIX) || 70591e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ((mRole == AUDIO_PORT_ROLE_SOURCE) && 7060d8622371d5ac5b98abcc5d388bd952bb3dd4fda9Eric Laurent (((mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) != 0)))) { 70611e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent bestFormat = AUDIO_FORMAT_INVALID; 70621e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70631e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 70641e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent for (size_t i = 0; i < mFormats.size(); i ++) { 70651e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if ((compareFormats(mFormats[i], format) > 0) && 70661e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent (compareFormats(mFormats[i], bestFormat) <= 0)) { 70671e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent format = mFormats[i]; 70681e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70691e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 70701e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent return format; 70711e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent} 70721e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 7073a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioPort::checkGain(const struct audio_gain_config *gainConfig, 7074a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent int index) const 7075a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 7076a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (index < 0 || (size_t)index >= mGains.size()) { 7077a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 7078a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7079a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return mGains[index]->checkConfig(gainConfig); 7080a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 7081a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 70821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::AudioPort::dump(int fd, int spaces) const 70831afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 70841afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const size_t SIZE = 256; 70851afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent char buffer[SIZE]; 70861afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent String8 result; 70871afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 70881afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mName.size() != 0) { 70891afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string()); 70901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 70911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 70921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 70931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mSamplingRates.size() != 0) { 70941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- sampling rates: ", spaces, ""); 70951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 70961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 70971e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (i == 0 && mSamplingRates[i] == 0) { 70981e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "Dynamic"); 70991e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 71001e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "%d", mSamplingRates[i]); 71011e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 71021afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 71031afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(i == (mSamplingRates.size() - 1) ? "" : ", "); 71041afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 71051afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append("\n"); 71061afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 71071afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 71081afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mChannelMasks.size() != 0) { 71091afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- channel masks: ", spaces, ""); 71101afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 71111afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 71121e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ALOGV("AudioPort::dump mChannelMasks %zu %08x", i, mChannelMasks[i]); 71131e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent 71141e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (i == 0 && mChannelMasks[i] == 0) { 71151e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "Dynamic"); 71161e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 71171e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]); 71181e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 71191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 71201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(i == (mChannelMasks.size() - 1) ? "" : ", "); 71211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 71221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append("\n"); 71231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 71241afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 71251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mFormats.size() != 0) { 71261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- formats: ", spaces, ""); 71271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 71281afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 71291e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent const char *formatStr = enumToString(sFormatNameToEnumTable, 71301e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent ARRAY_SIZE(sFormatNameToEnumTable), 71311e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mFormats[i]); 71321e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent if (i == 0 && strcmp(formatStr, "") == 0) { 71331e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent snprintf(buffer, SIZE, "Dynamic"); 71341e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } else { 7135cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent snprintf(buffer, SIZE, "%s", formatStr); 71361e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent } 71371afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 71381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(i == (mFormats.size() - 1) ? "" : ", "); 71391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 71401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append("\n"); 71411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 71421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, result.string(), result.size()); 71431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mGains.size() != 0) { 71441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- gains:\n", spaces, ""); 71451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, buffer, strlen(buffer) + 1); 71461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 71471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < mGains.size(); i++) { 71481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mGains[i]->dump(fd, spaces + 2, i); 71491afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 71501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 71511afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 71521afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 71531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent// --- AudioGain class implementation 71541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 7155a121f90f388343dc48793cbc7eb899aba42e7664Eric LaurentAudioPolicyManager::AudioGain::AudioGain(int index, bool useInChannelMask) 71561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 7157a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mIndex = index; 7158a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mUseInChannelMask = useInChannelMask; 71591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent memset(&mGain, 0, sizeof(struct audio_gain)); 71601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 71611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 7162a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentvoid AudioPolicyManager::AudioGain::getDefaultConfig(struct audio_gain_config *config) 7163a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 7164a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->index = mIndex; 7165a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->mode = mGain.mode; 7166a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->channel_mask = mGain.channel_mask; 7167a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((mGain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { 7168a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->values[0] = mGain.default_value; 7169a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 7170a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent uint32_t numValues; 7171a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mUseInChannelMask) { 7172a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_in_mask(mGain.channel_mask); 7173a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 7174a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_out_mask(mGain.channel_mask); 7175a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7176a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < numValues; i++) { 7177a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->values[i] = mGain.default_value; 7178a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7179a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7180a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((mGain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { 7181a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent config->ramp_duration_ms = mGain.min_ramp_ms; 7182a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7183a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 7184a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 7185a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioGain::checkConfig(const struct audio_gain_config *config) 7186a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 7187a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->mode & ~mGain.mode) != 0) { 7188a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 7189a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7190a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { 7191a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->values[0] < mGain.min_value) || 7192a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent (config->values[0] > mGain.max_value)) { 7193a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 7194a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7195a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 7196a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->channel_mask & ~mGain.channel_mask) != 0) { 7197a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 7198a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7199a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent uint32_t numValues; 7200a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (mUseInChannelMask) { 7201a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_in_mask(config->channel_mask); 7202a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } else { 7203a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent numValues = audio_channel_count_from_out_mask(config->channel_mask); 7204a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7205a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent for (size_t i = 0; i < numValues; i++) { 7206a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->values[i] < mGain.min_value) || 7207a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent (config->values[i] > mGain.max_value)) { 7208a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 7209a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7210a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7211a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7212a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { 7213a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if ((config->ramp_duration_ms < mGain.min_ramp_ms) || 7214a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent (config->ramp_duration_ms > mGain.max_ramp_ms)) { 7215a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return BAD_VALUE; 7216a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7217a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7218a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return NO_ERROR; 7219a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 7220a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 72211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::AudioGain::dump(int fd, int spaces, int index) const 72221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 72231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const size_t SIZE = 256; 72241afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent char buffer[SIZE]; 72251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent String8 result; 72261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 72271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*sGain %d:\n", spaces, "", index+1); 72281afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 72291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- mode: %08x\n", spaces, "", mGain.mode); 72301afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 72311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask); 72321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 72331afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- min_value: %d mB\n", spaces, "", mGain.min_value); 72341afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 72351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- max_value: %d mB\n", spaces, "", mGain.max_value); 72361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 72371afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- default_value: %d mB\n", spaces, "", mGain.default_value); 72381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 72391afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- step_value: %d mB\n", spaces, "", mGain.step_value); 72401afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 72411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms); 72421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 72431afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms); 72441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 72451afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 72461afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, result.string(), result.size()); 72471afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 72481afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 72491f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent// --- AudioPortConfig class implementation 72501f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 72511f2f2230900581e5de9cf01a883e5d9338f0df94Eric LaurentAudioPolicyManager::AudioPortConfig::AudioPortConfig() 72521f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent{ 72531f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mSamplingRate = 0; 72541f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mChannelMask = AUDIO_CHANNEL_NONE; 72551f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mFormat = AUDIO_FORMAT_INVALID; 72561f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent mGain.index = -1; 72571f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent} 72581f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 7259a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentstatus_t AudioPolicyManager::AudioPortConfig::applyAudioPortConfig( 7260a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent const struct audio_port_config *config, 7261a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config *backupConfig) 7262a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent{ 7263a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent struct audio_port_config localBackupConfig; 7264a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status_t status = NO_ERROR; 7265a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 7266a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent localBackupConfig.config_mask = config->config_mask; 7267a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent toAudioPortConfig(&localBackupConfig); 7268a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 7269961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen sp<AudioPort> audioport = getAudioPort(); 7270961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen if (audioport == 0) { 7271a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent status = NO_INIT; 7272a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 7273a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7274a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { 7275961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen status = audioport->checkExactSamplingRate(config->sample_rate); 7276a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 7277a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 7278a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7279a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mSamplingRate = config->sample_rate; 7280a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7281a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { 7282961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen status = audioport->checkExactChannelMask(config->channel_mask); 7283a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 7284a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 7285a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7286a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mChannelMask = config->channel_mask; 7287a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7288a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) { 7289961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen status = audioport->checkFormat(config->format); 7290a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 7291a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 7292a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7293a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mFormat = config->format; 7294a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7295a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) { 7296961ec21a5878517ce6db27bad8da269637c45a44Marco Nelissen status = audioport->checkGain(&config->gain, config->gain.index); 7297a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 7298a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent goto exit; 7299a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7300a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent mGain = config->gain; 7301a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7302a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 7303a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurentexit: 7304a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (status != NO_ERROR) { 7305a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent applyAudioPortConfig(&localBackupConfig); 7306a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7307a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent if (backupConfig != NULL) { 7308a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent *backupConfig = localBackupConfig; 7309a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent } 7310a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent return status; 7311a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent} 7312a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent 73131f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::AudioPortConfig::toAudioPortConfig( 73141f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent struct audio_port_config *dstConfig, 73151f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const struct audio_port_config *srcConfig) const 73161f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent{ 73171f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { 73181f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->sample_rate = mSamplingRate; 73191f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)) { 73201f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->sample_rate = srcConfig->sample_rate; 73211f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 73221f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 73231f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->sample_rate = 0; 73241f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 73251f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { 73261f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->channel_mask = mChannelMask; 73271f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)) { 73281f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->channel_mask = srcConfig->channel_mask; 73291f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 73301f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 73311f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->channel_mask = AUDIO_CHANNEL_NONE; 73321f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 73331f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) { 73341f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->format = mFormat; 73351f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)) { 73361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->format = srcConfig->format; 73371f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 73381f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 73391f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->format = AUDIO_FORMAT_INVALID; 73401f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 73411f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) { 73421f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->gain = mGain; 73431f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)) { 73441f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->gain = srcConfig->gain; 73451f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 73461f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 73471f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->gain.index = -1; 73481f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 73491f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (dstConfig->gain.index != -1) { 73501f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN; 73511f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } else { 73521f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN; 73531f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 73541f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent} 73551f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 73561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- IOProfile class implementation 73571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 73581afeecb88bea660b2c10b2096be0fd02433303ceEric LaurentAudioPolicyManager::IOProfile::IOProfile(const String8& name, audio_port_role_t role, 73591f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent const sp<HwModule>& module) 73601e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent : AudioPort(name, AUDIO_PORT_TYPE_MIX, role, module) 7361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7364e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile::~IOProfile() 7365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// checks if the IO profile is compatible with specified parameters. 7369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Sampling rate, format and channel mask must be specified in order to 7370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// get a valid a match 7371e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device, 7372275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent String8 address, 7373275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent uint32_t samplingRate, 7374275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent uint32_t *updatedSamplingRate, 7375275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent audio_format_t format, 7376275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent audio_channel_mask_t channelMask, 7377275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent uint32_t flags) const 7378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7379cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten const bool isPlaybackThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SOURCE; 7380cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK; 7381cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten ALOG_ASSERT(isPlaybackThread != isRecordThread); 7382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7383275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (device != AUDIO_DEVICE_NONE && mSupportedDevices.getDevice(device, address) == 0) { 7384cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 7385cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 7386cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 7387cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (samplingRate == 0) { 7388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 7389cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 7390cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten uint32_t myUpdatedSamplingRate = samplingRate; 7391cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isPlaybackThread && checkExactSamplingRate(samplingRate) != NO_ERROR) { 7392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 7393cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 7394cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isRecordThread && checkCompatibleSamplingRate(samplingRate, &myUpdatedSamplingRate) != 7395cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten NO_ERROR) { 7396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return false; 7397cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 7398cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 7399cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (!audio_is_valid_format(format) || checkFormat(format) != NO_ERROR) { 7400cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 7401cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 7402cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 7403cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isPlaybackThread && (!audio_is_output_channel(channelMask) || 7404cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten checkExactChannelMask(channelMask) != NO_ERROR)) { 7405cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 7406cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 7407cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isRecordThread && (!audio_is_input_channel(channelMask) || 7408cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten checkCompatibleChannelMask(channelMask) != NO_ERROR)) { 7409cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 7410cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 7411cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 7412cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (isPlaybackThread && (mFlags & flags) != flags) { 7413cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 7414cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 7415cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // The only input flag that is allowed to be different is the fast flag. 7416cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // An existing fast stream is compatible with a normal track request. 7417cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // An existing normal stream is compatible with a fast track request, 7418cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten // but the fast request will be denied by AudioFlinger and converted to normal track. 74195dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent if (isRecordThread && ((mFlags ^ flags) & 7420cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten ~AUDIO_INPUT_FLAG_FAST)) { 7421cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return false; 7422cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 7423cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten 7424cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten if (updatedSamplingRate != NULL) { 7425cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten *updatedSamplingRate = myUpdatedSamplingRate; 7426cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten } 7427cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten return true; 7428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7430e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::IOProfile::dump(int fd) 7431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent const size_t SIZE = 256; 7433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char buffer[SIZE]; 7434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent String8 result; 7435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 74361afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent AudioPort::dump(fd, 4); 7437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 74381afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, " - flags: 0x%04x\n", mFlags); 7439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 74403a4311c68348f728558e87b5db67d47605783890Eric Laurent snprintf(buffer, SIZE, " - devices:\n"); 7441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent result.append(buffer); 74423a4311c68348f728558e87b5db67d47605783890Eric Laurent write(fd, result.string(), result.size()); 74433a4311c68348f728558e87b5db67d47605783890Eric Laurent for (size_t i = 0; i < mSupportedDevices.size(); i++) { 74441afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mSupportedDevices[i]->dump(fd, 6, i); 74453a4311c68348f728558e87b5db67d47605783890Eric Laurent } 7446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7448d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::IOProfile::log() 7449d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{ 7450d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent const size_t SIZE = 256; 7451d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent char buffer[SIZE]; 7452d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent String8 result; 7453d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 7454d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - sampling rates: "); 7455d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mSamplingRates.size(); i++) { 7456d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" %d", mSamplingRates[i]); 7457d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 7458d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 7459d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - channel masks: "); 7460d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mChannelMasks.size(); i++) { 7461d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" 0x%04x", mChannelMasks[i]); 7462d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 7463d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 7464d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - formats: "); 7465d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent for (size_t i = 0; i < mFormats.size(); i++) { 7466d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" 0x%08x", mFormats[i]); 7467d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent } 7468d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 7469d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - devices: 0x%04x\n", mSupportedDevices.types()); 7470d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent ALOGV(" - flags: 0x%04x\n", mFlags); 7471d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent} 7472d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 7473d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent 74743a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- DeviceDescriptor implementation 7475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 74761f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 74771f2f2230900581e5de9cf01a883e5d9338f0df94Eric LaurentAudioPolicyManager::DeviceDescriptor::DeviceDescriptor(const String8& name, audio_devices_t type) : 74781f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPort(name, AUDIO_PORT_TYPE_DEVICE, 74791f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK : 74801f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_PORT_ROLE_SOURCE, 74811f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent NULL), 74821e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent mDeviceType(type), mAddress(""), mId(0) 74831f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent{ 74841f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent} 74851f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 74863a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const 74873a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 74883a4311c68348f728558e87b5db67d47605783890Eric Laurent // Devices are considered equal if they: 74893a4311c68348f728558e87b5db67d47605783890Eric Laurent // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE) 74903a4311c68348f728558e87b5db67d47605783890Eric Laurent // - have the same address or one device does not specify the address 74913a4311c68348f728558e87b5db67d47605783890Eric Laurent // - have the same channel mask or one device does not specify the channel mask 74921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return (mDeviceType == other->mDeviceType) && 74933a4311c68348f728558e87b5db67d47605783890Eric Laurent (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) && 74942f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent (mChannelMask == 0 || other->mChannelMask == 0 || 74953a4311c68348f728558e87b5db67d47605783890Eric Laurent mChannelMask == other->mChannelMask); 74963a4311c68348f728558e87b5db67d47605783890Eric Laurent} 7497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 74981db89b9c2692fd70eb1cc98b7db2f9beed81e66eEric Laurentvoid AudioPolicyManager::DeviceDescriptor::loadGains(cnode *root) 74991db89b9c2692fd70eb1cc98b7db2f9beed81e66eEric Laurent{ 75001db89b9c2692fd70eb1cc98b7db2f9beed81e66eEric Laurent AudioPort::loadGains(root); 75011db89b9c2692fd70eb1cc98b7db2f9beed81e66eEric Laurent if (mGains.size() > 0) { 75021db89b9c2692fd70eb1cc98b7db2f9beed81e66eEric Laurent mGains[0]->getDefaultConfig(&mGain); 75031db89b9c2692fd70eb1cc98b7db2f9beed81e66eEric Laurent } 75041db89b9c2692fd70eb1cc98b7db2f9beed81e66eEric Laurent} 75051db89b9c2692fd70eb1cc98b7db2f9beed81e66eEric Laurent 75061db89b9c2692fd70eb1cc98b7db2f9beed81e66eEric Laurent 75073a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::refreshTypes() 75083a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 75091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDeviceTypes = AUDIO_DEVICE_NONE; 75103a4311c68348f728558e87b5db67d47605783890Eric Laurent for(size_t i = 0; i < size(); i++) { 75111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent mDeviceTypes |= itemAt(i)->mDeviceType; 75123a4311c68348f728558e87b5db67d47605783890Eric Laurent } 75131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes); 75143a4311c68348f728558e87b5db67d47605783890Eric Laurent} 7515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 75163a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const 75173a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 75183a4311c68348f728558e87b5db67d47605783890Eric Laurent for(size_t i = 0; i < size(); i++) { 75193a4311c68348f728558e87b5db67d47605783890Eric Laurent if (item->equals(itemAt(i))) { 75203a4311c68348f728558e87b5db67d47605783890Eric Laurent return i; 75213a4311c68348f728558e87b5db67d47605783890Eric Laurent } 75223a4311c68348f728558e87b5db67d47605783890Eric Laurent } 75233a4311c68348f728558e87b5db67d47605783890Eric Laurent return -1; 75243a4311c68348f728558e87b5db67d47605783890Eric Laurent} 7525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 75263a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::add(const sp<DeviceDescriptor>& item) 75273a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 75283a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t ret = indexOf(item); 7529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 75303a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret < 0) { 75313a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = SortedVector::add(item); 75323a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret >= 0) { 75333a4311c68348f728558e87b5db67d47605783890Eric Laurent refreshTypes(); 75343a4311c68348f728558e87b5db67d47605783890Eric Laurent } 75353a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 75361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("DeviceVector::add device %08x already in", item->mDeviceType); 75373a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = -1; 75383a4311c68348f728558e87b5db67d47605783890Eric Laurent } 75393a4311c68348f728558e87b5db67d47605783890Eric Laurent return ret; 75403a4311c68348f728558e87b5db67d47605783890Eric Laurent} 7541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 75423a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::remove(const sp<DeviceDescriptor>& item) 75433a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 75443a4311c68348f728558e87b5db67d47605783890Eric Laurent size_t i; 75453a4311c68348f728558e87b5db67d47605783890Eric Laurent ssize_t ret = indexOf(item); 7546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 75473a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret < 0) { 75481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGW("DeviceVector::remove device %08x not in", item->mDeviceType); 75493a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 75503a4311c68348f728558e87b5db67d47605783890Eric Laurent ret = SortedVector::removeAt(ret); 75513a4311c68348f728558e87b5db67d47605783890Eric Laurent if (ret >= 0) { 75523a4311c68348f728558e87b5db67d47605783890Eric Laurent refreshTypes(); 75533a4311c68348f728558e87b5db67d47605783890Eric Laurent } 75543a4311c68348f728558e87b5db67d47605783890Eric Laurent } 75553a4311c68348f728558e87b5db67d47605783890Eric Laurent return ret; 75563a4311c68348f728558e87b5db67d47605783890Eric Laurent} 7557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 75583a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::loadDevicesFromType(audio_devices_t types) 7559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 75603a4311c68348f728558e87b5db67d47605783890Eric Laurent DeviceVector deviceList; 75613a4311c68348f728558e87b5db67d47605783890Eric Laurent 75623a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t role_bit = AUDIO_DEVICE_BIT_IN & types; 75633a4311c68348f728558e87b5db67d47605783890Eric Laurent types &= ~role_bit; 75643a4311c68348f728558e87b5db67d47605783890Eric Laurent 75653a4311c68348f728558e87b5db67d47605783890Eric Laurent while (types) { 75663a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t i = 31 - __builtin_clz(types); 75673a4311c68348f728558e87b5db67d47605783890Eric Laurent uint32_t type = 1 << i; 75683a4311c68348f728558e87b5db67d47605783890Eric Laurent types &= ~type; 75691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent add(new DeviceDescriptor(String8(""), type | role_bit)); 7570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 75731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentvoid AudioPolicyManager::DeviceVector::loadDevicesFromName(char *name, 75741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const DeviceVector& declaredDevices) 75751afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 75761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent char *devName = strtok(name, "|"); 75771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (devName != NULL) { 75781afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (strlen(devName) != 0) { 75791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent audio_devices_t type = stringToEnum(sDeviceNameToEnumTable, 75801afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 75811afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent devName); 75821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (type != AUDIO_DEVICE_NONE) { 7583fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi sp<DeviceDescriptor> dev = new DeviceDescriptor(String8(""), type); 7584275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || 7585275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) { 7586fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi dev->mAddress = String8("0"); 7587fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi } 7588fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi add(dev); 75891afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } else { 75901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> deviceDesc = 75911afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices.getDeviceFromName(String8(devName)); 75921afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (deviceDesc != 0) { 75931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent add(deviceDesc); 75941afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 75951afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 75961afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 7597275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent devName = strtok(NULL, "|"); 75981afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 75991afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 76001afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 76011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDevice( 76021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type, String8 address) const 76031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 76041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<DeviceDescriptor> device; 76051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; i < size(); i++) { 76061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (itemAt(i)->mDeviceType == type) { 7607275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (address == "" || itemAt(i)->mAddress == address) { 7608275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent device = itemAt(i); 7609275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent if (itemAt(i)->mAddress == address) { 7610275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent break; 7611275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 76121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 76131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 76141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 7615275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent ALOGV("DeviceVector::getDevice() for type %08x address %s found %p", 76161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent type, address.string(), device.get()); 76171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return device; 76181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 76191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 76206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromId( 76216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent audio_port_handle_t id) const 76226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{ 76236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent sp<DeviceDescriptor> device; 76246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent for (size_t i = 0; i < size(); i++) { 7625beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn ALOGV("DeviceVector::getDeviceFromId(%d) itemAt(%zu)->mId %d", id, i, itemAt(i)->mId); 76266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent if (itemAt(i)->mId == id) { 76276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent device = itemAt(i); 76286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent break; 76296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 76306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent } 76316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent return device; 76326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent} 76336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent 76341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromType( 76351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_devices_t type) const 76361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 76371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent DeviceVector devices; 76381b4d229ee6b2abef871bcfcd30e0f1d7a1e42afbEric Laurent bool isOutput = audio_is_output_devices(type); 76391b4d229ee6b2abef871bcfcd30e0f1d7a1e42afbEric Laurent type &= ~AUDIO_DEVICE_BIT_IN; 76401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) { 76411b4d229ee6b2abef871bcfcd30e0f1d7a1e42afbEric Laurent bool curIsOutput = audio_is_output_devices(itemAt(i)->mDeviceType); 76421b4d229ee6b2abef871bcfcd30e0f1d7a1e42afbEric Laurent audio_devices_t curType = itemAt(i)->mDeviceType & ~AUDIO_DEVICE_BIT_IN; 76431b4d229ee6b2abef871bcfcd30e0f1d7a1e42afbEric Laurent if ((isOutput == curIsOutput) && ((type & curType) != 0)) { 76441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent devices.add(itemAt(i)); 76451b4d229ee6b2abef871bcfcd30e0f1d7a1e42afbEric Laurent type &= ~curType; 76461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("DeviceVector::getDevicesFromType() for type %x found %p", 76471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent itemAt(i)->mDeviceType, itemAt(i).get()); 76481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 76491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 76501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return devices; 76511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 76521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 76530fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel TriviAudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromTypeAddr( 76540fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi audio_devices_t type, String8 address) const 76550fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi{ 76560fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi DeviceVector devices; 76570fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi for (size_t i = 0; i < size(); i++) { 76580fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (itemAt(i)->mDeviceType == type) { 76590fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi if (itemAt(i)->mAddress == address) { 76600fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi devices.add(itemAt(i)); 76610fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 76620fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 76630fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi } 76640fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi return devices; 76650fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi} 76660fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi 76671afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromName( 76681afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent const String8& name) const 76691afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent{ 76701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent sp<DeviceDescriptor> device; 76711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent for (size_t i = 0; i < size(); i++) { 76721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (itemAt(i)->mName == name) { 76731afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent device = itemAt(i); 76741afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent break; 76751afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 76761afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 76771afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent return device; 76781afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent} 76791afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 76806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentvoid AudioPolicyManager::DeviceDescriptor::toAudioPortConfig( 76816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent struct audio_port_config *dstConfig, 76826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent const struct audio_port_config *srcConfig) const 76831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 76841f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK|AUDIO_PORT_CONFIG_GAIN; 76851f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent if (srcConfig != NULL) { 768684c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent dstConfig->config_mask |= srcConfig->config_mask; 76871f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent } 76881f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 76891f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 76901f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent 76916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->id = mId; 76926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->role = audio_is_output_device(mDeviceType) ? 76931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE; 76946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->type = AUDIO_PORT_TYPE_DEVICE; 76956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.device.type = mDeviceType; 76966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent dstConfig->ext.device.hw_module = mModule->mHandle; 76976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN); 76981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 76991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 77001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::DeviceDescriptor::toAudioPort(struct audio_port *port) const 77011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 770283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ALOGV("DeviceDescriptor::toAudioPort() handle %d type %x", mId, mDeviceType); 77031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent AudioPort::toAudioPort(port); 77041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->id = mId; 77056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent toAudioPortConfig(&port->active_config); 77061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent port->ext.device.type = mDeviceType; 77076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent port->ext.device.hw_module = mModule->mHandle; 77081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN); 77091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 77101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 77111afeecb88bea660b2c10b2096be0fd02433303ceEric Laurentstatus_t AudioPolicyManager::DeviceDescriptor::dump(int fd, int spaces, int index) const 77123a4311c68348f728558e87b5db67d47605783890Eric Laurent{ 77133a4311c68348f728558e87b5db67d47605783890Eric Laurent const size_t SIZE = 256; 77143a4311c68348f728558e87b5db67d47605783890Eric Laurent char buffer[SIZE]; 77151afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent String8 result; 77163a4311c68348f728558e87b5db67d47605783890Eric Laurent 77171afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1); 77181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 77191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mId != 0) { 77201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId); 77211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 77221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 77231afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "", 77241afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent enumToString(sDeviceNameToEnumTable, 77251afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 77261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDeviceType)); 77271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 77281afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (mAddress.size() != 0) { 77291afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string()); 77301afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent result.append(buffer); 77311afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 77321afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent write(fd, result.string(), result.size()); 77331afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent AudioPort::dump(fd, spaces); 77343a4311c68348f728558e87b5db67d47605783890Eric Laurent 77353a4311c68348f728558e87b5db67d47605783890Eric Laurent return NO_ERROR; 77363a4311c68348f728558e87b5db67d47605783890Eric Laurent} 77373a4311c68348f728558e87b5db67d47605783890Eric Laurent 77384d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurentstatus_t AudioPolicyManager::AudioPatch::dump(int fd, int spaces, int index) const 77394d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent{ 77404d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent const size_t SIZE = 256; 77414d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent char buffer[SIZE]; 77424d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent String8 result; 77434d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent 77444d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent 77454d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*sAudio patch %d:\n", spaces, "", index+1); 77464d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 77474d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- handle: %2d\n", spaces, "", mHandle); 77484d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 77494d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- audio flinger handle: %2d\n", spaces, "", mAfPatchHandle); 77504d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 77514d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid); 77524d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 77534d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- %d sources:\n", spaces, "", mPatch.num_sources); 77544d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 77554d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent for (size_t i = 0; i < mPatch.num_sources; i++) { 77564d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent if (mPatch.sources[i].type == AUDIO_PORT_TYPE_DEVICE) { 77574d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "", 77584d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sources[i].id, enumToString(sDeviceNameToEnumTable, 77594d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 77604d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sources[i].ext.device.type)); 77614d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } else { 77624d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "", 77634d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sources[i].id, mPatch.sources[i].ext.mix.handle); 77644d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } 77654d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 77664d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } 77674d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- %d sinks:\n", spaces, "", mPatch.num_sinks); 77684d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 77694d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent for (size_t i = 0; i < mPatch.num_sinks; i++) { 77704d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent if (mPatch.sinks[i].type == AUDIO_PORT_TYPE_DEVICE) { 77714d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "", 77724d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sinks[i].id, enumToString(sDeviceNameToEnumTable, 77734d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 77744d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sinks[i].ext.device.type)); 77754d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } else { 77764d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "", 77774d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent mPatch.sinks[i].id, mPatch.sinks[i].ext.mix.handle); 77784d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } 77794d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent result.append(buffer); 77804d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent } 77814d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent 77824d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent write(fd, result.string(), result.size()); 77834d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent return NO_ERROR; 77844d41695d45e2c7211899afa94b20e32120b2b7e0Eric Laurent} 77853a4311c68348f728558e87b5db67d47605783890Eric Laurent 77863a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- audio_policy.conf file parsing 77873a4311c68348f728558e87b5db67d47605783890Eric Laurent 77885dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurentuint32_t AudioPolicyManager::parseOutputFlagNames(char *name) 7789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t flag = 0; 7791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // it is OK to cast name to non const here as we are not going to use it after 7793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // strtok() modifies it 7794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *flagName = strtok(name, "|"); 7795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (flagName != NULL) { 7796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strlen(flagName) != 0) { 77975dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent flag |= stringToEnum(sOutputFlagNameToEnumTable, 77985dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent ARRAY_SIZE(sOutputFlagNameToEnumTable), 7799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flagName); 7800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flagName = strtok(NULL, "|"); 7802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent //force direct flag if offload flag is set: offloading implies a direct output stream 7804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // and all common behaviors are driven by checking only the direct flag 7805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent // this should normally be set appropriately in the policy configuration file 7806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 7807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent flag |= AUDIO_OUTPUT_FLAG_DIRECT; 7808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 78105dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent return flag; 78115dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent} 78125dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent 78135dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurentuint32_t AudioPolicyManager::parseInputFlagNames(char *name) 78145dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent{ 78155dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent uint32_t flag = 0; 78165dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent 78175dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent // it is OK to cast name to non const here as we are not going to use it after 78185dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent // strtok() modifies it 78195dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent char *flagName = strtok(name, "|"); 78205dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent while (flagName != NULL) { 78215dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent if (strlen(flagName) != 0) { 78225dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent flag |= stringToEnum(sInputFlagNameToEnumTable, 78235dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent ARRAY_SIZE(sInputFlagNameToEnumTable), 78245dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent flagName); 78255dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent } 78265dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent flagName = strtok(NULL, "|"); 78275dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent } 78285dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent return flag; 7829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7831e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::parseDeviceNames(char *name) 7832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent uint32_t device = 0; 7834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *devName = strtok(name, "|"); 7836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (devName != NULL) { 7837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strlen(devName) != 0) { 7838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent device |= stringToEnum(sDeviceNameToEnumTable, 7839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 7840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devName); 78413a4311c68348f728558e87b5db67d47605783890Eric Laurent } 7842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent devName = strtok(NULL, "|"); 78433a4311c68348f728558e87b5db67d47605783890Eric Laurent } 7844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return device; 7845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7847e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModule(cnode *root) 7848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status_t status = NAME_NOT_FOUND; 78501afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent cnode *node; 78511f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module = new HwModule(root->name); 7852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 78531afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = config_find(root, DEVICES_TAG); 78541afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (node != NULL) { 78551afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->first_child; 78561afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent while (node) { 78571afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent ALOGV("loadHwModule() loading device %s", node->name); 78581afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status_t tmpStatus = module->loadDevice(node); 78591afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 78601afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status = tmpStatus; 78611afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 78621afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = node->next; 78631afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 78641afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 78651afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent node = config_find(root, OUTPUTS_TAG); 7866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node != NULL) { 7867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 7868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 7869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModule() loading output %s", node->name); 78701afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status_t tmpStatus = module->loadOutput(node); 7871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 7872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = tmpStatus; 7873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 7875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = config_find(root, INPUTS_TAG); 7878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node != NULL) { 7879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 7880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 7881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModule() loading input %s", node->name); 78821afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent status_t tmpStatus = module->loadInput(node); 7883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NAME_NOT_FOUND || status == NO_ERROR) { 7884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent status = tmpStatus; 7885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 7887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 78891afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent loadGlobalConfig(root, module); 78901afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 7891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (status == NO_ERROR) { 7892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules.add(module); 7893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7896e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModules(cnode *root) 7897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); 7899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node == NULL) { 7900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 7901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 7904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 7905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadHwModules() loading module %s", node->name); 7906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadHwModule(node); 7907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 7908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 79111f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::loadGlobalConfig(cnode *root, const sp<HwModule>& module) 7912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *node = config_find(root, GLOBAL_CONFIG_TAG); 7914eb108a4622825688b02d7afc981014d149913cd8Eric Laurent 7915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (node == NULL) { 7916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return; 7917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 79181afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent DeviceVector declaredDevices; 79191afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent if (module != NULL) { 79201afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices = module->mDeclaredDevices; 79211afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent } 79221afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent 7923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->first_child; 7924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent while (node) { 7925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { 79261afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableOutputDevices.loadDevicesFromName((char *)node->value, 79271afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices); 79283a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadGlobalConfig() Attached Output Devices %08x", 79293a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.types()); 7930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { 79313a4311c68348f728558e87b5db67d47605783890Eric Laurent audio_devices_t device = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable, 7932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ARRAY_SIZE(sDeviceNameToEnumTable), 7933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent (char *)node->value); 79343a4311c68348f728558e87b5db67d47605783890Eric Laurent if (device != AUDIO_DEVICE_NONE) { 79351afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mDefaultOutputDevice = new DeviceDescriptor(String8(""), device); 79363a4311c68348f728558e87b5db67d47605783890Eric Laurent } else { 79373a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGW("loadGlobalConfig() default device not specified"); 79383a4311c68348f728558e87b5db67d47605783890Eric Laurent } 79391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", mDefaultOutputDevice->mDeviceType); 7940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { 79411afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent mAvailableInputDevices.loadDevicesFromName((char *)node->value, 79421afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent declaredDevices); 79433a4311c68348f728558e87b5db67d47605783890Eric Laurent ALOGV("loadGlobalConfig() Available InputDevices %08x", mAvailableInputDevices.types()); 7944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) { 7945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mSpeakerDrcEnabled = stringToBool((char *)node->value); 7946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled); 7947eb108a4622825688b02d7afc981014d149913cd8Eric Laurent } else if (strcmp(AUDIO_HAL_VERSION_TAG, node->name) == 0) { 7948eb108a4622825688b02d7afc981014d149913cd8Eric Laurent uint32_t major, minor; 7949eb108a4622825688b02d7afc981014d149913cd8Eric Laurent sscanf((char *)node->value, "%u.%u", &major, &minor); 7950eb108a4622825688b02d7afc981014d149913cd8Eric Laurent module->mHalVersion = HARDWARE_DEVICE_API_VERSION(major, minor); 7951eb108a4622825688b02d7afc981014d149913cd8Eric Laurent ALOGV("loadGlobalConfig() mHalVersion = %04x major %u minor %u", 7952eb108a4622825688b02d7afc981014d149913cd8Eric Laurent module->mHalVersion, major, minor); 7953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent node = node->next; 7955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7958e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadAudioPolicyConfig(const char *path) 7959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 7960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent cnode *root; 7961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent char *data; 7962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent data = (char *)load_file(path, NULL); 7964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent if (data == NULL) { 7965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return -ENODEV; 7966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent } 7967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent root = config_node("", ""); 7968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent config_load(root, data); 7969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent loadHwModules(root); 79711afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent // legacy audio_policy.conf files have one global_configuration section 79721afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent loadGlobalConfig(root, getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)); 7973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent config_free(root); 7974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free(root); 7975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent free(data); 7976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent ALOGI("loadAudioPolicyConfig() loaded %s\n", path); 7978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent return NO_ERROR; 7980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 7981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7982e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::defaultAudioPolicyConfig(void) 7983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{ 79841f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<HwModule> module; 79851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<IOProfile> profile; 79861f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(String8(""), 79871f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent AUDIO_DEVICE_IN_BUILTIN_MIC); 79883a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableOutputDevices.add(mDefaultOutputDevice); 79893a4311c68348f728558e87b5db67d47605783890Eric Laurent mAvailableInputDevices.add(defaultInputDevice); 7990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 7991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module = new HwModule("primary"); 7992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 79931afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SOURCE, module); 7994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(44100); 7995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 7996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO); 79973a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.add(mDefaultOutputDevice); 7998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY; 7999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mOutputProfiles.add(profile); 8000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 80011afeecb88bea660b2c10b2096be0fd02433303ceEric Laurent profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SINK, module); 8002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mSamplingRates.add(8000); 8003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT); 8004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO); 80053a4311c68348f728558e87b5db67d47605783890Eric Laurent profile->mSupportedDevices.add(defaultInputDevice); 8006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent module->mInputProfiles.add(profile); 8007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 8008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent mHwModules.add(module); 8009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent} 8010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent 80115bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr) 80125bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{ 80135bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // flags to stream type mapping 80145bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { 80155bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_ENFORCED_AUDIBLE; 80165bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 80175bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) { 80185bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_BLUETOOTH_SCO; 80195bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 802079ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) { 802179ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi return AUDIO_STREAM_TTS; 802279ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi } 80235bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 80245bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi // usage to stream type mapping 80255bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi switch (attr->usage) { 80265bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_MEDIA: 80275bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_GAME: 80285bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 80295bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_MUSIC; 8030223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: 8031e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent if (isStreamActive(AUDIO_STREAM_ALARM)) { 8032e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent return AUDIO_STREAM_ALARM; 8033e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent } 8034e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent if (isStreamActive(AUDIO_STREAM_RING)) { 8035e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent return AUDIO_STREAM_RING; 8036e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent } 8037e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent if (isInCall()) { 8038e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent return AUDIO_STREAM_VOICE_CALL; 8039e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent } 8040223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent return AUDIO_STREAM_ACCESSIBILITY; 80415bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ASSISTANCE_SONIFICATION: 80425bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_SYSTEM; 80435bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION: 80445bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_VOICE_CALL; 80455bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 80465bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: 80475bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_DTMF; 80485bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 80495bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_ALARM: 80505bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_ALARM; 80515bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: 80525bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_RING; 80535bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 80545bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION: 80555bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: 80565bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: 80575bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: 80585bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_NOTIFICATION_EVENT: 80595bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_NOTIFICATION; 80605bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi 80615bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi case AUDIO_USAGE_UNKNOWN: 80625bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi default: 80635bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi return AUDIO_STREAM_MUSIC; 80645bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi } 80655bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi} 8066e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent 8067e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentbool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa) { 8068e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent // has flags that map to a strategy? 8069e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) { 8070e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent return true; 8071e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent } 8072e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent 8073e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent // has known usage? 8074e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent switch (paa->usage) { 8075e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_UNKNOWN: 8076e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_MEDIA: 8077e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_VOICE_COMMUNICATION: 8078e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: 8079e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_ALARM: 8080e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_NOTIFICATION: 8081e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: 8082e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: 8083e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: 8084e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: 8085e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_NOTIFICATION_EVENT: 8086e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: 8087e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 8088e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_ASSISTANCE_SONIFICATION: 8089e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent case AUDIO_USAGE_GAME: 8090275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent case AUDIO_USAGE_VIRTUAL_SOURCE: 8091e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent break; 8092e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent default: 8093e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent return false; 8094e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent } 8095e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent return true; 8096e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent} 8097e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent 8098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; // namespace android 8099