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