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