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