AudioPolicyManager.cpp revision b71e58b64cd4992355cf6afaf3f3530f723bc72c
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>
41e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#include <hardware_legacy/audio_policy_conf.h>
423b73df74357b33869b39a1d69427673c780bd805Eric Laurent#include <media/AudioParameter.h>
43d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include "AudioPolicyManager.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),
1033a4311c68348f728558e87b5db67d47605783890Eric Laurent};
1043a4311c68348f728558e87b5db67d47605783890Eric Laurent
1053a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFlagNameToEnumTable[] = {
1063a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT),
1073a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
1083a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST),
1093a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
1103a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
1113a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
1123a4311c68348f728558e87b5db67d47605783890Eric Laurent};
1133a4311c68348f728558e87b5db67d47605783890Eric Laurent
1143a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFormatNameToEnumTable[] = {
1153a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT),
1163a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT),
1173a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT),
1183a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT),
1193a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT),
1203a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED),
1213a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_MP3),
1223a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_AAC),
1233a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_VORBIS),
1243a4311c68348f728558e87b5db67d47605783890Eric Laurent};
1253a4311c68348f728558e87b5db67d47605783890Eric Laurent
1263a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sOutChannelsNameToEnumTable[] = {
1273a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO),
1283a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
1293a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
1303a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
1313a4311c68348f728558e87b5db67d47605783890Eric Laurent};
1323a4311c68348f728558e87b5db67d47605783890Eric Laurent
1333a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sInChannelsNameToEnumTable[] = {
1343a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO),
1353a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO),
1363a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK),
1373a4311c68348f728558e87b5db67d47605783890Eric Laurent};
1383a4311c68348f728558e87b5db67d47605783890Eric Laurent
1393a4311c68348f728558e87b5db67d47605783890Eric Laurent
1403a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::stringToEnum(const struct StringToEnum *table,
1413a4311c68348f728558e87b5db67d47605783890Eric Laurent                                              size_t size,
1423a4311c68348f728558e87b5db67d47605783890Eric Laurent                                              const char *name)
1433a4311c68348f728558e87b5db67d47605783890Eric Laurent{
1443a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i < size; i++) {
1453a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (strcmp(table[i].name, name) == 0) {
1463a4311c68348f728558e87b5db67d47605783890Eric Laurent            ALOGV("stringToEnum() found %s", table[i].name);
1473a4311c68348f728558e87b5db67d47605783890Eric Laurent            return table[i].value;
1483a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
1493a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
1503a4311c68348f728558e87b5db67d47605783890Eric Laurent    return 0;
1513a4311c68348f728558e87b5db67d47605783890Eric Laurent}
1523a4311c68348f728558e87b5db67d47605783890Eric Laurent
1533a4311c68348f728558e87b5db67d47605783890Eric Laurentconst char *AudioPolicyManager::enumToString(const struct StringToEnum *table,
1543a4311c68348f728558e87b5db67d47605783890Eric Laurent                                              size_t size,
1553a4311c68348f728558e87b5db67d47605783890Eric Laurent                                              uint32_t value)
1563a4311c68348f728558e87b5db67d47605783890Eric Laurent{
1573a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i < size; i++) {
1583a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (table[i].value == value) {
1593a4311c68348f728558e87b5db67d47605783890Eric Laurent            return table[i].name;
1603a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
1613a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
1623a4311c68348f728558e87b5db67d47605783890Eric Laurent    return "";
1633a4311c68348f728558e87b5db67d47605783890Eric Laurent}
1643a4311c68348f728558e87b5db67d47605783890Eric Laurent
1653a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::stringToBool(const char *value)
1663a4311c68348f728558e87b5db67d47605783890Eric Laurent{
1673a4311c68348f728558e87b5db67d47605783890Eric Laurent    return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0));
1683a4311c68348f728558e87b5db67d47605783890Eric Laurent}
1693a4311c68348f728558e87b5db67d47605783890Eric Laurent
1703a4311c68348f728558e87b5db67d47605783890Eric Laurent
1713a4311c68348f728558e87b5db67d47605783890Eric Laurent// ----------------------------------------------------------------------------
172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AudioPolicyInterface implementation
173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
176e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
1773b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                          audio_policy_dev_state_t state,
178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                  const char *device_address)
179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1803a4311c68348f728558e87b5db67d47605783890Eric Laurent    String8 address = String8(device_address);
181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address);
183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // connect/disconnect only 1 device at a time
185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle output devices
188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_output_device(device)) {
189d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        SortedVector <audio_io_handle_t> outputs;
190d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
1913a4311c68348f728558e87b5db67d47605783890Eric Laurent        sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device,
1923a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                            address,
1932f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent                                                            0);
1943a4311c68348f728558e87b5db67d47605783890Eric Laurent        ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
1953a4311c68348f728558e87b5db67d47605783890Eric Laurent
196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // save a copy of the opened output descriptors before any output is opened or closed
197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mPreviousOutputs = mOutputs;
199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        switch (state)
200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle output device connection
2023b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE:
2033a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device already connected: %x", device);
205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setDeviceConnectionState() connecting device %x", device);
208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2093a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (checkOutputsForDevice(device, state, outputs, address) != NO_ERROR) {
210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
212d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                  outputs.size());
214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // register new device as available
2153a4311c68348f728558e87b5db67d47605783890Eric Laurent            index = mAvailableOutputDevices.add(devDesc);
2163a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
2173a4311c68348f728558e87b5db67d47605783890Eric Laurent                mAvailableOutputDevices[index]->mId = nextUniqueId();
2183a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
2193a4311c68348f728558e87b5db67d47605783890Eric Laurent                return NO_MEMORY;
220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            break;
223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle output device disconnection
2243b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
2253a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index < 0) {
226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device not connected: %x", device);
227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setDeviceConnectionState() disconnecting device %x", device);
231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // remove device from available output devices
2323a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.remove(devDesc);
2333a4311c68348f728558e87b5db67d47605783890Eric Laurent
2343a4311c68348f728558e87b5db67d47605783890Eric Laurent            checkOutputsForDevice(device, state, outputs, address);
235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // not currently handling multiple simultaneous submixes: ignoring remote submix
236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            //   case and address
237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } break;
238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("setDeviceConnectionState() invalid state: %x", state);
241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2443a4311c68348f728558e87b5db67d47605783890Eric Laurent        // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
2453a4311c68348f728558e87b5db67d47605783890Eric Laurent        // output is suspended before any tracks are moved to it
246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkA2dpSuspend();
247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkOutputForAllStrategies();
248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // outputs must be closed after checkOutputForAllStrategies() is executed
249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputs.isEmpty()) {
250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < outputs.size(); i++) {
251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]);
252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // close unused outputs after device disconnection or direct outputs that have been
253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // opened by checkOutputsForDevice() to query dynamic parameters
2543b73df74357b33869b39a1d69427673c780bd805Eric Laurent                if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                         (desc->mDirectOpenCount == 0))) {
257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    closeOutput(outputs[i]);
258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2603a4311c68348f728558e87b5db67d47605783890Eric Laurent            // check again after closing A2DP output to reset mA2dpSuspended if needed
2613a4311c68348f728558e87b5db67d47605783890Eric Laurent            checkA2dpSuspend();
262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        updateDevicesAndOutputs();
265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // do not force device change on duplicated output because if device is 0, it will
267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // also force a device 0 for the two outputs it is duplicated to which may override
268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // a valid device selection on those outputs.
269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setOutputDevice(mOutputs.keyAt(i),
2701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                            getNewOutputDevice(mOutputs.keyAt(i), true /*fromCache*/),
271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            !mOutputs.valueAt(i)->isDuplicated(),
272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            0);
273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
275b71e58b64cd4992355cf6afaf3f3530f723bc72cEric Laurent        return NO_ERROR;
276d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }  // end if is output device
277d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle input devices
279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_input_device(device)) {
280d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        SortedVector <audio_io_handle_t> inputs;
281d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2823a4311c68348f728558e87b5db67d47605783890Eric Laurent        sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device,
2833a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                            address,
2842f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent                                                            0);
285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2863a4311c68348f728558e87b5db67d47605783890Eric Laurent        ssize_t index = mAvailableInputDevices.indexOf(devDesc);
287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        switch (state)
288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle input device connection
2903b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
2913a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device already connected: %d", device);
293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
295d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (checkInputsForDevice(device, state, inputs, address) != NO_ERROR) {
296d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                return INVALID_OPERATION;
297d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
298d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2993a4311c68348f728558e87b5db67d47605783890Eric Laurent            index = mAvailableInputDevices.add(devDesc);
3003a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
3013a4311c68348f728558e87b5db67d47605783890Eric Laurent                mAvailableInputDevices[index]->mId = nextUniqueId();
3023a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
3033a4311c68348f728558e87b5db67d47605783890Eric Laurent                return NO_MEMORY;
3043a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
305d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } break;
306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle input device disconnection
3083b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
3093a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index < 0) {
310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device not connected: %d", device);
311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
313d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            checkInputsForDevice(device, state, inputs, address);
3143a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.remove(devDesc);
315d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } break;
316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("setDeviceConnectionState() invalid state: %x", state);
319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
322d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        closeAllInputs();
323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
325d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } // end if is input device
326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW("setDeviceConnectionState() invalid device: %x", device);
328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return BAD_VALUE;
329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
331e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                  const char *device_address)
333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3343b73df74357b33869b39a1d69427673c780bd805Eric Laurent    audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 address = String8(device_address);
3363a4311c68348f728558e87b5db67d47605783890Eric Laurent    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device,
3373a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                        String8(device_address),
3382f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent                                                        0);
3393a4311c68348f728558e87b5db67d47605783890Eric Laurent    ssize_t index;
3403a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceVector *deviceVector;
3413a4311c68348f728558e87b5db67d47605783890Eric Laurent
342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_output_device(device)) {
3433a4311c68348f728558e87b5db67d47605783890Eric Laurent        deviceVector = &mAvailableOutputDevices;
344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (audio_is_input_device(device)) {
3453a4311c68348f728558e87b5db67d47605783890Eric Laurent        deviceVector = &mAvailableInputDevices;
3463a4311c68348f728558e87b5db67d47605783890Eric Laurent    } else {
3473a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGW("getDeviceConnectionState() invalid device type %08x", device);
3483a4311c68348f728558e87b5db67d47605783890Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3513a4311c68348f728558e87b5db67d47605783890Eric Laurent    index = deviceVector->indexOf(devDesc);
3523a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (index >= 0) {
3533a4311c68348f728558e87b5db67d47605783890Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_AVAILABLE;
3543a4311c68348f728558e87b5db67d47605783890Eric Laurent    } else {
3553a4311c68348f728558e87b5db67d47605783890Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
3563a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
359e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setPhoneState(audio_mode_t state)
360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setPhoneState() state %d", state);
362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t newDevice = AUDIO_DEVICE_NONE;
3633b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state < 0 || state >= AUDIO_MODE_CNT) {
364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("setPhoneState() invalid state %d", state);
365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (state == mPhoneState ) {
369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("setPhoneState() setting same state %d", state);
370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if leaving call state, handle special case of active streams
374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // pertaining to sonification strategy see handleIncallSonification()
375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isInCall()) {
376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setPhoneState() in call state management: new state is %d", state);
3773b73df74357b33869b39a1d69427673c780bd805Eric Laurent        for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
3783b73df74357b33869b39a1d69427673c780bd805Eric Laurent            handleIncallSonification((audio_stream_type_t)stream, false, true);
379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // store previous phone state for management of sonification strategy below
383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int oldState = mPhoneState;
384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPhoneState = state;
385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    bool force = false;
386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // are we entering or starting a call
388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!isStateInCall(oldState) && isStateInCall(state)) {
389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("  Entering call in setPhoneState()");
390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // force routing command to audio hardware when starting a call
391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // even if no device change is needed
392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        force = true;
393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j];
396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (isStateInCall(oldState) && !isStateInCall(state)) {
398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("  Exiting call in setPhoneState()");
399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // force routing command to audio hardware when exiting a call
400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // even if no device change is needed
401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        force = true;
402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    sVolumeProfiles[AUDIO_STREAM_DTMF][j];
405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (isStateInCall(state) && (state != oldState)) {
407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("  Switching between telephony and VoIP in setPhoneState()");
408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // force routing command to audio hardware when switching between telephony and VoIP
409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // even if no device change is needed
410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        force = true;
411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check for device and output changes triggered by new phone state
4141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkA2dpSuspend();
416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForAllStrategies();
417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // force routing command to audio hardware when ending call
422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // even if no device change is needed
423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) {
424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        newDevice = hwOutputDesc->device();
425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int delayMs = 0;
428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(state)) {
429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        nsecs_t sysTime = systemTime();
430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // mute media and sonification strategies and delay device switch by the largest
433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // latency of any output where either strategy is active.
434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // This avoid sending the ring tone or music tail into the earpiece or headset.
435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if ((desc->isStrategyActive(STRATEGY_MEDIA,
436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                     SONIFICATION_HEADSET_MUSIC_DELAY,
437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                     sysTime) ||
438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    desc->isStrategyActive(STRATEGY_SONIFICATION,
439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                         SONIFICATION_HEADSET_MUSIC_DELAY,
440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                         sysTime)) &&
441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    (delayMs < (int)desc->mLatency*2)) {
442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                delayMs = desc->mLatency*2;
443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i));
448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS,
449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // change routing is necessary
454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    setOutputDevice(mPrimaryOutput, newDevice, force, delayMs);
455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if entering in call state, handle special case of active streams
457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // pertaining to sonification strategy see handleIncallSonification()
458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(state)) {
459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setPhoneState() in call state management: new state is %d", state);
4603b73df74357b33869b39a1d69427673c780bd805Eric Laurent        for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
4613b73df74357b33869b39a1d69427673c780bd805Eric Laurent            handleIncallSonification((audio_stream_type_t)stream, true, true);
462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
4663b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state == AUDIO_MODE_RINGTONE &&
4673b73df74357b33869b39a1d69427673c780bd805Eric Laurent        isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mLimitRingtoneVolume = true;
469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mLimitRingtoneVolume = false;
471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
474e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
4753b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                         audio_policy_forced_cfg_t config)
476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    bool forceVolumeReeval = false;
480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch(usage) {
4813b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
4823b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
4833b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_NONE) {
484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        forceVolumeReeval = true;
488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mForceUse[usage] = config;
489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
4903b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_POLICY_FORCE_FOR_MEDIA:
4913b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
4923b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
4933b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
4943b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
4953b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_NO_BT_A2DP) {
496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mForceUse[usage] = config;
500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
5013b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_POLICY_FORCE_FOR_RECORD:
5023b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
5033b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_NONE) {
504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mForceUse[usage] = config;
508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
5093b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_POLICY_FORCE_FOR_DOCK:
5103b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
5113b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
5123b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
5133b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
5143b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        forceVolumeReeval = true;
518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mForceUse[usage] = config;
519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
5203b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_POLICY_FORCE_FOR_SYSTEM:
5213b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (config != AUDIO_POLICY_FORCE_NONE &&
5223b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        forceVolumeReeval = true;
526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mForceUse[usage] = config;
527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("setForceUse() invalid usage %d", usage);
530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check for device and output changes triggered by new force usage
534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkA2dpSuspend();
535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForAllStrategies();
536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_io_handle_t output = mOutputs.keyAt(i);
5391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        audio_devices_t newDevice = getNewOutputDevice(output, true /*fromCache*/);
540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            applyStreamVolumes(output, newDevice, 0, true);
543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t activeInput = getActiveInput();
547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (activeInput != 0) {
5481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        setInputDevice(activeInput, getNewInputDevice(activeInput));
549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
553e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return mForceUse[usage];
556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
558e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setSystemProperty(const char* property, const char* value)
559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setSystemProperty() property %s, value %s", property, value);
561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Find a direct output profile compatible with the parameters passed, even if the input flags do
564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// not explicitly request a direct output
5651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::IOProfile> AudioPolicyManager::getProfileForDirectOutput(
566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_devices_t device,
567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               uint32_t samplingRate,
568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_format_t format,
569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_channel_mask_t channelMask,
570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_output_flags_t flags)
571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++) {
573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
5771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
5783a4311c68348f728558e87b5db67d47605783890Eric Laurent            bool found = false;
579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (profile->isCompatibleProfile(device, samplingRate, format,
581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           channelMask,
582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
5833a4311c68348f728558e87b5db67d47605783890Eric Laurent                    found = true;
584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (profile->isCompatibleProfile(device, samplingRate, format,
587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           channelMask,
588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           AUDIO_OUTPUT_FLAG_DIRECT)) {
5893a4311c68348f728558e87b5db67d47605783890Eric Laurent                    found = true;
590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
5923a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (found && (mAvailableOutputDevices.types() & profile->mSupportedDevices.types())) {
5933a4311c68348f728558e87b5db67d47605783890Eric Laurent                return profile;
5943a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
600e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    uint32_t samplingRate,
602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    audio_format_t format,
603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    audio_channel_mask_t channelMask,
6043b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                    audio_output_flags_t flags,
605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    const audio_offload_info_t *offloadInfo)
606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t output = 0;
608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t latency = 0;
6093b73df74357b33869b39a1d69427673c780bd805Eric Laurent    routing_strategy strategy = getStrategy(stream);
610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          device, stream, samplingRate, format, channelMask, flags);
613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mCurOutput != 0) {
616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mTestOutputs[mCurOutput] == 0) {
620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("getOutput() opening test output");
621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mDevice = mTestDevice;
623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mSamplingRate = mTestSamplingRate;
624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mFormat = mTestFormat;
625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mChannelMask = mTestChannels;
626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mLatency = mTestLatencyMs;
6273b73df74357b33869b39a1d69427673c780bd805Eric Laurent            outputDesc->mFlags =
6283b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mRefCount[stream] = 0;
630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice,
631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            &outputDesc->mSamplingRate,
632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            &outputDesc->mFormat,
633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            &outputDesc->mChannelMask,
634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            &outputDesc->mLatency,
635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            outputDesc->mFlags,
636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo);
637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (mTestOutputs[mCurOutput]) {
638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioParameter outputCmd = AudioParameter();
639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputCmd.addInt(String8("set_id"),mCurOutput);
640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                addOutput(mTestOutputs[mCurOutput], outputDesc);
642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mTestOutputs[mCurOutput];
645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open a direct output if required by specified parameters
649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //force direct flag if offload flag is set: offloading implies a direct output stream
650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and all common behaviors are driven by checking only the direct flag
651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // this should normally be set appropriately in the policy configuration file
652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
6533b73df74357b33869b39a1d69427673c780bd805Eric Laurent        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not allow offloading if one non offloadable effect is enabled. This prevents from
657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // creating an offloaded track and tearing it down immediately after start when audioflinger
658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // detects there is an active non offloadable effect.
659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // FIXME: We should check the audio session here but we do not have it in this context.
660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // This may prevent offloading in rare situations where effects are left active by apps
661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the background.
6621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    sp<IOProfile> profile;
663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            !isNonOffloadableEffectEnabled()) {
665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        profile = getProfileForDirectOutput(device,
666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           samplingRate,
667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           format,
668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           channelMask,
669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           (audio_output_flags_t)flags);
670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
6721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (profile != 0) {
673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *outputDesc = NULL;
674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (!desc->isDuplicated() && (profile == desc->mProfile)) {
678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc = desc;
679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // reuse direct output if currently open and configured with same parameters
680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if ((samplingRate == outputDesc->mSamplingRate) &&
681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (format == outputDesc->mFormat) &&
682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (channelMask == outputDesc->mChannelMask)) {
683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->mDirectOpenCount++;
684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    return mOutputs.keyAt(i);
686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // close direct output if currently open and configured with different parameters
690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc != NULL) {
6911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            closeOutput(outputDesc->mIoHandle);
692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc = new AudioOutputDescriptor(profile);
694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mDevice = device;
695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mSamplingRate = samplingRate;
696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mFormat = format;
697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mChannelMask = channelMask;
698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mLatency = 0;
699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags);
700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mRefCount[stream] = 0;
701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mStopTime[stream] = 0;
702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mDirectOpenCount = 1;
703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        output = mpClientInterface->openOutput(profile->mModule->mHandle,
704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        &outputDesc->mDevice,
705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        &outputDesc->mSamplingRate,
706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        &outputDesc->mFormat,
707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        &outputDesc->mChannelMask,
708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        &outputDesc->mLatency,
709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        outputDesc->mFlags,
710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        offloadInfo);
711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // only accept an output with the requested parameters
713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (output == 0 ||
714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (format != AUDIO_FORMAT_DEFAULT && format != outputDesc->mFormat) ||
716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (channelMask != 0 && channelMask != outputDesc->mChannelMask)) {
717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    "format %d %d, channelMask %04x %04x", output, samplingRate,
719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->mChannelMask);
721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (output != 0) {
722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->closeOutput(output);
723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            delete outputDesc;
725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return 0;
726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_io_handle_t srcOutput = getOutputForEffect();
728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        addOutput(output, outputDesc);
729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_io_handle_t dstOutput = getOutputForEffect();
730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (dstOutput == output) {
731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mPreviousOutputs = mOutputs;
734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("getOutput() returns new direct output %d", output);
735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return output;
736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // ignoring channel mask due to downmix capability in mixer
739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open a non direct output
741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // for non direct outputs, only PCM is supported
743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_linear_pcm(format)) {
744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // get which output is suitable for the specified stream. The actual
745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // routing change will happen when startOutput() will be called
746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        output = selectOutput(outputs, flags);
749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getOutput() returns output %d", output);
754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return output;
756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
758e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
7593b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                       audio_output_flags_t flags)
760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // select one output among several that provide a path to a particular device or set of
762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // devices (the list was previously build by getOutputsForDevice()).
763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // The priority is as follows:
764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: the output with the highest number of requested policy flags
765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: the primary output
766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 3: the first output in the list
767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 0) {
769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 1) {
772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputs[0];
773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int maxCommonFlags = 0;
776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t outputFlags = 0;
777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t outputPrimary = 0;
778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs.size(); i++) {
780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]);
781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputDesc->isDuplicated()) {
7823b73df74357b33869b39a1d69427673c780bd805Eric Laurent            int commonFlags = popcount(outputDesc->mProfile->mFlags & flags);
783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (commonFlags > maxCommonFlags) {
784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputFlags = outputs[i];
785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                maxCommonFlags = commonFlags;
786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputPrimary = outputs[i];
790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputFlags != 0) {
795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputFlags;
796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputPrimary != 0) {
798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputPrimary;
799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs[0];
802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
804e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startOutput(audio_io_handle_t output,
8053b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                             audio_stream_type_t stream,
806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             int session)
807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session);
809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("startOutput() unknown output %d", output);
812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // increment usage count for this stream on the requested output:
818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // NOTE that the usage count is the same for duplicated output and hardware output which is
819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    outputDesc->changeRefCount(stream, 1);
821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->mRefCount[stream] == 1) {
8231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/);
824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        routing_strategy strategy = getStrategy(stream);
825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            (strategy == STRATEGY_SONIFICATION_RESPECTFUL);
827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        uint32_t waitMs = 0;
828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool force = false;
829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (desc != outputDesc) {
832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // force a device change if any other output is managed by the same hw
833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // module and has a current device selection that differs from selected device.
834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // In this case, the audio HAL must receive the new device selection so that it can
835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // change the device currently selected by the other active output.
836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (outputDesc->sharesHwModuleWith(desc) &&
837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    desc->device() != newDevice) {
838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    force = true;
839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // wait for audio on other active outputs to be presented when starting
841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // a notification so that audio focus effect can propagate.
842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                uint32_t latency = desc->latency();
843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    waitMs = latency;
845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        uint32_t muteWaitMs = setOutputDevice(output, newDevice, force);
849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle special case for sonification while in call
851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (isInCall()) {
852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            handleIncallSonification(stream, true, false);
853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // apply volume rules for current stream and device if necessary
856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkAndSetVolume(stream,
857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          mStreams[stream].getVolumeIndex(newDevice),
858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          output,
859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          newDevice);
860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // update the outputs if starting an output with a stream that can affect notification
862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // routing
863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        handleNotificationRoutingForStream(stream);
864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (waitMs > muteWaitMs) {
865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            usleep((waitMs - muteWaitMs) * 2 * 1000);
866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
872e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
8733b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                            audio_stream_type_t stream,
874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int session)
875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopOutput() unknown output %d", output);
880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle special case for sonification while in call
886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isInCall()) {
887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        handleIncallSonification(stream, false, false);
888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->mRefCount[stream] > 0) {
891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // decrement usage count of this stream on the output
892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->changeRefCount(stream, -1);
893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // store time at which the stream was stopped - see isStreamActive()
894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mRefCount[stream] == 0) {
895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStopTime[stream] = systemTime();
8961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/);
897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // delay the device switch by twice the latency because stopOutput() is executed when
898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // the track stop() command is received and at that time the audio track buffer can
899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // still contain data that needs to be drained. The latency only covers the audio HAL
900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // and kernel buffers. Also the latency does not always include additional delay in the
901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // audio path (audio DSP, CODEC ...)
902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setOutputDevice(output, newDevice, false, outputDesc->mLatency*2);
903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // force restoring the device selection on other active outputs if it differs from the
905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // one being selected for this output
906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < mOutputs.size(); i++) {
907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                audio_io_handle_t curOutput = mOutputs.keyAt(i);
908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *desc = mOutputs.valueAt(i);
909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (curOutput != output &&
910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        desc->isActive() &&
911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputDesc->sharesHwModuleWith(desc) &&
912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (newDevice != desc->device())) {
913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    setOutputDevice(curOutput,
9141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                    getNewOutputDevice(curOutput, false /*fromCache*/),
915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    true,
916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    outputDesc->mLatency*2);
917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // update the outputs if stopping one with a stream that can affect notification routing
920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            handleNotificationRoutingForStream(stream);
921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopOutput() refcount is already 0 for output %d", output);
925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
929e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::releaseOutput(audio_io_handle_t output)
930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseOutput() %d", output);
932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("releaseOutput() releasing unknown output %d", output);
935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int testIndex = testOutputIndex(output);
940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (testIndex != 0) {
941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->isActive()) {
943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->closeOutput(output);
944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            delete mOutputs.valueAt(index);
945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mOutputs.removeItem(output);
946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mTestOutputs[testIndex] = 0;
947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *desc = mOutputs.valueAt(index);
9533b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (desc->mDirectOpenCount <= 0) {
955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("releaseOutput() invalid open count %d for output %d",
956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                              desc->mDirectOpenCount, output);
957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (--desc->mDirectOpenCount == 0) {
960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            closeOutput(output);
961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // If effects where present on the output, audioflinger moved them to the primary
962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // output by default: move them back to the appropriate output.
963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t dstOutput = getOutputForEffect();
964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (dstOutput != mPrimaryOutput) {
965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput);
966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
972e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,
973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    uint32_t samplingRate,
974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    audio_format_t format,
975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    audio_channel_mask_t channelMask,
9763b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                    audio_in_acoustics_t acoustics)
977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t input = 0;
979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = getDeviceForInputSource(inputSource);
980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x",
982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          inputSource, samplingRate, format, channelMask, acoustics);
983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("getInput() could not find device for inputSource %d", inputSource);
986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // adapt channel selection to input source
990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch(inputSource) {
991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_UPLINK:
992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_DOWNLINK:
995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK;
996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_CALL:
998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK;
999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
1000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
1001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
1002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
10041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    sp<IOProfile> profile = getInputProfile(device,
1005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                         samplingRate,
1006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                         format,
1007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                         channelMask);
10081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (profile == 0) {
1009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d, "
1010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                "channelMask %04x",
1011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                device, samplingRate, format, channelMask);
1012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
1013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (profile->mModule->mHandle == 0) {
1016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGE("getInput(): HW module %s not opened", profile->mModule->mName);
1017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
1018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile);
1021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mInputSource = inputSource;
1023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mDevice = device;
1024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mSamplingRate = samplingRate;
1025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mFormat = format;
1026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mChannelMask = channelMask;
1027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mRefCount = 0;
1028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    input = mpClientInterface->openInput(profile->mModule->mHandle,
1029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    &inputDesc->mDevice,
1030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    &inputDesc->mSamplingRate,
1031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    &inputDesc->mFormat,
1032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    &inputDesc->mChannelMask);
1033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // only accept input with the exact requested set of parameters
1035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (input == 0 ||
1036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        (samplingRate != inputDesc->mSamplingRate) ||
1037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        (format != inputDesc->mFormat) ||
1038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        (channelMask != inputDesc->mChannelMask)) {
1039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGI("getInput() failed opening input: samplingRate %d, format %d, channelMask %x",
1040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                samplingRate, format, channelMask);
1041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (input != 0) {
1042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->closeInput(input);
1043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete inputDesc;
1045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
1046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1047d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    addInput(input, inputDesc);
1048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return input;
1049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1051e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startInput(audio_io_handle_t input)
1052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("startInput() input %d", input);
1054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("startInput() unknown input %d", input);
1057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mTestInput == 0)
1063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
1065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // refuse 2 active AudioRecord clients at the same time except if the active input
1066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // uses AUDIO_SOURCE_HOTWORD in which case it is closed.
1067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_io_handle_t activeInput = getActiveInput();
1068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!isVirtualInputDevice(inputDesc->mDevice) && activeInput != 0) {
1069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput);
1070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
1071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("startInput() preempting already started low-priority input %d", activeInput);
1072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                stopInput(activeInput);
1073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                releaseInput(activeInput);
1074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
1075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("startInput() input %d failed: other input already started", input);
1076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
1077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
10811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    setInputDevice(input, getNewInputDevice(input), true /* force */);
1082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // automatically enable the remote submix output when input is started
1084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
10863b73df74357b33869b39a1d69427673c780bd805Eric Laurent                AUDIO_POLICY_DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS);
1087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
1090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mRefCount = 1;
1092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1095e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopInput(audio_io_handle_t input)
1096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("stopInput() input %d", input);
1098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopInput() unknown input %d", input);
1101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (inputDesc->mRefCount == 0) {
1106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopInput() input %d already stopped", input);
1107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
1109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // automatically disable the remote submix output when input is stopped
1110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
11123b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS);
1113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
11151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        resetInputDevice(input);
1116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        inputDesc->mRefCount = 0;
1117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
1118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1121e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::releaseInput(audio_io_handle_t input)
1122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseInput() %d", input);
1124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("releaseInput() releasing unknown input %d", input);
1127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
1128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->closeInput(input);
1130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    delete mInputs.valueAt(index);
1131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mInputs.removeItem(input);
1132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseInput() exit");
1133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1135d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::closeAllInputs() {
1136d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    for(size_t input_index = 0; input_index < mInputs.size(); input_index++) {
1137d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        mpClientInterface->closeInput(mInputs.keyAt(input_index));
1138d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }
1139d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    mInputs.clear();
1140d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
1141d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
1142e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
1143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int indexMin,
1144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int indexMax)
1145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
1147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (indexMin < 0 || indexMin >= indexMax) {
1148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax);
1149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
1150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mStreams[stream].mIndexMin = indexMin;
1152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mStreams[stream].mIndexMax = indexMax;
1153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1155e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
1156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      int index,
1157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      audio_devices_t device)
1158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
1161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device)) {
1164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Force max volume if stream cannot be muted
1168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
1169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
1171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          stream, device, index);
1172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
1174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // clear all device specific values
1175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_OUT_DEFAULT) {
1176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[stream].mIndexCur.clear();
1177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mStreams[stream].mIndexCur.add(device, index);
1179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // compute and apply stream volume on all outputs according to connected device
1181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    status_t status = NO_ERROR;
1182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
1183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_devices_t curDevice =
1184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForVolume(mOutputs.valueAt(i)->device());
1185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) {
1186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
1187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (volStatus != NO_ERROR) {
1188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                status = volStatus;
1189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return status;
1193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1195e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
1196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      int *index,
1197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      audio_devices_t device)
1198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index == NULL) {
1200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device)) {
1203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to
1206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // the strategy the stream belongs to.
1207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_OUT_DEFAULT) {
1208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
1209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    device = getDeviceForVolume(device);
1211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    *index =  mStreams[stream].getVolumeIndex(device);
1213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
1214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1217e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutputForEffects(
1218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            const SortedVector<audio_io_handle_t>& outputs)
1219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // select one output among several suitable for global effects.
1221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // The priority is as follows:
1222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: An offloaded output. If the effect ends up not being offloadable,
1223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //    AudioFlinger will invalidate the track and the offloaded output
1224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //    will be closed causing the effect to be moved to a PCM output.
1225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: A deep buffer output
1226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 3: the first output in the list
1227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 0) {
1229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
1230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t outputOffloaded = 0;
1233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t outputDeepBuffer = 0;
1234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs.size(); i++) {
1236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]);
1237d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags);
1238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
1239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputOffloaded = outputs[i];
1240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
1242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDeepBuffer = outputs[i];
1243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d",
1247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          outputOffloaded, outputDeepBuffer);
1248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputOffloaded != 0) {
1249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputOffloaded;
1250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDeepBuffer != 0) {
1252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputDeepBuffer;
1253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs[0];
1256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1258e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc)
1259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // apply simple rule where global effects are attached to the same output as MUSIC streams
1261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
12623b73df74357b33869b39a1d69427673c780bd805Eric Laurent    routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
1263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
1264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs);
1265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t output = selectOutputForEffects(dstOutputs);
1267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getOutputForEffect() got output %d for fx %s flags %x",
1268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          output, (desc == NULL) ? "unspecified" : desc->name,  (desc == NULL) ? 0 : desc->flags);
1269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return output;
1271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1273e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
1274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                audio_io_handle_t io,
1275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                uint32_t strategy,
1276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                int session,
1277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                int id)
1278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(io);
1280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        index = mInputs.indexOfKey(io);
1282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (index < 0) {
1283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("registerEffect() unknown io %d", io);
1284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return INVALID_OPERATION;
1285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) {
1289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB",
1290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                desc->name, desc->memoryUsage);
1291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mTotalEffectsMemory += desc->memoryUsage;
1294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d",
1295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc->name, io, strategy, session, id);
1296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory);
1297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    EffectDescriptor *pDesc = new EffectDescriptor();
1299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t));
1300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    pDesc->mIo = io;
1301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    pDesc->mStrategy = (routing_strategy)strategy;
1302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    pDesc->mSession = session;
1303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    pDesc->mEnabled = false;
1304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mEffects.add(id, pDesc);
1306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1310e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::unregisterEffect(int id)
1311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mEffects.indexOfKey(id);
1313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("unregisterEffect() unknown effect ID %d", id);
1315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    EffectDescriptor *pDesc = mEffects.valueAt(index);
1319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    setEffectEnabled(pDesc, false);
1321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) {
1323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("unregisterEffect() memory %d too big for total %d",
1324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
1325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        pDesc->mDesc.memoryUsage = mTotalEffectsMemory;
1326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mTotalEffectsMemory -= pDesc->mDesc.memoryUsage;
1328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d",
1329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
1330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mEffects.removeItem(id);
1332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    delete pDesc;
1333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1337e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(int id, bool enabled)
1338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mEffects.indexOfKey(id);
1340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("unregisterEffect() unknown effect ID %d", id);
1342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return setEffectEnabled(mEffects.valueAt(index), enabled);
1346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1348e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(EffectDescriptor *pDesc, bool enabled)
1349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (enabled == pDesc->mEnabled) {
1351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setEffectEnabled(%s) effect already %s",
1352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             enabled?"true":"false", enabled?"enabled":"disabled");
1353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (enabled) {
1357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) {
1358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS",
1359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                 pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10);
1360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return INVALID_OPERATION;
1361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad;
1363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad);
1364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
1365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) {
1366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setEffectEnabled(false) CPU load %d too high for total %d",
1367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad);
1368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad;
1369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad;
1371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad);
1372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    pDesc->mEnabled = enabled;
1374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1377e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isNonOffloadableEffectEnabled()
1378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mEffects.size(); i++) {
1380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const EffectDescriptor * const pDesc = mEffects.valueAt(i);
1381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (pDesc->mEnabled && (pDesc->mStrategy == STRATEGY_MEDIA) &&
1382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ((pDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) {
1383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d",
1384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                  pDesc->mDesc.name, pDesc->mSession);
1385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
1386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
1389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1391e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
1392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    nsecs_t sysTime = systemTime();
1394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
1395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
13963b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
1397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
1398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
1401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1403e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream,
14043b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                    uint32_t inPastMs) const
1405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    nsecs_t sysTime = systemTime();
1407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
1408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
1409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
14103b73df74357b33869b39a1d69427673c780bd805Eric Laurent                outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
1411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
1412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
1415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1417e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isSourceActive(audio_source_t source) const
1418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
1420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const AudioInputDescriptor * inputDescriptor = mInputs.valueAt(i);
1421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((inputDescriptor->mInputSource == (int)source ||
14223b73df74357b33869b39a1d69427673c780bd805Eric Laurent                (source == AUDIO_SOURCE_VOICE_RECOGNITION &&
1423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                 inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD))
1424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             && (inputDescriptor->mRefCount > 0)) {
1425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
1426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
1429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1432e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::dump(int fd)
1433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
1435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
1436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
1437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
1439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
1440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput);
1442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
1443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
1444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
14453b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for communications %d\n",
14463b73df74357b33869b39a1d69427673c780bd805Eric Laurent             mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]);
1447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
14483b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA]);
1449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
14503b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD]);
1451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
14523b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK]);
1453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
14543b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM]);
1455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
1456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
14573a4311c68348f728558e87b5db67d47605783890Eric Laurent    snprintf(buffer, SIZE, " Available output devices:\n");
14583a4311c68348f728558e87b5db67d47605783890Eric Laurent    result.append(buffer);
14593a4311c68348f728558e87b5db67d47605783890Eric Laurent    write(fd, result.string(), result.size());
14603a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceDescriptor::dumpHeader(fd, 2);
14613a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
14623a4311c68348f728558e87b5db67d47605783890Eric Laurent        mAvailableOutputDevices[i]->dump(fd, 2);
14633a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
14643a4311c68348f728558e87b5db67d47605783890Eric Laurent    snprintf(buffer, SIZE, "\n Available input devices:\n");
14653a4311c68348f728558e87b5db67d47605783890Eric Laurent    write(fd, buffer, strlen(buffer));
14663a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceDescriptor::dumpHeader(fd, 2);
14673a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
14683a4311c68348f728558e87b5db67d47605783890Eric Laurent        mAvailableInputDevices[i]->dump(fd, 2);
14693a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
1470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nHW Modules dump:\n");
1472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++) {
1474d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1);
1475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, buffer, strlen(buffer));
1476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mHwModules[i]->dump(fd);
1477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nOutputs dump:\n");
1480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
1482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
1483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, buffer, strlen(buffer));
1484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mOutputs.valueAt(i)->dump(fd);
1485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nInputs dump:\n");
1488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
1490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
1491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, buffer, strlen(buffer));
1492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mInputs.valueAt(i)->dump(fd);
1493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nStreams dump:\n");
1496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE,
1498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             " Stream  Can be muted  Index Min  Index Max  Index Cur [device : index]...\n");
1499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
15003b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
1501d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        snprintf(buffer, SIZE, " %02zu      ", i);
1502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, buffer, strlen(buffer));
1503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[i].dump(fd);
1504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n",
1507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory);
1508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "Registered effects:\n");
1511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mEffects.size(); i++) {
1513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i));
1514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, buffer, strlen(buffer));
1515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mEffects.valueAt(i)->dump(fd);
1516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This function checks for the parameters which can be offloaded.
1523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This can be enhanced depending on the capability of the DSP and policy
1524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// of the system.
1525e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
1526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
1528d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent     " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
1529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.sample_rate, offloadInfo.channel_mask,
1530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.format,
1531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
1532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.has_video);
1533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check if offload has been disabled
1535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char propValue[PROPERTY_VALUE_MAX];
1536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (property_get("audio.offload.disable", propValue, "0")) {
1537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (atoi(propValue) != 0) {
1538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("offload disabled by audio.offload.disable=%s", propValue );
1539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
1540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check if stream type is music, then only allow offload as of now.
1544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
1545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
1546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
1547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
1548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //TODO: enable audio offloading with video when ready
1551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (offloadInfo.has_video)
1552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
1553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("isOffloadSupported: has_video == true, returning false");
1554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
1555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //If duration is less than minimum value defined in property, return false
1558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
1559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
1560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
1561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
1562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
1564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
1565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
1566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not allow offloading if one non offloadable effect is enabled. This prevents from
1569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // creating an offloaded track and tearing it down immediately after start when audioflinger
1570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // detects there is an active non offloadable effect.
1571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // FIXME: We should check the audio session here but we do not have it in this context.
1572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // This may prevent offloading in rare situations where effects are left active by apps
1573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the background.
1574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isNonOffloadableEffectEnabled()) {
1575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
1576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // See if there is a profile to support this.
1579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // AUDIO_DEVICE_NONE
15801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
1581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.sample_rate,
1582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.format,
1583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.channel_mask,
1584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
15851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
15861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return (profile != 0);
1587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
1590e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent// AudioPolicyManager
1591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
1592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
15933a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::nextUniqueId()
15943a4311c68348f728558e87b5db67d47605783890Eric Laurent{
15953a4311c68348f728558e87b5db67d47605783890Eric Laurent    return android_atomic_inc(&mNextUniqueId);
15963a4311c68348f728558e87b5db67d47605783890Eric Laurent}
15973a4311c68348f728558e87b5db67d47605783890Eric Laurent
1598e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
1599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    :
1600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    Thread(false),
1602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPrimaryOutput((audio_io_handle_t)0),
16043b73df74357b33869b39a1d69427673c780bd805Eric Laurent    mPhoneState(AUDIO_MODE_NORMAL),
1605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
1606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),
16073a4311c68348f728558e87b5db67d47605783890Eric Laurent    mA2dpSuspended(false),
16083a4311c68348f728558e87b5db67d47605783890Eric Laurent    mSpeakerDrcEnabled(false), mNextUniqueId(0)
1609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface = clientInterface;
1611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
16123b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
16133b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
1614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
16163a4311c68348f728558e87b5db67d47605783890Eric Laurent    mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
1617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) {
1618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) {
1619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("could not load audio policy configuration file, setting defaults");
1620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            defaultAudioPolicyConfig();
1621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
16233a4311c68348f728558e87b5db67d47605783890Eric Laurent    // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
1624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // must be done after reading the policy
1626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    initializeVolumeCurves();
1627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open all output streams needed to access attached devices
16293a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
16303a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
1631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++) {
1632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
1633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
1634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("could not open HW module %s", mHwModules[i]->mName);
1635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
1636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // open all output streams needed to access attached devices
1638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // except for direct output streams that are only opened when they are actually
1639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // required by an app.
16403a4311c68348f728558e87b5db67d47605783890Eric Laurent        // This also validates mAvailableOutputDevices list
1641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
1642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
16431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
1644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
16453a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (outProfile->mSupportedDevices.isEmpty()) {
16463a4311c68348f728558e87b5db67d47605783890Eric Laurent                ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName);
16473a4311c68348f728558e87b5db67d47605783890Eric Laurent                continue;
16483a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
16493a4311c68348f728558e87b5db67d47605783890Eric Laurent
16503a4311c68348f728558e87b5db67d47605783890Eric Laurent            audio_devices_t profileTypes = outProfile->mSupportedDevices.types();
16513a4311c68348f728558e87b5db67d47605783890Eric Laurent            if ((profileTypes & outputDeviceTypes) &&
1652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {
1653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile);
16543a4311c68348f728558e87b5db67d47605783890Eric Laurent
16551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice->mDeviceType & profileTypes);
1656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                audio_io_handle_t output = mpClientInterface->openOutput(
1657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                outProfile->mModule->mHandle,
1658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mDevice,
1659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mSamplingRate,
1660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mFormat,
1661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mChannelMask,
1662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mLatency,
1663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                outputDesc->mFlags);
1664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (output == 0) {
16653a4311c68348f728558e87b5db67d47605783890Eric Laurent                    ALOGW("Cannot open output stream for device %08x on hw module %s",
16663a4311c68348f728558e87b5db67d47605783890Eric Laurent                          outputDesc->mDevice,
16673a4311c68348f728558e87b5db67d47605783890Eric Laurent                          mHwModules[i]->mName);
1668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    delete outputDesc;
1669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else {
16705b61dddd0dba28922068da2487894761486aec6cEric Laurent                    for (size_t k = 0; k  < outProfile->mSupportedDevices.size(); k++) {
16711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                        audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType;
16723a4311c68348f728558e87b5db67d47605783890Eric Laurent                        ssize_t index =
16735b61dddd0dba28922068da2487894761486aec6cEric Laurent                                mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]);
16743a4311c68348f728558e87b5db67d47605783890Eric Laurent                        // give a valid ID to an attached device once confirmed it is reachable
16753a4311c68348f728558e87b5db67d47605783890Eric Laurent                        if ((index >= 0) && (mAvailableOutputDevices[index]->mId == 0)) {
16763a4311c68348f728558e87b5db67d47605783890Eric Laurent                            mAvailableOutputDevices[index]->mId = nextUniqueId();
16773a4311c68348f728558e87b5db67d47605783890Eric Laurent                        }
16783a4311c68348f728558e87b5db67d47605783890Eric Laurent                    }
1679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (mPrimaryOutput == 0 &&
1680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
1681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mPrimaryOutput = output;
1682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
1683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    addOutput(output, outputDesc);
1684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    setOutputDevice(output,
16853a4311c68348f728558e87b5db67d47605783890Eric Laurent                                    outputDesc->mDevice,
1686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    true);
1687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
16903a4311c68348f728558e87b5db67d47605783890Eric Laurent        // open input streams needed to access attached devices to validate
16913a4311c68348f728558e87b5db67d47605783890Eric Laurent        // mAvailableInputDevices list
16923a4311c68348f728558e87b5db67d47605783890Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
16933a4311c68348f728558e87b5db67d47605783890Eric Laurent        {
16941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
16953a4311c68348f728558e87b5db67d47605783890Eric Laurent
16963a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (inProfile->mSupportedDevices.isEmpty()) {
16973a4311c68348f728558e87b5db67d47605783890Eric Laurent                ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName);
16983a4311c68348f728558e87b5db67d47605783890Eric Laurent                continue;
16993a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
1700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
17013a4311c68348f728558e87b5db67d47605783890Eric Laurent            audio_devices_t profileTypes = inProfile->mSupportedDevices.types();
17023a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (profileTypes & inputDeviceTypes) {
17033a4311c68348f728558e87b5db67d47605783890Eric Laurent                AudioInputDescriptor *inputDesc = new AudioInputDescriptor(inProfile);
17043a4311c68348f728558e87b5db67d47605783890Eric Laurent
17053a4311c68348f728558e87b5db67d47605783890Eric Laurent                inputDesc->mInputSource = AUDIO_SOURCE_MIC;
17061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                inputDesc->mDevice = inProfile->mSupportedDevices[0]->mDeviceType;
17073a4311c68348f728558e87b5db67d47605783890Eric Laurent                audio_io_handle_t input = mpClientInterface->openInput(
17083a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                    inProfile->mModule->mHandle,
17093a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                    &inputDesc->mDevice,
17103a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                    &inputDesc->mSamplingRate,
17113a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                    &inputDesc->mFormat,
17123a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                    &inputDesc->mChannelMask);
17133a4311c68348f728558e87b5db67d47605783890Eric Laurent
17143a4311c68348f728558e87b5db67d47605783890Eric Laurent                if (input != 0) {
17155b61dddd0dba28922068da2487894761486aec6cEric Laurent                    for (size_t k = 0; k  < inProfile->mSupportedDevices.size(); k++) {
17161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                        audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType;
17173a4311c68348f728558e87b5db67d47605783890Eric Laurent                        ssize_t index =
17185b61dddd0dba28922068da2487894761486aec6cEric Laurent                                mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]);
17193a4311c68348f728558e87b5db67d47605783890Eric Laurent                        // give a valid ID to an attached device once confirmed it is reachable
17203a4311c68348f728558e87b5db67d47605783890Eric Laurent                        if ((index >= 0) && (mAvailableInputDevices[index]->mId == 0)) {
17213a4311c68348f728558e87b5db67d47605783890Eric Laurent                            mAvailableInputDevices[index]->mId = nextUniqueId();
17223a4311c68348f728558e87b5db67d47605783890Eric Laurent                        }
17233a4311c68348f728558e87b5db67d47605783890Eric Laurent                    }
17243a4311c68348f728558e87b5db67d47605783890Eric Laurent                    mpClientInterface->closeInput(input);
17253a4311c68348f728558e87b5db67d47605783890Eric Laurent                } else {
17263a4311c68348f728558e87b5db67d47605783890Eric Laurent                    ALOGW("Cannot open input stream for device %08x on hw module %s",
17273a4311c68348f728558e87b5db67d47605783890Eric Laurent                          inputDesc->mDevice,
17283a4311c68348f728558e87b5db67d47605783890Eric Laurent                          mHwModules[i]->mName);
17293a4311c68348f728558e87b5db67d47605783890Eric Laurent                }
17303a4311c68348f728558e87b5db67d47605783890Eric Laurent                delete inputDesc;
17313a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
17323a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
17333a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
17343a4311c68348f728558e87b5db67d47605783890Eric Laurent    // make sure all attached devices have been allocated a unique ID
17353a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i  < mAvailableOutputDevices.size();) {
17363a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (mAvailableOutputDevices[i]->mId == 0) {
17371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mDeviceType);
17383a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
17393a4311c68348f728558e87b5db67d47605783890Eric Laurent            continue;
17403a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
17413a4311c68348f728558e87b5db67d47605783890Eric Laurent        i++;
17423a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
17433a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i  < mAvailableInputDevices.size();) {
17443a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (mAvailableInputDevices[i]->mId == 0) {
17451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mDeviceType);
17463a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.remove(mAvailableInputDevices[i]);
17473a4311c68348f728558e87b5db67d47605783890Eric Laurent            continue;
17483a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
17493a4311c68348f728558e87b5db67d47605783890Eric Laurent        i++;
17503a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
17513a4311c68348f728558e87b5db67d47605783890Eric Laurent    // make sure default device is reachable
17523a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
17531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mDeviceType);
17543a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
1755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
1757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
1759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mPrimaryOutput != 0) {
1762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioParameter outputCmd = AudioParameter();
1763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputCmd.addInt(String8("set_id"), 0);
1764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
1765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestDevice = AUDIO_DEVICE_OUT_SPEAKER;
1767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestSamplingRate = 44100;
17683b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mTestFormat = AUDIO_FORMAT_PCM_16_BIT;
17693b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mTestChannels =  AUDIO_CHANNEL_OUT_STEREO;
1770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestLatencyMs = 0;
1771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mCurOutput = 0;
1772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mDirectOutput = false;
1773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
1774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mTestOutputs[i] = 0;
1775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const size_t SIZE = 256;
1778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        char buffer[SIZE];
1779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "AudioPolicyManagerTest");
1780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        run(buffer, ANDROID_PRIORITY_AUDIO);
1781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1785e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::~AudioPolicyManager()
1786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    exit();
1789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mOutputs.size(); i++) {
1791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mpClientInterface->closeOutput(mOutputs.keyAt(i));
1792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete mOutputs.valueAt(i);
1793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
1794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mInputs.size(); i++) {
1795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mpClientInterface->closeInput(mInputs.keyAt(i));
1796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete mInputs.valueAt(i);
1797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
1798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mHwModules.size(); i++) {
1799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete mHwModules[i];
1800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
18013a4311c68348f728558e87b5db67d47605783890Eric Laurent   mAvailableOutputDevices.clear();
18023a4311c68348f728558e87b5db67d47605783890Eric Laurent   mAvailableInputDevices.clear();
1803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1805e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::initCheck()
1806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR;
1808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1811e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::threadLoop()
1812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("entering threadLoop()");
1814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (!exitPending())
1815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
1816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        String8 command;
1817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        int valueInt;
1818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        String8 value;
1819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        Mutex::Autolock _l(mLock);
1821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mWaitWorkCV.waitRelative(mLock, milliseconds(50));
1822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
1824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioParameter param = AudioParameter(command);
1825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
1827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            valueInt != 0) {
1828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("Test command %s received", command.string());
1829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            String8 target;
1830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("target"), target) != NO_ERROR) {
1831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                target = "Manager";
1832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
1834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_output"));
1835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mCurOutput = valueInt;
1836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
1838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_direct"));
1839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "false") {
1840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mDirectOutput = false;
1841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "true") {
1842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mDirectOutput = true;
1843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
1846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_input"));
1847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mTestInput = valueInt;
1848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
1851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_format"));
18523b73df74357b33869b39a1d69427673c780bd805Eric Laurent                int format = AUDIO_FORMAT_INVALID;
1853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "PCM 16 bits") {
18543b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_PCM_16_BIT;
1855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "PCM 8 bits") {
18563b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_PCM_8_BIT;
1857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "Compressed MP3") {
18583b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_MP3;
1859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
18603b73df74357b33869b39a1d69427673c780bd805Eric Laurent                if (format != AUDIO_FORMAT_INVALID) {
1861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
1862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestFormat = format;
1863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
1864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
1865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputParam.addInt(String8("format"), format);
1866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
1867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
1868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
1871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_channels"));
1872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                int channels = 0;
1873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "Channels Stereo") {
18753b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    channels =  AUDIO_CHANNEL_OUT_STEREO;
1876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "Channels Mono") {
18773b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    channels =  AUDIO_CHANNEL_OUT_MONO;
1878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (channels != 0) {
1880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
1881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestChannels = channels;
1882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
1883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
1884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputParam.addInt(String8("channels"), channels);
1885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
1886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
1887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
1890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_sampleRate"));
1891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (valueInt >= 0 && valueInt <= 96000) {
1892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    int samplingRate = valueInt;
1893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
1894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestSamplingRate = samplingRate;
1895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
1896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
1897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputParam.addInt(String8("sampling_rate"), samplingRate);
1898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
1899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
1900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
1904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_reopen"));
1905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput);
1907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->closeOutput(mPrimaryOutput);
1908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle;
1910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                delete mOutputs.valueFor(mPrimaryOutput);
1912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mOutputs.removeItem(mPrimaryOutput);
1913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
1915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
1916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mPrimaryOutput = mpClientInterface->openOutput(moduleHandle,
1917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mDevice,
1918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mSamplingRate,
1919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mFormat,
1920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mChannelMask,
1921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mLatency,
1922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                outputDesc->mFlags);
1923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (mPrimaryOutput == 0) {
1924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
1925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
1926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else {
1927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    AudioParameter outputCmd = AudioParameter();
1928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputCmd.addInt(String8("set_id"), 0);
1929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
1930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    addOutput(mPrimaryOutput, outputDesc);
1931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->setParameters(0, String8("test_cmd_policy="));
1936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
1939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1941e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::exit()
1942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
1944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AutoMutex _l(mLock);
1945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        requestExit();
1946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mWaitWorkCV.signal();
1947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    requestExitAndWait();
1949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1951e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::testOutputIndex(audio_io_handle_t output)
1952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
1954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (output == mTestOutputs[i]) return i;
1955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
1957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---
1961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
19621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::addOutput(audio_io_handle_t output, AudioOutputDescriptor *outputDesc)
1963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
19641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    outputDesc->mIoHandle = output;
19651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    outputDesc->mId = nextUniqueId();
19661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mOutputs.add(output, outputDesc);
1967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
19691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::addInput(audio_io_handle_t input, AudioInputDescriptor *inputDesc)
1970d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
19711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    inputDesc->mIoHandle = input;
19721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    inputDesc->mId = nextUniqueId();
19731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mInputs.add(input, inputDesc);
1974d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
1975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
19763a4311c68348f728558e87b5db67d47605783890Eric LaurentString8 AudioPolicyManager::addressToParameter(audio_devices_t device, const String8 address)
19773a4311c68348f728558e87b5db67d47605783890Eric Laurent{
19783a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
19793a4311c68348f728558e87b5db67d47605783890Eric Laurent        return String8("a2dp_sink_address=")+address;
19803a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
19813a4311c68348f728558e87b5db67d47605783890Eric Laurent    return address;
19823a4311c68348f728558e87b5db67d47605783890Eric Laurent}
19833a4311c68348f728558e87b5db67d47605783890Eric Laurent
1984e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device,
19853b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                       audio_policy_dev_state_t state,
1986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       SortedVector<audio_io_handle_t>& outputs,
19873a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                       const String8 address)
1988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *desc;
1990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
19913b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
1992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // first list already open outputs that can be routed to this device
1993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
1994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = mOutputs.valueAt(i);
19953a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) {
1996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
1997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputs.add(mOutputs.keyAt(i));
1998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // then look for output profiles that can be routed to this device
20011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        SortedVector< sp<IOProfile> > profiles;
2002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mHwModules.size(); i++)
2003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
2004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (mHwModules[i]->mHandle == 0) {
2005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
2006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
2008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            {
20093a4311c68348f728558e87b5db67d47605783890Eric Laurent                if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) {
2010d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i);
2011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    profiles.add(mHwModules[i]->mOutputProfiles[j]);
2012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (profiles.isEmpty() && outputs.isEmpty()) {
2017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
2018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
2019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // open outputs for matching profiles if needed. Direct outputs are also opened to
2022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
2023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
20241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = profiles[profile_index];
2025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // nothing to do if one output is already opened for this profile
2027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            size_t j;
2028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (j = 0; j < mOutputs.size(); j++) {
2029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                desc = mOutputs.valueAt(j);
2030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (!desc->isDuplicated() && desc->mProfile == profile) {
2031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    break;
2032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (j != mOutputs.size()) {
2035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
2036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
20383a4311c68348f728558e87b5db67d47605783890Eric Laurent            ALOGV("opening output for device %08x with params %s", device, address.string());
2039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = new AudioOutputDescriptor(profile);
2040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc->mDevice = device;
2041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
2042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            offloadInfo.sample_rate = desc->mSamplingRate;
2043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            offloadInfo.format = desc->mFormat;
2044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            offloadInfo.channel_mask = desc->mChannelMask;
2045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle,
2047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &desc->mDevice,
2048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &desc->mSamplingRate,
2049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &desc->mFormat,
2050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &desc->mChannelMask,
2051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &desc->mLatency,
2052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       desc->mFlags,
2053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &offloadInfo);
2054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (output != 0) {
2055d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                // Here is where the out_set_parameters() for card & device gets called
20563a4311c68348f728558e87b5db67d47605783890Eric Laurent                if (!address.isEmpty()) {
20573a4311c68348f728558e87b5db67d47605783890Eric Laurent                    mpClientInterface->setParameters(output, addressToParameter(device, address));
2058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2060d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                // Here is where we step through and resolve any "dynamic" fields
2061d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                String8 reply;
2062d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                char *value;
2063d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mSamplingRates[0] == 0) {
2064d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(output,
2065d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
2066d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice() direct output sup sampling rates %s",
2067d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                              reply.string());
2068d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2069d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
20701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                        profile->loadSamplingRates(value + 1);
2071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2072d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2073d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
2074d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(output,
2075d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                   String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
2076d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice() direct output sup formats %s",
2077d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                              reply.string());
2078d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2079d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
20801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                        profile->loadFormats(value + 1);
2081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2082d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2083d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mChannelMasks[0] == 0) {
2084d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(output,
2085d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                  String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
2086d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice() direct output sup channel masks %s",
2087d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                              reply.string());
2088d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2089d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
20901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                        profile->loadOutChannels(value + 1);
2091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2092d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2093d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (((profile->mSamplingRates[0] == 0) &&
2094d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                         (profile->mSamplingRates.size() < 2)) ||
2095d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                     ((profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) &&
2096d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                         (profile->mFormats.size() < 2)) ||
2097d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                     ((profile->mChannelMasks[0] == 0) &&
2098d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                         (profile->mChannelMasks.size() < 2))) {
2099d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGW("checkOutputsForDevice() direct output missing param");
2100d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeOutput(output);
2101d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    output = 0;
2102d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                } else if (profile->mSamplingRates[0] == 0) {
2103d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeOutput(output);
2104d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    desc->mSamplingRate = profile->mSamplingRates[1];
2105d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    offloadInfo.sample_rate = desc->mSamplingRate;
2106d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    output = mpClientInterface->openOutput(
2107d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    profile->mModule->mHandle,
2108d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &desc->mDevice,
2109d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &desc->mSamplingRate,
2110d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &desc->mFormat,
2111d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &desc->mChannelMask,
2112d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &desc->mLatency,
2113d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    desc->mFlags,
2114d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &offloadInfo);
2115d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2116d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2117d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (output != 0) {
2118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    addOutput(output, desc);
2119d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) {
2120d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        audio_io_handle_t duplicatedOutput = 0;
2121d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2122d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        // set initial stream volume for device
2123d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        applyStreamVolumes(output, device, 0, true);
2124d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2125d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        //TODO: configure audio effect output stage here
2126d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2127d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        // open a duplicating output thread for the new output and the primary output
2128d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        duplicatedOutput = mpClientInterface->openDuplicateOutput(output,
2129d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                                                  mPrimaryOutput);
2130d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        if (duplicatedOutput != 0) {
2131d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            // add duplicated output descriptor
2132d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL);
2133d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput);
2134d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mOutput2 = mOutputs.valueFor(output);
2135d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mSamplingRate = desc->mSamplingRate;
2136d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mFormat = desc->mFormat;
2137d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mChannelMask = desc->mChannelMask;
2138d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mLatency = desc->mLatency;
2139d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            addOutput(duplicatedOutput, dupOutputDesc);
2140d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            applyStreamVolumes(duplicatedOutput, device, 0, true);
2141d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        } else {
2142d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
2143d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                    mPrimaryOutput, output);
2144d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            mpClientInterface->closeOutput(output);
2145d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            mOutputs.removeItem(output);
2146d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            output = 0;
2147d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        }
2148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (output == 0) {
2152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("checkOutputsForDevice() could not open output for device %x", device);
2153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                delete desc;
2154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                profiles.removeAt(profile_index);
2155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                profile_index--;
2156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
2157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputs.add(output);
2158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("checkOutputsForDevice(): adding output %d", output);
2159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (profiles.isEmpty()) {
2163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
2164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
2165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2166d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } else { // Disconnect
2167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // check if one opened output is not needed any more after disconnecting one device
2168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
2169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = mOutputs.valueAt(i);
2170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (!desc->isDuplicated() &&
21713a4311c68348f728558e87b5db67d47605783890Eric Laurent                    !(desc->mProfile->mSupportedDevices.types() &
21723a4311c68348f728558e87b5db67d47605783890Eric Laurent                            mAvailableOutputDevices.types())) {
2173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i));
2174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputs.add(mOutputs.keyAt(i));
2175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2177d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Clear any profiles associated with the disconnected device.
2178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mHwModules.size(); i++)
2179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
2180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (mHwModules[i]->mHandle == 0) {
2181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
2182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
2184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            {
21851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
2186d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mSupportedDevices.types() & device) {
2187d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice(): "
2188d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            "clearing direct output profile %zu on module %zu", j, i);
2189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (profile->mSamplingRates[0] == 0) {
2190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mSamplingRates.clear();
2191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mSamplingRates.add(0);
2192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
2194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mFormats.clear();
2195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
2196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (profile->mChannelMasks[0] == 0) {
2198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mChannelMasks.clear();
2199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mChannelMasks.add(0);
2200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
2206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2208d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentstatus_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device,
2209d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                      audio_policy_dev_state_t state,
2210d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                      SortedVector<audio_io_handle_t>& inputs,
2211d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                      const String8 address)
2212d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
2213d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    AudioInputDescriptor *desc;
2214d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
2215d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // first list already open inputs that can be routed to this device
2216d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
2217d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = mInputs.valueAt(input_index);
2218d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (desc->mProfile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) {
2219d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
2220d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent               inputs.add(mInputs.keyAt(input_index));
2221d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2222d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2223d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2224d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // then look for input profiles that can be routed to this device
22251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        SortedVector< sp<IOProfile> > profiles;
2226d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++)
2227d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        {
2228d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (mHwModules[module_idx]->mHandle == 0) {
2229d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
2230d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2231d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (size_t profile_index = 0;
2232d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index < mHwModules[module_idx]->mInputProfiles.size();
2233d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index++)
2234d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            {
2235d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (mHwModules[module_idx]->mInputProfiles[profile_index]->mSupportedDevices.types()
2236d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        & (device & ~AUDIO_DEVICE_BIT_IN)) {
2237d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkInputsForDevice(): adding profile %d from module %d",
2238d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                          profile_index, module_idx);
2239d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    profiles.add(mHwModules[module_idx]->mInputProfiles[profile_index]);
2240d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2241d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2242d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2243d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2244d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        if (profiles.isEmpty() && inputs.isEmpty()) {
2245d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
2246d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            return BAD_VALUE;
2247d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2248d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2249d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // open inputs for matching profiles if needed. Direct inputs are also opened to
2250d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
2251d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
2252d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
22531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = profiles[profile_index];
2254d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            // nothing to do if one input is already opened for this profile
2255d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            size_t input_index;
2256d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (input_index = 0; input_index < mInputs.size(); input_index++) {
2257d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                desc = mInputs.valueAt(input_index);
2258d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (desc->mProfile == profile) {
2259d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    break;
2260d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2261d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2262d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (input_index != mInputs.size()) {
2263d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
2264d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2265d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2266d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGV("opening input for device 0x%X with params %s", device, address.string());
2267d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = new AudioInputDescriptor(profile);
2268d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc->mDevice = device;
2269d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2270d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle,
2271d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            &desc->mDevice,
2272d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            &desc->mSamplingRate,
2273d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            &desc->mFormat,
2274d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            &desc->mChannelMask);
2275d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2276d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (input != 0) {
2277d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (!address.isEmpty()) {
2278d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->setParameters(input, addressToParameter(device, address));
2279d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2280d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2281d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                // Here is where we step through and resolve any "dynamic" fields
2282d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                String8 reply;
2283d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                char *value;
2284d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mSamplingRates[0] == 0) {
2285d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(input,
2286d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
2287d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkInputsForDevice() direct input sup sampling rates %s",
2288d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                              reply.string());
2289d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2290d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
22911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                        profile->loadSamplingRates(value + 1);
2292d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2293d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2294d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
2295d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(input,
2296d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                   String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
2297d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string());
2298d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2299d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
23001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                        profile->loadFormats(value + 1);
2301d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2302d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2303d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mChannelMasks[0] == 0) {
2304d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(input,
2305d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                  String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
2306d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkInputsForDevice() direct input sup channel masks %s",
2307d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                              reply.string());
2308d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2309d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
23101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                        profile->loadInChannels(value + 1);
2311d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2312d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2313d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) ||
2314d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                     ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) ||
2315d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                     ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) {
2316d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGW("checkInputsForDevice() direct input missing param");
2317d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeInput(input);
2318d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    input = 0;
2319d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2320d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2321d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (input != 0) {
2322d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    addInput(input, desc);
2323d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2324d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            } // endif input != 0
2325d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2326d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (input == 0) {
2327d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
2328d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                delete desc;
2329d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                profiles.removeAt(profile_index);
2330d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                profile_index--;
2331d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            } else {
2332d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                inputs.add(input);
2333d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): adding input %d", input);
2334d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2335d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } // end scan profiles
2336d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2337d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        if (profiles.isEmpty()) {
2338d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
2339d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            return BAD_VALUE;
2340d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2341d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } else {
2342d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Disconnect
2343d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // check if one opened input is not needed any more after disconnecting one device
2344d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
2345d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = mInputs.valueAt(input_index);
2346d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types())) {
2347d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): disconnecting adding input %d",
2348d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                      mInputs.keyAt(input_index));
2349d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                inputs.add(mInputs.keyAt(input_index));
2350d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2351d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2352d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Clear any profiles associated with the disconnected device.
2353d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) {
2354d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (mHwModules[module_index]->mHandle == 0) {
2355d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
2356d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2357d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (size_t profile_index = 0;
2358d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index < mHwModules[module_index]->mInputProfiles.size();
2359d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index++) {
23601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index];
2361d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mSupportedDevices.types() & device) {
2362d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkInputsForDevice(): clearing direct input profile %d on module %d",
2363d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                          profile_index, module_index);
2364d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (profile->mSamplingRates[0] == 0) {
2365d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mSamplingRates.clear();
2366d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mSamplingRates.add(0);
2367d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2368d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
2369d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mFormats.clear();
2370d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
2371d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2372d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (profile->mChannelMasks[0] == 0) {
2373d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mChannelMasks.clear();
2374d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mChannelMasks.add(0);
2375d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2376d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2377d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2378d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2379d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } // end disconnect
2380d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2381d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    return NO_ERROR;
2382d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
2383d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2384d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2385e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::closeOutput(audio_io_handle_t output)
2386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("closeOutput(%d)", output);
2388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
2390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc == NULL) {
2391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("closeOutput() unknown output %d", output);
2392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
2393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // look for duplicated outputs connected to the output being removed.
2396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
2397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i);
2398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (dupOutputDesc->isDuplicated() &&
2399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                (dupOutputDesc->mOutput1 == outputDesc ||
2400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                dupOutputDesc->mOutput2 == outputDesc)) {
2401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *outputDesc2;
2402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (dupOutputDesc->mOutput1 == outputDesc) {
2403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc2 = dupOutputDesc->mOutput2;
2404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
2405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc2 = dupOutputDesc->mOutput1;
2406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // As all active tracks on duplicated output will be deleted,
2408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // and as they were also referenced on the other output, the reference
2409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // count for their stream type must be adjusted accordingly on
2410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // the other output.
24113b73df74357b33869b39a1d69427673c780bd805Eric Laurent            for (int j = 0; j < AUDIO_STREAM_CNT; j++) {
2412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                int refCount = dupOutputDesc->mRefCount[j];
24133b73df74357b33869b39a1d69427673c780bd805Eric Laurent                outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount);
2414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i);
2416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
2417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->closeOutput(duplicatedOutput);
2419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            delete mOutputs.valueFor(duplicatedOutput);
2420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mOutputs.removeItem(duplicatedOutput);
2421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioParameter param;
2425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    param.add(String8("closing"), String8("true"));
2426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->setParameters(output, param.toString());
2427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->closeOutput(output);
2429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    delete outputDesc;
2430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mOutputs.removeItem(output);
2431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPreviousOutputs = mOutputs;
2432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2434e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device,
2435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs)
2436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> outputs;
2438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("getOutputsForDevice() device %04x", device);
2440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < openOutputs.size(); i++) {
2441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("output %d isDuplicated=%d device=%04x",
2442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices());
2443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
2444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
2445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputs.add(openOutputs.keyAt(i));
2446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs;
2449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2451e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
2452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                   SortedVector<audio_io_handle_t>& outputs2)
2453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs1.size() != outputs2.size()) {
2455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs1.size(); i++) {
2458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputs1[i] != outputs2[i]) {
2459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
2460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return true;
2463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2465e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
2466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
2468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
2469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
2470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
2471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!vectorsEqual(srcOutputs,dstOutputs)) {
2473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
2474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              strategy, srcOutputs[0], dstOutputs[0]);
2475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // mute strategy while moving tracks from one output to another
2476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < srcOutputs.size(); i++) {
2477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]);
2478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (desc->isStrategyActive(strategy)) {
2479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                setStrategyMute(strategy, true, srcOutputs[i]);
2480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice);
2481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Move effects associated to this strategy from previous output to new output
2485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strategy == STRATEGY_MEDIA) {
2486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs);
2487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            SortedVector<audio_io_handle_t> moved;
2488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < mEffects.size(); i++) {
2489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                EffectDescriptor *desc = mEffects.valueAt(i);
2490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX &&
2491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        desc->mIo != fxOutput) {
2492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (moved.indexOf(desc->mIo) < 0) {
2493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        ALOGV("checkOutputForStrategy() moving effect %d to output %d",
2494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              mEffects.keyAt(i), fxOutput);
2495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, desc->mIo,
2496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       fxOutput);
2497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        moved.add(desc->mIo);
2498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    desc->mIo = fxOutput;
2500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Move tracks associated to this strategy from previous output to new output
25043b73df74357b33869b39a1d69427673c780bd805Eric Laurent        for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
25053b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (getStrategy((audio_stream_type_t)i) == strategy) {
25063b73df74357b33869b39a1d69427673c780bd805Eric Laurent                mpClientInterface->invalidateStream((audio_stream_type_t)i);
2507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2512e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForAllStrategies()
2513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
2515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_PHONE);
2516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_SONIFICATION);
2517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
2518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_MEDIA);
2519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_DTMF);
2520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2522e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getA2dpOutput()
2523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
2525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
2526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
2527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return mOutputs.keyAt(i);
2528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
2532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2534e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkA2dpSuspend()
2535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t a2dpOutput = getA2dpOutput();
2537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (a2dpOutput == 0) {
25383a4311c68348f728558e87b5db67d47605783890Eric Laurent        mA2dpSuspended = false;
2539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
2540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
25423a4311c68348f728558e87b5db67d47605783890Eric Laurent    bool isScoConnected =
25433a4311c68348f728558e87b5db67d47605783890Eric Laurent            (mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) != 0;
2544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // suspend A2DP output if:
2545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (NOT already suspended) &&
2546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      ((SCO device is connected &&
2547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //       (forced usage for communication || for record is SCO))) ||
2548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (phone state is ringing || in call)
2549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //
2550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // restore A2DP output if:
2551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (Already suspended) &&
2552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      ((SCO device is NOT connected ||
2553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //       (forced usage NOT for communication && NOT for record is SCO))) &&
2554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (phone state is NOT ringing && NOT in call)
2555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //
2556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mA2dpSuspended) {
25573a4311c68348f728558e87b5db67d47605783890Eric Laurent        if ((!isScoConnected ||
25583b73df74357b33869b39a1d69427673c780bd805Eric Laurent             ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO) &&
25593b73df74357b33869b39a1d69427673c780bd805Eric Laurent              (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] != AUDIO_POLICY_FORCE_BT_SCO))) &&
25603b73df74357b33869b39a1d69427673c780bd805Eric Laurent             ((mPhoneState != AUDIO_MODE_IN_CALL) &&
25613b73df74357b33869b39a1d69427673c780bd805Eric Laurent              (mPhoneState != AUDIO_MODE_RINGTONE))) {
2562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->restoreOutput(a2dpOutput);
2564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mA2dpSuspended = false;
2565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
25673a4311c68348f728558e87b5db67d47605783890Eric Laurent        if ((isScoConnected &&
25683b73df74357b33869b39a1d69427673c780bd805Eric Laurent             ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) ||
25693b73df74357b33869b39a1d69427673c780bd805Eric Laurent              (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO))) ||
25703b73df74357b33869b39a1d69427673c780bd805Eric Laurent             ((mPhoneState == AUDIO_MODE_IN_CALL) ||
25713b73df74357b33869b39a1d69427673c780bd805Eric Laurent              (mPhoneState == AUDIO_MODE_RINGTONE))) {
2572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->suspendOutput(a2dpOutput);
2574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mA2dpSuspended = true;
2575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
25791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentaudio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, bool fromCache)
2580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = AUDIO_DEVICE_NONE;
2582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
2584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check the following by order of priority to request a routing change if necessary:
2585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: the strategy enforced audible is active on the output:
2586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy enforced audible
2587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: we are in call or the strategy phone is active on the output:
2588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy phone
2589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 3: the strategy sonification is active on the output:
2590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy sonification
2591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 4: the strategy "respectful" sonification is active on the output:
2592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy "respectful" sonification
2593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 5: the strategy media is active on the output:
2594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy media
2595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 6: the strategy DTMF is active on the output:
2596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy DTMF
2597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) {
2598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
2599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (isInCall() ||
2600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->isStrategyActive(STRATEGY_PHONE)) {
2601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
2602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) {
2603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
2604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) {
2605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
2606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) {
2607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
2608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) {
2609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
2610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
26121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("getNewOutputDevice() selected device %x", device);
26131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return device;
26141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
26151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
26161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentaudio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input)
26171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
26181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    AudioInputDescriptor *inputDesc = mInputs.valueFor(input);
26191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    audio_devices_t device = getDeviceForInputSource(inputDesc->mInputSource);
26201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
26211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("getNewInputDevice() selected device %x", device);
2622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
2623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2625e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
2626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return (uint32_t)getStrategy(stream);
2627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2629e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
2630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t devices;
2631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // By checking the range of stream before calling getStrategy, we avoid
2632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // getStrategy's behavior for invalid streams.  getStrategy would do a ALOGE
2633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and then return STRATEGY_MEDIA, but we want to return the empty set.
26343b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_CNT) {
2635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        devices = AUDIO_DEVICE_NONE;
2636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
2637e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent        AudioPolicyManager::routing_strategy strategy = getStrategy(stream);
2638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        devices = getDeviceForStrategy(strategy, true /*fromCache*/);
2639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return devices;
2641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2643e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(
26443b73df74357b33869b39a1d69427673c780bd805Eric Laurent        audio_stream_type_t stream) {
2645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // stream to strategy mapping
2646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch (stream) {
26473b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_VOICE_CALL:
26483b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_BLUETOOTH_SCO:
2649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_PHONE;
26503b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_RING:
26513b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_ALARM:
2652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_SONIFICATION;
26533b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_NOTIFICATION:
2654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_SONIFICATION_RESPECTFUL;
26553b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_DTMF:
2656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_DTMF;
2657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
2658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGE("unknown stream type");
26593b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_SYSTEM:
2660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
2661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // while key clicks are played produces a poor result
26623b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_TTS:
26633b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_MUSIC:
2664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_MEDIA;
26653b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_ENFORCED_AUDIBLE:
2666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_ENFORCED_AUDIBLE;
2667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2670e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
2671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch(stream) {
26723b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_MUSIC:
2673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
2674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        updateDevicesAndOutputs();
2675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
2676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
2677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
2678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2681e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
2682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                             bool fromCache)
2683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t device = AUDIO_DEVICE_NONE;
2685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (fromCache) {
2687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
2688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              strategy, mDeviceForStrategy[strategy]);
2689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mDeviceForStrategy[strategy];
2690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
26913a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
2692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch (strategy) {
2693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_SONIFICATION_RESPECTFUL:
2695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (isInCall()) {
2696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
26973b73df74357b33869b39a1d69427673c780bd805Eric Laurent        } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
2698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
2699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // while media is playing on a remote device, use the the sonification behavior.
2700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // Note that we test this usecase before testing if media is playing because
2701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            //   the isStreamActive() method only informs about the activity of a stream, not
2702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            //   if it's for local playback. Note also that we use the same delay between both tests
2703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
27043b73df74357b33869b39a1d69427673c780bd805Eric Laurent        } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
2705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // while media is playing (or has recently played), use the same device
2706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
2707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else {
2708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // when media is not playing anymore, fall back on the sonification behavior
2709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
2710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
2713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_DTMF:
2715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!isInCall()) {
2716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // when off call, DTMF strategy follows the same rules as MEDIA strategy
2717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
2718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            break;
2719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // when in call, DTMF and PHONE strategies follow the same rules
2721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // FALL THROUGH
2722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_PHONE:
2724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // for phone strategy, we first consider the forced use and then the available devices by order
2725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // of priority
27263b73df74357b33869b39a1d69427673c780bd805Eric Laurent        switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
27273b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_FORCE_BT_SCO:
2728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (!isInCall() || strategy != STRATEGY_DTMF) {
27293a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
2730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
2731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
27323a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
2733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
27343a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
2735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
2736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // if SCO device is requested but no SCO device is available, fall back to default case
2737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // FALL THROUGH
2738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:    // FORCE_NONE
2740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
27413a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (!isInCall() &&
27423b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
2743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    (getA2dpOutput() != 0) && !mA2dpSuspended) {
27443a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
2745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27463a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
2747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
2748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
27493a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
2750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
27513a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
2752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
27533b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (mPhoneState != AUDIO_MODE_IN_CALL) {
27543a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
2755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27563a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
2757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27583a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
2759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27603a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
2761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27623a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
2763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
2764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
27653a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE;
2766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
27671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            device = mDefaultOutputDevice->mDeviceType;
2768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device == AUDIO_DEVICE_NONE) {
2769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
2770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            break;
2772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
27733b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_FORCE_SPEAKER:
2774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
2775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // A2DP speaker when forcing to speaker output
27763a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (!isInCall() &&
27773b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
2778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    (getA2dpOutput() != 0) && !mA2dpSuspended) {
27793a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
2780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
2781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
27823b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (mPhoneState != AUDIO_MODE_IN_CALL) {
27833a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
2784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27853a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
2786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27873a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
2788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27893a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
2790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27913a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
2792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
2793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
27943a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
2795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
27961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            device = mDefaultOutputDevice->mDeviceType;
2797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device == AUDIO_DEVICE_NONE) {
2798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
2799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            break;
2801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    break;
2803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_SONIFICATION:
2805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
2807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handleIncallSonification().
2808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (isInCall()) {
2809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
2810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            break;
2811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // FALL THROUGH
2813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_ENFORCED_AUDIBLE:
2815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
2816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // except:
2817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        //   - when in call where it doesn't default to STRATEGY_PHONE behavior
2818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        //   - in countries where not enforced in which case it follows STRATEGY_MEDIA
2819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((strategy == STRATEGY_SONIFICATION) ||
28213b73df74357b33869b39a1d69427673c780bd805Eric Laurent                (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
28223a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
2823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device == AUDIO_DEVICE_NONE) {
2824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
2825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // The second device used for sonification is the same as the device used by media strategy
2828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // FALL THROUGH
2829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_MEDIA: {
2831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        uint32_t device2 = AUDIO_DEVICE_NONE;
2832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strategy != STRATEGY_SONIFICATION) {
2833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // no sonification on remote submix (e.g. WFD)
28343a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
2835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device2 == AUDIO_DEVICE_NONE) &&
28373b73df74357b33869b39a1d69427673c780bd805Eric Laurent                (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
2838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                (getA2dpOutput() != 0) && !mA2dpSuspended) {
28393a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
2840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device2 == AUDIO_DEVICE_NONE) {
28413a4311c68348f728558e87b5db67d47605783890Eric Laurent                device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
2842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device2 == AUDIO_DEVICE_NONE) {
28443a4311c68348f728558e87b5db67d47605783890Eric Laurent                device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
2845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28483a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
2849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28513a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
2852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28543a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
2855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28573a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
2858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28603a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
2861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
2863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // no sonification on aux digital (e.g. HDMI)
28643a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
2865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device2 == AUDIO_DEVICE_NONE) &&
28673b73df74357b33869b39a1d69427673c780bd805Eric Laurent                (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
28683a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
2869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28713a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
2872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
2875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
2876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device |= device2;
2877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device) break;
28781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        device = mDefaultOutputDevice->mDeviceType;
2879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device == AUDIO_DEVICE_NONE) {
2880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
2881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } break;
2883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
2885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
2886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
2887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
2890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
2891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2893e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::updateDevicesAndOutputs()
2894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < NUM_STRATEGIES; i++) {
2896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
2897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPreviousOutputs = mOutputs;
2899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2901e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc,
2902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       audio_devices_t prevDevice,
2903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       uint32_t delayMs)
2904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // mute/unmute strategies using an incompatible device combination
2906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if muting, wait for the audio in pcm buffer to be drained before proceeding
2907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if unmuting, unmute only after the specified delay
2908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isDuplicated()) {
2909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
2910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t muteWaitMs = 0;
2913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = outputDesc->device();
29143b73df74357b33869b39a1d69427673c780bd805Eric Laurent    bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2);
2915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < NUM_STRATEGIES; i++) {
2917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
2918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool mute = shouldMute && (curDevice & device) && (curDevice != device);
2919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool doMute = false;
2920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
2922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            doMute = true;
2923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStrategyMutedByDevice[i] = true;
2924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
2925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            doMute = true;
2926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStrategyMutedByDevice[i] = false;
2927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
292899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        if (doMute) {
2929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mOutputs.size(); j++) {
2930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *desc = mOutputs.valueAt(j);
2931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // skip output if it does not share any device with current output
2932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if ((desc->supportedDevices() & outputDesc->supportedDevices())
2933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        == AUDIO_DEVICE_NONE) {
2934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    continue;
2935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                audio_io_handle_t curOutput = mOutputs.keyAt(j);
2937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d",
2938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                      mute ? "muting" : "unmuting", i, curDevice, curOutput);
2939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs);
2940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (desc->isStrategyActive((routing_strategy)i)) {
294199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                    if (mute) {
294299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // FIXME: should not need to double latency if volume could be applied
294399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // immediately by the audioflinger mixer. We must account for the delay
294499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // between now and the next time the audioflinger thread for this output
294599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // will process a buffer (which corresponds to one buffer size,
294699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // usually 1/2 or 1/4 of the latency).
294799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        if (muteWaitMs < desc->latency() * 2) {
294899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                            muteWaitMs = desc->latency() * 2;
2949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        }
2950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
295699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    // temporary mute output if device selection changes to avoid volume bursts due to
295799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    // different per device volumes
295899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    if (outputDesc->isActive() && (device != prevDevice)) {
295999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        if (muteWaitMs < outputDesc->latency() * 2) {
296099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent            muteWaitMs = outputDesc->latency() * 2;
296199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        }
296299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        for (size_t i = 0; i < NUM_STRATEGIES; i++) {
296399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent            if (outputDesc->isStrategyActive((routing_strategy)i)) {
29641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                setStrategyMute((routing_strategy)i, true, outputDesc->mIoHandle);
296599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                // do tempMute unmute after twice the mute wait time
29661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                setStrategyMute((routing_strategy)i, false, outputDesc->mIoHandle,
296799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                                muteWaitMs *2, device);
296899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent            }
296999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        }
297099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    }
297199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent
2972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // wait for the PCM output buffers to empty before proceeding with the rest of the command
2973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (muteWaitMs > delayMs) {
2974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        muteWaitMs -= delayMs;
2975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        usleep(muteWaitMs * 1000);
2976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
2977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
2979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2981e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output,
2982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             audio_devices_t device,
2983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             bool force,
2984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             int delayMs)
2985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs);
2987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
2988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioParameter param;
2989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t muteWaitMs;
2990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isDuplicated()) {
29921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        muteWaitMs = setOutputDevice(outputDesc->mOutput1->mIoHandle, device, force, delayMs);
29931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        muteWaitMs += setOutputDevice(outputDesc->mOutput2->mIoHandle, device, force, delayMs);
2994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
2995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
2997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // output profile
2998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((device != AUDIO_DEVICE_NONE) &&
29993a4311c68348f728558e87b5db67d47605783890Eric Laurent            ((device & outputDesc->mProfile->mSupportedDevices.types()) == 0)) {
3000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
3001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // filter devices according to output selected
30043a4311c68348f728558e87b5db67d47605783890Eric Laurent    device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices.types());
3005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t prevDevice = outputDesc->mDevice;
3007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setOutputDevice() prevDevice %04x", prevDevice);
3009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device != AUDIO_DEVICE_NONE) {
3011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mDevice = device;
3012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
3014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not change the routing if:
3016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //  - the requested device is AUDIO_DEVICE_NONE
3017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //  - the requested device is the same as current device and force is not specified.
3018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Doing this check here allows the caller to call setOutputDevice() without conditions
3019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) {
3020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output);
3021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
3022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setOutputDevice() changing device");
30251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
3026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do the routing
30271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (device == AUDIO_DEVICE_NONE) {
30281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        resetOutputDevice(output, delayMs);
30291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    } else {
30301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        DeviceVector deviceList = mAvailableOutputDevices.getDevicesFromType(device);
30311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (!deviceList.isEmpty()) {
30321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            struct audio_patch patch;
30331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            outputDesc->toAudioPortConfig(&patch.sources[0]);
30341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sources = 1;
30351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sinks = 0;
30361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
30371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]);
30381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                patch.sinks[i].ext.device.hw_module = patch.sources[0].ext.mix.hw_module;
30391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                patch.num_sinks++;
30401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
30411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            audio_patch_handle_t patchHandle = outputDesc->mPatchHandle;
30421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            status_t status = mpClientInterface->createAudioPatch(&patch,
30431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                                  &patchHandle,
30441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                                  delayMs);
30451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d"
30461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                    "num_sources %d num_sinks %d",
30471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                       status, patchHandle, patch.num_sources, patch.num_sinks);
30481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            if (status == NO_ERROR) {
30491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                outputDesc->mPatchHandle = patchHandle;
30501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
30511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
30521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
3053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // update stream volumes according to new device
3055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    applyStreamVolumes(output, device, delayMs);
3056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return muteWaitMs;
3058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
30601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output,
30611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                               int delayMs)
30621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
30631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
30641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (outputDesc->mPatchHandle == 0) {
30651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return INVALID_OPERATION;
30661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
30671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    status_t status = mpClientInterface->releaseAudioPatch(outputDesc->mPatchHandle, delayMs);
30681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status);
30691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    outputDesc->mPatchHandle = 0;
30701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
30711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
30721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
30731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::setInputDevice(audio_io_handle_t input,
30741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                            audio_devices_t device,
30751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                            bool force)
30761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
30771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    status_t status = NO_ERROR;
30781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
30791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    AudioInputDescriptor *inputDesc = mInputs.valueFor(input);
30801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) {
30811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        inputDesc->mDevice = device;
30821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
30831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device);
30841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (!deviceList.isEmpty()) {
30851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            struct audio_patch patch;
30861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            inputDesc->toAudioPortConfig(&patch.sinks[0]);
30871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sinks = 1;
30881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            //only one input device for now
30891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
30901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.sources[0].ext.device.hw_module = patch.sinks[0].ext.mix.hw_module;
30911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sources = 1;
30921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            audio_patch_handle_t patchHandle = inputDesc->mPatchHandle;
30931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            status_t status = mpClientInterface->createAudioPatch(&patch,
30941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                                  &patchHandle,
30951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                                  0);
30961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d",
30971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                                          status, patchHandle);
30981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            if (status == NO_ERROR) {
30991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                inputDesc->mPatchHandle = patchHandle;
31001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
31011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
31021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
31031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
31041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
31051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
31061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input)
31071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
31081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    AudioInputDescriptor *inputDesc = mInputs.valueFor(input);
31091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (inputDesc->mPatchHandle == 0) {
31101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return INVALID_OPERATION;
31111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
31121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    status_t status = mpClientInterface->releaseAudioPatch(inputDesc->mPatchHandle, 0);
31131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("resetInputDevice() releaseAudioPatch returned %d", status);
31141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    inputDesc->mPatchHandle = 0;
31151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
31161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
31171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
31181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
3119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   uint32_t samplingRate,
3120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   audio_format_t format,
3121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   audio_channel_mask_t channelMask)
3122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Choose an input profile based on the requested capture parameters: select the first available
3124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // profile supporting all requested parameters.
3125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++)
3127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
3128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
3129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
3130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
3132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
31331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j];
3134d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            // profile->log();
3135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (profile->isCompatibleProfile(device, samplingRate, format,
3136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             channelMask, AUDIO_OUTPUT_FLAG_NONE)) {
3137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return profile;
3138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NULL;
3142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3144e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
3145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t device = AUDIO_DEVICE_NONE;
31473a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() &
31483a4311c68348f728558e87b5db67d47605783890Eric Laurent                                            ~AUDIO_DEVICE_BIT_IN;
3149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch (inputSource) {
3150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_UPLINK:
31513a4311c68348f728558e87b5db67d47605783890Eric Laurent      if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
3152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          device = AUDIO_DEVICE_IN_VOICE_CALL;
3153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          break;
3154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent      }
3155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent      // FALL THROUGH
3156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_DEFAULT:
3158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_MIC:
3159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_RECOGNITION:
3160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_HOTWORD:
3161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_COMMUNICATION:
31623b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
31633a4311c68348f728558e87b5db67d47605783890Eric Laurent                availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
3164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
31653a4311c68348f728558e87b5db67d47605783890Eric Laurent        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
3166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_WIRED_HEADSET;
3167d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
3168d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            device = AUDIO_DEVICE_IN_USB_DEVICE;
31693a4311c68348f728558e87b5db67d47605783890Eric Laurent        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
3170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
3171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
3173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_CAMCORDER:
31743a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
3175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_BACK_MIC;
31763a4311c68348f728558e87b5db67d47605783890Eric Laurent        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
3177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
3178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
3180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_DOWNLINK:
3181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_CALL:
31823a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
3183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_VOICE_CALL;
3184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
3186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_REMOTE_SUBMIX:
31873a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
3188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
3189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
3191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
3192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
3193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
3194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
3196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
3197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3199e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device)
3200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((device & AUDIO_DEVICE_BIT_IN) != 0) {
3202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device &= ~AUDIO_DEVICE_BIT_IN;
3203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0))
3204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
3205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
3207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3209e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs)
3210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
3212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const AudioInputDescriptor * input_descriptor = mInputs.valueAt(i);
3213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((input_descriptor->mRefCount > 0)
3214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) {
3215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return mInputs.keyAt(i);
3216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
3219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3222e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device)
3223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
3225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // this happens when forcing a route update and no track is active on an output.
3226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // In this case the returned category is not important.
3227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device =  AUDIO_DEVICE_OUT_SPEAKER;
32283b73df74357b33869b39a1d69427673c780bd805Eric Laurent    } else if (popcount(device) > 1) {
3229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Multiple device selection is either:
3230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        //  - speaker + one other device: give priority to speaker in this case.
3231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        //  - one A2DP device + another device: happens with duplicated output. In this case
3232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // retain the device on the A2DP output as the other must not correspond to an active
3233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // selection if not the speaker.
3234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device & AUDIO_DEVICE_OUT_SPEAKER) {
3235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_OUT_SPEAKER;
3236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else {
3237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP);
3238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
32413b73df74357b33869b39a1d69427673c780bd805Eric Laurent    ALOGW_IF(popcount(device) != 1,
3242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "getDeviceForVolume() invalid device combination: %08x",
3243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device);
3244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
3246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3248e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device)
3249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch(getDeviceForVolume(device)) {
3251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_EARPIECE:
3252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return DEVICE_CATEGORY_EARPIECE;
3253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_WIRED_HEADSET:
3254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
3255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
3256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
3257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
3258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
3259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return DEVICE_CATEGORY_HEADSET;
3260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_SPEAKER:
3261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
3262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
3263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_AUX_DIGITAL:
3264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_USB_ACCESSORY:
3265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_USB_DEVICE:
3266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
3267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
3268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return DEVICE_CATEGORY_SPEAKER;
3269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3272e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
3273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        int indexInUi)
3274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    device_category deviceCategory = getDeviceCategory(device);
3276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory];
3277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // the volume index in the UI is relative to the min and max volume indices for this stream type
3279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int nbSteps = 1 + curve[VOLMAX].mIndex -
3280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            curve[VOLMIN].mIndex;
3281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) /
3282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (streamDesc.mIndexMax - streamDesc.mIndexMin);
3283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // find what part of the curve this index volume belongs to, or if it's out of bounds
3285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int segment = 0;
3286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (volIdx < curve[VOLMIN].mIndex) {         // out of bounds
3287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0.0f;
3288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (volIdx < curve[VOLKNEE1].mIndex) {
3289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        segment = 0;
3290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (volIdx < curve[VOLKNEE2].mIndex) {
3291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        segment = 1;
3292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (volIdx <= curve[VOLMAX].mIndex) {
3293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        segment = 2;
3294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {                                                               // out of bounds
3295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 1.0f;
3296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // linear interpolation in the attenuation table in dB
3299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    float decibels = curve[segment].mDBAttenuation +
3300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ((float)(volIdx - curve[segment].mIndex)) *
3301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ( (curve[segment+1].mDBAttenuation -
3302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        curve[segment].mDBAttenuation) /
3303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ((float)(curve[segment+1].mIndex -
3304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            curve[segment].mIndex)) );
3305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 )
3307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f",
3309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            curve[segment].mIndex, volIdx,
3310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            curve[segment+1].mIndex,
3311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            curve[segment].mDBAttenuation,
3312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            decibels,
3313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            curve[segment+1].mDBAttenuation,
3314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            amplification);
3315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return amplification;
3317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3319e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3320e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sDefaultVolumeCurve[AudioPolicyManager::VOLCNT] = {
3321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f}
3322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3324e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3325e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT] = {
3326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f}
3327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3329e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3330e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT] = {
3331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f}
3332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3334e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3335e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = {
3336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f}
3337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3339e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3340e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
3341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f}
3342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks
3345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets.
3346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java).
3347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset.
3348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3349e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3350e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
3351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f}
3352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3354e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3355e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
3356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f}
3357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3359e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3360e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
3361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f}
3362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3364e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3365e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = {
3366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f}
3367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3369e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3370e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = {
3371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f}
3372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3374e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3375e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent            *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT]
3376e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent                                                   [AudioPolicyManager::DEVICE_CATEGORY_CNT] = {
3377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_VOICE_CALL
3378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
3379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVoiceVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_SYSTEM
3383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
3384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_RING
3388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
3389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_MUSIC
3393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
3394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_ALARM
3398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
3399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_NOTIFICATION
3403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
3404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_BLUETOOTH_SCO
3408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
3409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVoiceVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_ENFORCED_AUDIBLE
3413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
3414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {  // AUDIO_STREAM_DTMF
3418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
3419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_TTS
3423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
3424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3429e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initializeVolumeCurves()
3430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
3432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
3433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mStreams[i].mVolumeCurve[j] =
3434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    sVolumeProfiles[i][j];
3435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check availability of DRC on speaker path: if available, override some of the speaker curves
3439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mSpeakerDrcEnabled) {
3440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
3441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                sDefaultSystemVolumeCurveDrc;
3442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
3443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                sSpeakerSonificationVolumeCurveDrc;
3444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
3445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                sSpeakerSonificationVolumeCurveDrc;
3446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
3447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                sSpeakerSonificationVolumeCurveDrc;
3448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3451e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::computeVolume(audio_stream_type_t stream,
3452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int index,
3453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            audio_io_handle_t output,
3454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            audio_devices_t device)
3455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    float volume = 1.0;
3457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
3458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    StreamDescriptor &streamDesc = mStreams[stream];
3459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
3461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = outputDesc->device();
3462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if volume is not 0 (not muted), force media volume to max on digital output
34653b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (stream == AUDIO_STREAM_MUSIC &&
3466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        index != mStreams[stream].mIndexMin &&
3467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        (device == AUDIO_DEVICE_OUT_AUX_DIGITAL ||
3468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET ||
3469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         device == AUDIO_DEVICE_OUT_USB_ACCESSORY ||
3470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         device == AUDIO_DEVICE_OUT_USB_DEVICE)) {
3471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 1.0;
3472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    volume = volIndexToAmpl(device, streamDesc, index);
3475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if a headset is connected, apply the following rules to ring tones and notifications
3477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // to avoid sound level bursts in user's ears:
3478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // - always attenuate ring tones and notifications volume by 6dB
3479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // - if music is playing, always limit the volume to current music volume,
3480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // with a minimum threshold at -36dB so that notification is always perceived.
34813b73df74357b33869b39a1d69427673c780bd805Eric Laurent    const routing_strategy stream_strategy = getStrategy(stream);
3482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
3483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
3484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_WIRED_HEADSET |
3485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) &&
3486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ((stream_strategy == STRATEGY_SONIFICATION)
3487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
34883b73df74357b33869b39a1d69427673c780bd805Eric Laurent                || (stream == AUDIO_STREAM_SYSTEM)
3489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
34903b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) &&
3491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        streamDesc.mCanBeMuted) {
3492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
3493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // when the phone is ringing we must consider that music could have been paused just before
3494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // by the music application and behave as if music was active if the last music track was
3495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // just stopped
34963b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
3497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mLimitRingtoneVolume) {
3498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
34993b73df74357b33869b39a1d69427673c780bd805Eric Laurent            float musicVol = computeVolume(AUDIO_STREAM_MUSIC,
35003b73df74357b33869b39a1d69427673c780bd805Eric Laurent                               mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice),
3501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                               output,
3502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                               musicDevice);
3503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ?
3504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
3505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (volume > minVol) {
3506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                volume = minVol;
3507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
3508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return volume;
3513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3515e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
3516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   int index,
3517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   audio_io_handle_t output,
3518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   audio_devices_t device,
3519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   int delayMs,
3520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   bool force)
3521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do not change actual stream volume if the stream is muted
3524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
3525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("checkAndSetVolume() stream %d muted count %d",
3526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              stream, mOutputs.valueFor(output)->mMuteCount[stream]);
3527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
3528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do not change in call volume if bluetooth is connected and vice versa
35313b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if ((stream == AUDIO_STREAM_VOICE_CALL &&
35323b73df74357b33869b39a1d69427673c780bd805Eric Laurent            mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) ||
35333b73df74357b33869b39a1d69427673c780bd805Eric Laurent        (stream == AUDIO_STREAM_BLUETOOTH_SCO &&
35343b73df74357b33869b39a1d69427673c780bd805Eric Laurent                mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO)) {
3535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
35363b73df74357b33869b39a1d69427673c780bd805Eric Laurent             stream, mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]);
3537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
3538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    float volume = computeVolume(stream, index, output, device);
3541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // We actually change the volume if:
3542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // - the float value returned by computeVolume() changed
3543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // - the force flag is set
3544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
3545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            force) {
3546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mOutputs.valueFor(output)->mCurVolume[stream] = volume;
3547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
3548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
3549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // enabled
35503b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
35513b73df74357b33869b39a1d69427673c780bd805Eric Laurent            mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs);
3552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
35533b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mpClientInterface->setStreamVolume(stream, volume, output, delayMs);
3554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
35563b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (stream == AUDIO_STREAM_VOICE_CALL ||
35573b73df74357b33869b39a1d69427673c780bd805Eric Laurent        stream == AUDIO_STREAM_BLUETOOTH_SCO) {
3558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        float voiceVolume;
3559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Force voice volume to max for bluetooth SCO as volume is managed by the headset
35603b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (stream == AUDIO_STREAM_VOICE_CALL) {
3561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
3562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else {
3563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            voiceVolume = 1.0;
3564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {
3567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
3568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mLastVoiceVolume = voiceVolume;
3569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
3573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3575e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output,
3576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                audio_devices_t device,
3577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                int delayMs,
3578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                bool force)
3579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("applyStreamVolumes() for output %d and device %x", output, device);
3581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
35823b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
35833b73df74357b33869b39a1d69427673c780bd805Eric Laurent        checkAndSetVolume((audio_stream_type_t)stream,
3584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          mStreams[stream].getVolumeIndex(device),
3585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          output,
3586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          device,
3587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          delayMs,
3588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          force);
3589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3592e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStrategyMute(routing_strategy strategy,
3593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             bool on,
3594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             audio_io_handle_t output,
3595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             int delayMs,
3596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             audio_devices_t device)
3597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
35993b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
36003b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (getStrategy((audio_stream_type_t)stream) == strategy) {
36013b73df74357b33869b39a1d69427673c780bd805Eric Laurent            setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device);
3602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3606e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
3607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           bool on,
3608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           audio_io_handle_t output,
3609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           int delayMs,
3610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           audio_devices_t device)
3611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    StreamDescriptor &streamDesc = mStreams[stream];
3613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
3614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
3615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = outputDesc->device();
3616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x",
3619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          stream, on, output, outputDesc->mMuteCount[stream], device);
3620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (on) {
3622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mMuteCount[stream] == 0) {
3623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (streamDesc.mCanBeMuted &&
36243b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
36253b73df74357b33869b39a1d69427673c780bd805Eric Laurent                     (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) {
3626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                checkAndSetVolume(stream, 0, output, device, delayMs);
3627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
3630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mMuteCount[stream]++;
3631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
3632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mMuteCount[stream] == 0) {
3633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setStreamMute() unmuting non muted stream!");
3634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
3635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (--outputDesc->mMuteCount[stream] == 0) {
3637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            checkAndSetVolume(stream,
3638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              streamDesc.getVolumeIndex(device),
3639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              output,
3640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              device,
3641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              delayMs);
3642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3646e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
36473b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                      bool starting, bool stateChange)
3648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if the stream pertains to sonification strategy and we are in call we must
3650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // mute the stream if it is low visibility. If it is high visibility, we must play a tone
3651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the device used for phone strategy and play the tone if the selected device does not
3652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // interfere with the device used for phone strategy
3653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
3654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // many times as there are active tracks on the output
36553b73df74357b33869b39a1d69427673c780bd805Eric Laurent    const routing_strategy stream_strategy = getStrategy(stream);
3656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((stream_strategy == STRATEGY_SONIFICATION) ||
3657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
3658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput);
3659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
3660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                stream, starting, outputDesc->mDevice, stateChange);
3661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mRefCount[stream]) {
3662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            int muteCount = 1;
3663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (stateChange) {
3664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                muteCount = outputDesc->mRefCount[stream];
3665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
36663b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (audio_is_low_visibility(stream)) {
3667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
3668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                for (int i = 0; i < muteCount; i++) {
3669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    setStreamMute(stream, starting, mPrimaryOutput);
3670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
3672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("handleIncallSonification() high visibility");
3673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (outputDesc->device() &
3674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
3675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
3676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    for (int i = 0; i < muteCount; i++) {
3677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        setStreamMute(stream, starting, mPrimaryOutput);
3678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
3679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (starting) {
36813b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
36823b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                 AUDIO_STREAM_VOICE_CALL);
3683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else {
3684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mpClientInterface->stopTone();
3685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3691e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isInCall()
3692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return isStateInCall(mPhoneState);
3694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3696e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStateInCall(int state) {
36973b73df74357b33869b39a1d69427673c780bd805Eric Laurent    return ((state == AUDIO_MODE_IN_CALL) ||
36983b73df74357b33869b39a1d69427673c780bd805Eric Laurent            (state == AUDIO_MODE_IN_COMMUNICATION));
3699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3701e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsCpuLoad()
3702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return MAX_EFFECTS_CPU_LOAD;
3704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3706e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsMemory()
3707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return MAX_EFFECTS_MEMORY;
3709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioOutputDescriptor class implementation
3712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3713e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor(
37141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        const sp<IOProfile>& profile)
37151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    : mId(0), mIoHandle(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT),
3716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent      mChannelMask(0), mLatency(0),
37171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0),
3718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0)
3719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // clear usage count for all stream types
37213b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
3722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mRefCount[i] = 0;
3723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mCurVolume[i] = -1.0;
3724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mMuteCount[i] = 0;
3725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStopTime[i] = 0;
3726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < NUM_STRATEGIES; i++) {
3728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStrategyMutedByDevice[i] = false;
3729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (profile != NULL) {
3731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mSamplingRate = profile->mSamplingRates[0];
3732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mFormat = profile->mFormats[0];
3733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mChannelMask = profile->mChannelMasks[0];
3734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mFlags = profile->mFlags;
3735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3738e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::device() const
3739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isDuplicated()) {
3741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
3742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
3743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mDevice;
3744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3747e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::AudioOutputDescriptor::latency()
3748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isDuplicated()) {
3750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
3751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
3752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mLatency;
3753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3756e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith(
3757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const AudioOutputDescriptor *outputDesc)
3758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isDuplicated()) {
3760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
3761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (outputDesc->isDuplicated()){
3762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2);
3763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
3764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return (mProfile->mModule == outputDesc->mProfile->mModule);
3765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3768e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
37693b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                                   int delta)
3770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // forward usage count change to attached outputs
3772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isDuplicated()) {
3773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mOutput1->changeRefCount(stream, delta);
3774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mOutput2->changeRefCount(stream, delta);
3775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((delta + (int)mRefCount[stream]) < 0) {
37773b73df74357b33869b39a1d69427673c780bd805Eric Laurent        ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
37783b73df74357b33869b39a1d69427673c780bd805Eric Laurent              delta, stream, mRefCount[stream]);
3779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mRefCount[stream] = 0;
3780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
3781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mRefCount[stream] += delta;
3783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
3784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3786e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::supportedDevices()
3787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isDuplicated()) {
3789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
3790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
37913a4311c68348f728558e87b5db67d47605783890Eric Laurent        return mProfile->mSupportedDevices.types() ;
3792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3795e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isActive(uint32_t inPastMs) const
3796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return isStrategyActive(NUM_STRATEGIES, inPastMs);
3798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3800e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy,
3801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       uint32_t inPastMs,
3802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       nsecs_t sysTime) const
3803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((sysTime == 0) && (inPastMs != 0)) {
3805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sysTime = systemTime();
3806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
38073b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
38083b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (((getStrategy((audio_stream_type_t)i) == strategy) ||
3809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                (NUM_STRATEGIES == strategy)) &&
38103b73df74357b33869b39a1d69427673c780bd805Eric Laurent                isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
3811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
3812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
3815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3817e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
3818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       uint32_t inPastMs,
3819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       nsecs_t sysTime) const
3820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mRefCount[stream] != 0) {
3822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return true;
3823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (inPastMs == 0) {
3825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
3826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (sysTime == 0) {
3828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sysTime = systemTime();
3829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
3831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return true;
3832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
3834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
38361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::toAudioPortConfig(
38371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                        struct audio_port_config *config) const
38381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
38391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->id = mId;
38401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->role = AUDIO_PORT_ROLE_SOURCE;
38411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->type = AUDIO_PORT_TYPE_MIX;
38421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->sample_rate = mSamplingRate;
38431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->channel_mask = mChannelMask;
38441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->format = mFormat;
38451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->gain.index = -1;
38461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
38471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                            AUDIO_PORT_CONFIG_FORMAT;
38481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->ext.mix.hw_module = mProfile->mModule->mHandle;
38491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->ext.mix.handle = mIoHandle;
38501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
38511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
38521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
38531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::toAudioPort(
38541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                    struct audio_port *port) const
38551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
38561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mProfile->toAudioPort(port);
38571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->id = mId;
38581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->ext.mix.handle = mIoHandle;
38591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->ext.mix.latency_class =
38601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
38611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
3862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3863e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd)
3864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
3866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
3867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
3868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
3870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
3872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
3874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
3876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
3878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Devices %08x\n", device());
3880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
3882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
38833b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
38843b73df74357b33869b39a1d69427673c780bd805Eric Laurent        snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n",
38853b73df74357b33869b39a1d69427673c780bd805Eric Laurent                 i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
3886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(buffer);
3887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
3889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
3891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioInputDescriptor class implementation
3894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
38951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
38961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    : mId(0), mIoHandle(0), mSamplingRate(0),
38971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent      mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(0),
38981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent      mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mRefCount(0),
38993b73df74357b33869b39a1d69427673c780bd805Eric Laurent      mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile)
3900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
39013a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (profile != NULL) {
39023a4311c68348f728558e87b5db67d47605783890Eric Laurent        mSamplingRate = profile->mSamplingRates[0];
39033a4311c68348f728558e87b5db67d47605783890Eric Laurent        mFormat = profile->mFormats[0];
39043a4311c68348f728558e87b5db67d47605783890Eric Laurent        mChannelMask = profile->mChannelMasks[0];
39053a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
3906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
39081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioInputDescriptor::toAudioPortConfig(
39091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                        struct audio_port_config *config) const
39101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
39111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->id = mId;
39121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->role = AUDIO_PORT_ROLE_SINK;
39131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->type = AUDIO_PORT_TYPE_MIX;
39141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->sample_rate = mSamplingRate;
39151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->channel_mask = mChannelMask;
39161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->format = mFormat;
39171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->gain.index = -1;
39181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
39191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                          AUDIO_PORT_CONFIG_FORMAT;
39201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->ext.mix.hw_module = mProfile->mModule->mHandle;
39211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->ext.mix.handle = mIoHandle;
39221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->ext.mix.usecase.source = (mInputSource == AUDIO_SOURCE_HOTWORD) ?
39231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                    AUDIO_SOURCE_VOICE_RECOGNITION : mInputSource;
39241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
39251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
39261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioInputDescriptor::toAudioPort(
39271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                    struct audio_port *port) const
39281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
39291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mProfile->toAudioPort(port);
39301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->id = mId;
39311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->ext.mix.handle = mIoHandle;
39321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
39331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
39341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
3935e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioInputDescriptor::dump(int fd)
3936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
3938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
3939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
3940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
3942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
3944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
3946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
3948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
3950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
3952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
3954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- StreamDescriptor class implementation
3957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3958e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::StreamDescriptor::StreamDescriptor()
3959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    :   mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
3960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0);
3962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3964e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::StreamDescriptor::getVolumeIndex(audio_devices_t device)
3965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3966e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    device = AudioPolicyManager::getDeviceForVolume(device);
3967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT
3968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mIndexCur.indexOfKey(device) < 0) {
3969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = AUDIO_DEVICE_OUT_DEFAULT;
3970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return mIndexCur.valueFor(device);
3972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3974e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::StreamDescriptor::dump(int fd)
3975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
3977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
3978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
3979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "%s         %02d         %02d         ",
3981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
3982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mIndexCur.size(); i++) {
3984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "%04x : %02d, ",
3985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                 mIndexCur.keyAt(i),
3986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                 mIndexCur.valueAt(i));
3987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(buffer);
3988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append("\n");
3990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
3992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- EffectDescriptor class implementation
3995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3996e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::EffectDescriptor::dump(int fd)
3997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
3999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
4000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
4001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " I/O: %d\n", mIo);
4003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy);
4005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Session: %d\n", mSession);
4007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Name: %s\n",  mDesc.name);
4009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " %s\n",  mEnabled ? "Enabled" : "Disabled");
4011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
4013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
4015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
40171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- HwModule class implementation
4018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4019e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::HwModule(const char *name)
4020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0)
4021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4024e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::~HwModule()
4025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputProfiles.size(); i++) {
40273a4311c68348f728558e87b5db67d47605783890Eric Laurent        mOutputProfiles[i]->mSupportedDevices.clear();
4028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mInputProfiles.size(); i++) {
40303a4311c68348f728558e87b5db67d47605783890Eric Laurent        mInputProfiles[i]->mSupportedDevices.clear();
4031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    free((void *)mName);
4033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4035e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::HwModule::dump(int fd)
4036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
4038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
4039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
4040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "  - name: %s\n", mName);
4042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "  - handle: %d\n", mHandle);
4044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
4046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mOutputProfiles.size()) {
4047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, "  - outputs:\n", strlen("  - outputs:\n"));
4048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputProfiles.size(); i++) {
4049d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            snprintf(buffer, SIZE, "    output %zu:\n", i);
4050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            write(fd, buffer, strlen(buffer));
4051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mOutputProfiles[i]->dump(fd);
4052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mInputProfiles.size()) {
4055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, "  - inputs:\n", strlen("  - inputs:\n"));
4056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mInputProfiles.size(); i++) {
4057d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            snprintf(buffer, SIZE, "    input %zu:\n", i);
4058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            write(fd, buffer, strlen(buffer));
4059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mInputProfiles[i]->dump(fd);
4060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
40641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- AudioPort class implementation
40651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
40661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const
40671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
40681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->role = mRole;
40691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->type = mType;
40701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    unsigned int i;
40711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) {
40721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        port->sample_rates[i] = mSamplingRates[i];
40731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
40741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->num_sample_rates = i;
40751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) {
40761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        port->channel_masks[i] = mChannelMasks[i];
40771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
40781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->num_channel_masks = i;
40791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) {
40801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        port->formats[i] = mFormats[i];
40811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
40821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->num_formats = i;
40831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->num_gains = 0;
40841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
40851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
40861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
40871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadSamplingRates(char *name)
40881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
40891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    char *str = strtok(name, "|");
40901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
40911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling
40921c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    // rates should be read from the output stream after it is opened for the first time
40931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
40941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        mSamplingRates.add(0);
40951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return;
40961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
40971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
40981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    while (str != NULL) {
40991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        uint32_t rate = atoi(str);
41001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (rate != 0) {
41011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("loadSamplingRates() adding rate %d", rate);
41021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            mSamplingRates.add(rate);
41031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
41041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        str = strtok(NULL, "|");
41051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
41061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return;
41071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
41081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadFormats(char *name)
41101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
41111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    char *str = strtok(name, "|");
41121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    // by convention, "0' in the first entry in mFormats indicates the supported formats
41141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    // should be read from the output stream after it is opened for the first time
41151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
41161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        mFormats.add(AUDIO_FORMAT_DEFAULT);
41171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return;
41181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
41191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    while (str != NULL) {
41211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable,
41221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                             ARRAY_SIZE(sFormatNameToEnumTable),
41231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                             str);
41241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (format != AUDIO_FORMAT_DEFAULT) {
41251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            mFormats.add(format);
41261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
41271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        str = strtok(NULL, "|");
41281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
41291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return;
41301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
41311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadInChannels(char *name)
41331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
41341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    const char *str = strtok(name, "|");
41351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("loadInChannels() %s", name);
41371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
41391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        mChannelMasks.add(0);
41401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return;
41411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
41421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    while (str != NULL) {
41441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        audio_channel_mask_t channelMask =
41451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable,
41461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                   ARRAY_SIZE(sInChannelsNameToEnumTable),
41471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                   str);
41481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (channelMask != 0) {
41491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("loadInChannels() adding channelMask %04x", channelMask);
41501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            mChannelMasks.add(channelMask);
41511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
41521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        str = strtok(NULL, "|");
41531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
41541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return;
41551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
41561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::AudioPort::loadOutChannels(char *name)
41581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
41591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    const char *str = strtok(name, "|");
41601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("loadOutChannels() %s", name);
41621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    // by convention, "0' in the first entry in mChannelMasks indicates the supported channel
41641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    // masks should be read from the output stream after it is opened for the first time
41651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
41661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        mChannelMasks.add(0);
41671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return;
41681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
41691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    while (str != NULL) {
41711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        audio_channel_mask_t channelMask =
41721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable,
41731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                   ARRAY_SIZE(sOutChannelsNameToEnumTable),
41741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                   str);
41751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (channelMask != 0) {
41761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            mChannelMasks.add(channelMask);
41771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
41781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        str = strtok(NULL, "|");
41791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
41801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return;
41811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
41821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent// --- IOProfile class implementation
41841c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
41851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::IOProfile::IOProfile(audio_port_role_t role, HwModule *module)
41861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    : AudioPort(AUDIO_PORT_TYPE_MIX, role, module), mFlags((audio_output_flags_t)0)
4187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4190e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile::~IOProfile()
4191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// checks if the IO profile is compatible with specified parameters.
4195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Sampling rate, format and channel mask must be specified in order to
4196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// get a valid a match
4197e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device,
4198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                            uint32_t samplingRate,
4199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                            audio_format_t format,
4200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                            audio_channel_mask_t channelMask,
4201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                            audio_output_flags_t flags) const
4202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (samplingRate == 0 || !audio_is_valid_format(format) || channelMask == 0) {
4204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
4205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
4206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
42073a4311c68348f728558e87b5db67d47605783890Eric Laurent     if ((mSupportedDevices.types() & device) != device) {
4208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
4209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
4210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     if ((mFlags & flags) != flags) {
4211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
4212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
4213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     size_t i;
4214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     for (i = 0; i < mSamplingRates.size(); i++)
4215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     {
4216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         if (mSamplingRates[i] == samplingRate) {
4217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             break;
4218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         }
4219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
4220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     if (i == mSamplingRates.size()) {
4221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
4222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
4223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     for (i = 0; i < mFormats.size(); i++)
4224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     {
4225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         if (mFormats[i] == format) {
4226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             break;
4227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         }
4228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
4229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     if (i == mFormats.size()) {
4230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
4231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
4232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     for (i = 0; i < mChannelMasks.size(); i++)
4233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     {
4234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         if (mChannelMasks[i] == channelMask) {
4235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             break;
4236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         }
4237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
4238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     if (i == mChannelMasks.size()) {
4239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
4240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
4241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     return true;
4242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4244e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::IOProfile::dump(int fd)
4245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
4247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
4248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
4249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "    - sampling rates: ");
4251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mSamplingRates.size(); i++) {
4253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "%d", mSamplingRates[i]);
4254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(buffer);
4255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(i == (mSamplingRates.size() - 1) ? "\n" : ", ");
4256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "    - channel masks: ");
4259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mChannelMasks.size(); i++) {
4261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]);
4262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(buffer);
4263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(i == (mChannelMasks.size() - 1) ? "\n" : ", ");
4264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "    - formats: ");
4267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mFormats.size(); i++) {
4269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "0x%08x", mFormats[i]);
4270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(buffer);
4271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(i == (mFormats.size() - 1) ? "\n" : ", ");
4272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
42743a4311c68348f728558e87b5db67d47605783890Eric Laurent    snprintf(buffer, SIZE, "    - devices:\n");
4275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
42763a4311c68348f728558e87b5db67d47605783890Eric Laurent    write(fd, result.string(), result.size());
42773a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceDescriptor::dumpHeader(fd, 6);
42783a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i < mSupportedDevices.size(); i++) {
42793a4311c68348f728558e87b5db67d47605783890Eric Laurent        mSupportedDevices[i]->dump(fd, 6);
42803a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
42813a4311c68348f728558e87b5db67d47605783890Eric Laurent
4282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "    - flags: 0x%04x\n", mFlags);
4283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
4286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4288d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::IOProfile::log()
4289d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
4290d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    const size_t SIZE = 256;
4291d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    char buffer[SIZE];
4292d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    String8 result;
4293d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4294d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    ALOGV("    - sampling rates: ");
4295d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    for (size_t i = 0; i < mSamplingRates.size(); i++) {
4296d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        ALOGV("  %d", mSamplingRates[i]);
4297d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }
4298d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4299d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    ALOGV("    - channel masks: ");
4300d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    for (size_t i = 0; i < mChannelMasks.size(); i++) {
4301d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        ALOGV("  0x%04x", mChannelMasks[i]);
4302d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }
4303d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4304d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    ALOGV("    - formats: ");
4305d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    for (size_t i = 0; i < mFormats.size(); i++) {
4306d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        ALOGV("  0x%08x", mFormats[i]);
4307d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }
4308d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4309d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    ALOGV("    - devices: 0x%04x\n", mSupportedDevices.types());
4310d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    ALOGV("    - flags: 0x%04x\n", mFlags);
4311d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
4312d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4313d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
43143a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- DeviceDescriptor implementation
4315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43163a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
43173a4311c68348f728558e87b5db67d47605783890Eric Laurent{
43183a4311c68348f728558e87b5db67d47605783890Eric Laurent    // Devices are considered equal if they:
43193a4311c68348f728558e87b5db67d47605783890Eric Laurent    // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
43203a4311c68348f728558e87b5db67d47605783890Eric Laurent    // - have the same address or one device does not specify the address
43213a4311c68348f728558e87b5db67d47605783890Eric Laurent    // - have the same channel mask or one device does not specify the channel mask
43221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return (mDeviceType == other->mDeviceType) &&
43233a4311c68348f728558e87b5db67d47605783890Eric Laurent           (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) &&
43242f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent           (mChannelMask == 0 || other->mChannelMask == 0 ||
43253a4311c68348f728558e87b5db67d47605783890Eric Laurent                mChannelMask == other->mChannelMask);
43263a4311c68348f728558e87b5db67d47605783890Eric Laurent}
4327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43283a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::refreshTypes()
43293a4311c68348f728558e87b5db67d47605783890Eric Laurent{
43301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mDeviceTypes = AUDIO_DEVICE_NONE;
43313a4311c68348f728558e87b5db67d47605783890Eric Laurent    for(size_t i = 0; i < size(); i++) {
43321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        mDeviceTypes |= itemAt(i)->mDeviceType;
43333a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
43341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes);
43353a4311c68348f728558e87b5db67d47605783890Eric Laurent}
4336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43373a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
43383a4311c68348f728558e87b5db67d47605783890Eric Laurent{
43393a4311c68348f728558e87b5db67d47605783890Eric Laurent    for(size_t i = 0; i < size(); i++) {
43403a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (item->equals(itemAt(i))) {
43413a4311c68348f728558e87b5db67d47605783890Eric Laurent            return i;
43423a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
43433a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
43443a4311c68348f728558e87b5db67d47605783890Eric Laurent    return -1;
43453a4311c68348f728558e87b5db67d47605783890Eric Laurent}
4346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43473a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::add(const sp<DeviceDescriptor>& item)
43483a4311c68348f728558e87b5db67d47605783890Eric Laurent{
43493a4311c68348f728558e87b5db67d47605783890Eric Laurent    ssize_t ret = indexOf(item);
4350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43513a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (ret < 0) {
43523a4311c68348f728558e87b5db67d47605783890Eric Laurent        ret = SortedVector::add(item);
43533a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (ret >= 0) {
43543a4311c68348f728558e87b5db67d47605783890Eric Laurent            refreshTypes();
43553a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
43563a4311c68348f728558e87b5db67d47605783890Eric Laurent    } else {
43571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        ALOGW("DeviceVector::add device %08x already in", item->mDeviceType);
43583a4311c68348f728558e87b5db67d47605783890Eric Laurent        ret = -1;
43593a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
43603a4311c68348f728558e87b5db67d47605783890Eric Laurent    return ret;
43613a4311c68348f728558e87b5db67d47605783890Eric Laurent}
4362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43633a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::remove(const sp<DeviceDescriptor>& item)
43643a4311c68348f728558e87b5db67d47605783890Eric Laurent{
43653a4311c68348f728558e87b5db67d47605783890Eric Laurent    size_t i;
43663a4311c68348f728558e87b5db67d47605783890Eric Laurent    ssize_t ret = indexOf(item);
4367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43683a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (ret < 0) {
43691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        ALOGW("DeviceVector::remove device %08x not in", item->mDeviceType);
43703a4311c68348f728558e87b5db67d47605783890Eric Laurent    } else {
43713a4311c68348f728558e87b5db67d47605783890Eric Laurent        ret = SortedVector::removeAt(ret);
43723a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (ret >= 0) {
43733a4311c68348f728558e87b5db67d47605783890Eric Laurent            refreshTypes();
43743a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
43753a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
43763a4311c68348f728558e87b5db67d47605783890Eric Laurent    return ret;
43773a4311c68348f728558e87b5db67d47605783890Eric Laurent}
4378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43793a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::loadDevicesFromType(audio_devices_t types)
4380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
43813a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceVector deviceList;
43823a4311c68348f728558e87b5db67d47605783890Eric Laurent
43833a4311c68348f728558e87b5db67d47605783890Eric Laurent    uint32_t role_bit = AUDIO_DEVICE_BIT_IN & types;
43843a4311c68348f728558e87b5db67d47605783890Eric Laurent    types &= ~role_bit;
43853a4311c68348f728558e87b5db67d47605783890Eric Laurent
43863a4311c68348f728558e87b5db67d47605783890Eric Laurent    while (types) {
43873a4311c68348f728558e87b5db67d47605783890Eric Laurent        uint32_t i = 31 - __builtin_clz(types);
43883a4311c68348f728558e87b5db67d47605783890Eric Laurent        uint32_t type = 1 << i;
43893a4311c68348f728558e87b5db67d47605783890Eric Laurent        types &= ~type;
43903a4311c68348f728558e87b5db67d47605783890Eric Laurent        add(new DeviceDescriptor(type | role_bit));
4391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentsp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDevice(
43951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                        audio_devices_t type, String8 address) const
43961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
43971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    sp<DeviceDescriptor> device;
43981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    for (size_t i = 0; i < size(); i++) {
43991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (itemAt(i)->mDeviceType == type) {
44001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            device = itemAt(i);
44011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            if (itemAt(i)->mAddress = address) {
44021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                break;
44031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
44041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
44051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
44061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("DeviceVector::getDevice() for type %d address %s found %p",
44071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent          type, address.string(), device.get());
44081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return device;
44091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
44101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
44111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric LaurentAudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromType(
44121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                                        audio_devices_t type) const
44131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
44141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    DeviceVector devices;
44151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
44161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (itemAt(i)->mDeviceType & type & ~AUDIO_DEVICE_BIT_IN) {
44171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            devices.add(itemAt(i));
44181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            type &= ~itemAt(i)->mDeviceType;
44191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("DeviceVector::getDevicesFromType() for type %x found %p",
44201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                  itemAt(i)->mDeviceType, itemAt(i).get());
44211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
44221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
44231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return devices;
44241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
44251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
44261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::DeviceDescriptor::toAudioPortConfig(struct audio_port_config *config) const
44271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
44281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->id = mId;
44291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->role = audio_is_output_device(mDeviceType) ?
44301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                        AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
44311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->type = AUDIO_PORT_TYPE_DEVICE;
44321c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->sample_rate = 0;
44331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->channel_mask = mChannelMask;
44341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->format = AUDIO_FORMAT_DEFAULT;
44351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK;
44361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->gain.index = -1;
44371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    config->ext.device.type = mDeviceType;
44381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    strncpy(config->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
44391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
44401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
44411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentvoid AudioPolicyManager::DeviceDescriptor::toAudioPort(struct audio_port *port) const
44421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
44431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    AudioPort::toAudioPort(port);
44441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->id = mId;
44451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    port->ext.device.type = mDeviceType;
44461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
44471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
44481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
44493a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceDescriptor::dumpHeader(int fd, int spaces)
4450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
44513a4311c68348f728558e87b5db67d47605783890Eric Laurent    const size_t SIZE = 256;
44523a4311c68348f728558e87b5db67d47605783890Eric Laurent    char buffer[SIZE];
44533a4311c68348f728558e87b5db67d47605783890Eric Laurent
44543a4311c68348f728558e87b5db67d47605783890Eric Laurent    snprintf(buffer, SIZE, "%*s%-48s %-2s %-8s %-32s \n",
44553a4311c68348f728558e87b5db67d47605783890Eric Laurent                         spaces, "", "Type", "ID", "Cnl Mask", "Address");
44563a4311c68348f728558e87b5db67d47605783890Eric Laurent    write(fd, buffer, strlen(buffer));
4457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
44593a4311c68348f728558e87b5db67d47605783890Eric Laurentstatus_t AudioPolicyManager::DeviceDescriptor::dump(int fd, int spaces) const
44603a4311c68348f728558e87b5db67d47605783890Eric Laurent{
44613a4311c68348f728558e87b5db67d47605783890Eric Laurent    const size_t SIZE = 256;
44623a4311c68348f728558e87b5db67d47605783890Eric Laurent    char buffer[SIZE];
44633a4311c68348f728558e87b5db67d47605783890Eric Laurent
44643a4311c68348f728558e87b5db67d47605783890Eric Laurent    snprintf(buffer, SIZE, "%*s%-48s %2d %08x %-32s \n",
44653a4311c68348f728558e87b5db67d47605783890Eric Laurent                         spaces, "",
44663a4311c68348f728558e87b5db67d47605783890Eric Laurent                         enumToString(sDeviceNameToEnumTable,
44673a4311c68348f728558e87b5db67d47605783890Eric Laurent                                      ARRAY_SIZE(sDeviceNameToEnumTable),
44681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                      mDeviceType),
44693a4311c68348f728558e87b5db67d47605783890Eric Laurent                         mId, mChannelMask, mAddress.string());
44703a4311c68348f728558e87b5db67d47605783890Eric Laurent    write(fd, buffer, strlen(buffer));
44713a4311c68348f728558e87b5db67d47605783890Eric Laurent
44723a4311c68348f728558e87b5db67d47605783890Eric Laurent    return NO_ERROR;
44733a4311c68348f728558e87b5db67d47605783890Eric Laurent}
44743a4311c68348f728558e87b5db67d47605783890Eric Laurent
44753a4311c68348f728558e87b5db67d47605783890Eric Laurent
44763a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- audio_policy.conf file parsing
44773a4311c68348f728558e87b5db67d47605783890Eric Laurent
4478e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_output_flags_t AudioPolicyManager::parseFlagNames(char *name)
4479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t flag = 0;
4481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // it is OK to cast name to non const here as we are not going to use it after
4483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // strtok() modifies it
4484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char *flagName = strtok(name, "|");
4485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (flagName != NULL) {
4486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strlen(flagName) != 0) {
4487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            flag |= stringToEnum(sFlagNameToEnumTable,
4488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                               ARRAY_SIZE(sFlagNameToEnumTable),
4489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                               flagName);
4490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        flagName = strtok(NULL, "|");
4492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //force direct flag if offload flag is set: offloading implies a direct output stream
4494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and all common behaviors are driven by checking only the direct flag
4495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // this should normally be set appropriately in the policy configuration file
4496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
4497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        flag |= AUDIO_OUTPUT_FLAG_DIRECT;
4498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return (audio_output_flags_t)flag;
4501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4503e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::parseDeviceNames(char *name)
4504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t device = 0;
4506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char *devName = strtok(name, "|");
4508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (devName != NULL) {
4509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strlen(devName) != 0) {
4510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device |= stringToEnum(sDeviceNameToEnumTable,
4511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                 ARRAY_SIZE(sDeviceNameToEnumTable),
4512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                 devName);
45133a4311c68348f728558e87b5db67d47605783890Eric Laurent         }
4514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        devName = strtok(NULL, "|");
45153a4311c68348f728558e87b5db67d47605783890Eric Laurent     }
4516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
4517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4519e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadInput(cnode *root, HwModule *module)
4520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *node = root->first_child;
4522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
45231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    sp<IOProfile> profile = new IOProfile(AUDIO_PORT_ROLE_SINK, module);
4524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (node) {
4526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
45271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            profile->loadSamplingRates((char *)node->value);
4528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
45291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            profile->loadFormats((char *)node->value);
4530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
45311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            profile->loadInChannels((char *)node->value);
4532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
45333a4311c68348f728558e87b5db67d47605783890Eric Laurent            profile->mSupportedDevices.loadDevicesFromType(parseDeviceNames((char *)node->value));
4534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->next;
4536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
45373a4311c68348f728558e87b5db67d47605783890Eric Laurent    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
4538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadInput() invalid supported devices");
4539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mChannelMasks.size() == 0,
4540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadInput() invalid supported channel masks");
4541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mSamplingRates.size() == 0,
4542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadInput() invalid supported sampling rates");
4543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mFormats.size() == 0,
4544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadInput() invalid supported formats");
45453a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (!profile->mSupportedDevices.isEmpty() &&
4546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mChannelMasks.size() != 0) &&
4547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mSamplingRates.size() != 0) &&
4548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mFormats.size() != 0)) {
4549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
45503a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGV("loadInput() adding input Supported Devices %04x",
45513a4311c68348f728558e87b5db67d47605783890Eric Laurent              profile->mSupportedDevices.types());
4552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        module->mInputProfiles.add(profile);
4554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
4555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
4556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
4557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4560e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadOutput(cnode *root, HwModule *module)
4561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *node = root->first_child;
4563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
45641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    sp<IOProfile> profile = new IOProfile(AUDIO_PORT_ROLE_SOURCE, module);
4565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (node) {
4567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
45681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            profile->loadSamplingRates((char *)node->value);
4569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
45701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            profile->loadFormats((char *)node->value);
4571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
45721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            profile->loadOutChannels((char *)node->value);
4573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
45743a4311c68348f728558e87b5db67d47605783890Eric Laurent            profile->mSupportedDevices.loadDevicesFromType(parseDeviceNames((char *)node->value));
4575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, FLAGS_TAG) == 0) {
4576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            profile->mFlags = parseFlagNames((char *)node->value);
4577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->next;
4579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
45803a4311c68348f728558e87b5db67d47605783890Eric Laurent    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
4581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadOutput() invalid supported devices");
4582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mChannelMasks.size() == 0,
4583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadOutput() invalid supported channel masks");
4584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mSamplingRates.size() == 0,
4585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadOutput() invalid supported sampling rates");
4586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mFormats.size() == 0,
4587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadOutput() invalid supported formats");
45883a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (!profile->mSupportedDevices.isEmpty() &&
4589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mChannelMasks.size() != 0) &&
4590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mSamplingRates.size() != 0) &&
4591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mFormats.size() != 0)) {
4592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
45933a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x",
45943a4311c68348f728558e87b5db67d47605783890Eric Laurent              profile->mSupportedDevices.types(), profile->mFlags);
4595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        module->mOutputProfiles.add(profile);
4597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
4598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
4599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
4600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4603e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModule(cnode *root)
4604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *node = config_find(root, OUTPUTS_TAG);
4606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    status_t status = NAME_NOT_FOUND;
4607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    HwModule *module = new HwModule(root->name);
4609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (node != NULL) {
4611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->first_child;
4612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        while (node) {
4613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("loadHwModule() loading output %s", node->name);
4614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            status_t tmpStatus = loadOutput(node, module);
4615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (status == NAME_NOT_FOUND || status == NO_ERROR) {
4616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                status = tmpStatus;
4617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            node = node->next;
4619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    node = config_find(root, INPUTS_TAG);
4622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (node != NULL) {
4623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->first_child;
4624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        while (node) {
4625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("loadHwModule() loading input %s", node->name);
4626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            status_t tmpStatus = loadInput(node, module);
4627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (status == NAME_NOT_FOUND || status == NO_ERROR) {
4628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                status = tmpStatus;
4629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            node = node->next;
4631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (status == NO_ERROR) {
4634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mHwModules.add(module);
4635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
4636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete module;
4637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4640e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModules(cnode *root)
4641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *node = config_find(root, AUDIO_HW_MODULE_TAG);
4643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (node == NULL) {
4644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    node = node->first_child;
4648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (node) {
4649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("loadHwModules() loading module %s", node->name);
4650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        loadHwModule(node);
4651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->next;
4652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4655e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadGlobalConfig(cnode *root)
4656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *node = config_find(root, GLOBAL_CONFIG_TAG);
4658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (node == NULL) {
4659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    node = node->first_child;
4662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (node) {
4663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) {
46643a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.loadDevicesFromType(parseDeviceNames((char *)node->value));
46653a4311c68348f728558e87b5db67d47605783890Eric Laurent            ALOGV("loadGlobalConfig() Attached Output Devices %08x",
46663a4311c68348f728558e87b5db67d47605783890Eric Laurent                  mAvailableOutputDevices.types());
4667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) {
46683a4311c68348f728558e87b5db67d47605783890Eric Laurent            audio_devices_t device = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable,
4669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                              ARRAY_SIZE(sDeviceNameToEnumTable),
4670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                              (char *)node->value);
46713a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (device != AUDIO_DEVICE_NONE) {
46723a4311c68348f728558e87b5db67d47605783890Eric Laurent                mDefaultOutputDevice = new DeviceDescriptor(device);
46733a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
46743a4311c68348f728558e87b5db67d47605783890Eric Laurent                ALOGW("loadGlobalConfig() default device not specified");
46753a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
46761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", mDefaultOutputDevice->mDeviceType);
4677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) {
46783a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.loadDevicesFromType(parseDeviceNames((char *)node->value));
46793a4311c68348f728558e87b5db67d47605783890Eric Laurent            ALOGV("loadGlobalConfig() Available InputDevices %08x", mAvailableInputDevices.types());
4680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) {
4681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mSpeakerDrcEnabled = stringToBool((char *)node->value);
4682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled);
4683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->next;
4685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4688e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadAudioPolicyConfig(const char *path)
4689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *root;
4691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char *data;
4692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    data = (char *)load_file(path, NULL);
4694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (data == NULL) {
4695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return -ENODEV;
4696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    root = config_node("", "");
4698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    config_load(root, data);
4699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    loadGlobalConfig(root);
4701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    loadHwModules(root);
4702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    config_free(root);
4704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    free(root);
4705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    free(data);
4706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGI("loadAudioPolicyConfig() loaded %s\n", path);
4708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
4710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4712e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::defaultAudioPolicyConfig(void)
4713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    HwModule *module;
47151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    sp<IOProfile> profile;
47163a4311c68348f728558e87b5db67d47605783890Eric Laurent    sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
47173a4311c68348f728558e87b5db67d47605783890Eric Laurent    mAvailableOutputDevices.add(mDefaultOutputDevice);
47183a4311c68348f728558e87b5db67d47605783890Eric Laurent    mAvailableInputDevices.add(defaultInputDevice);
4719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    module = new HwModule("primary");
4721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
47221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    profile = new IOProfile(AUDIO_PORT_ROLE_SOURCE, module);
4723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mSamplingRates.add(44100);
4724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
4725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO);
47263a4311c68348f728558e87b5db67d47605783890Eric Laurent    profile->mSupportedDevices.add(mDefaultOutputDevice);
4727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY;
4728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    module->mOutputProfiles.add(profile);
4729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
47301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    profile = new IOProfile(AUDIO_PORT_ROLE_SINK, module);
4731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mSamplingRates.add(8000);
4732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
4733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO);
47343a4311c68348f728558e87b5db67d47605783890Eric Laurent    profile->mSupportedDevices.add(defaultInputDevice);
4735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    module->mInputProfiles.add(profile);
4736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mHwModules.add(module);
4738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; // namespace android
4741