AudioPolicyManager.cpp revision 5b61dddd0dba28922068da2487894761486aec6c
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),
733a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
743a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
753a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY),
763a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE),
773a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB),
783a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX),
793a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
803a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
813a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO),
823a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
833a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
843a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
853a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
863a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
873a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
883a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
893a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
90d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
913a4311c68348f728558e87b5db67d47605783890Eric Laurent};
923a4311c68348f728558e87b5db67d47605783890Eric Laurent
933a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFlagNameToEnumTable[] = {
943a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT),
953a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
963a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST),
973a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
983a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
993a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
1003a4311c68348f728558e87b5db67d47605783890Eric Laurent};
1013a4311c68348f728558e87b5db67d47605783890Eric Laurent
1023a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sFormatNameToEnumTable[] = {
1033a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT),
1043a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT),
1053a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT),
1063a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT),
1073a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT),
1083a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED),
1093a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_MP3),
1103a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_AAC),
1113a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_FORMAT_VORBIS),
1123a4311c68348f728558e87b5db67d47605783890Eric Laurent};
1133a4311c68348f728558e87b5db67d47605783890Eric Laurent
1143a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sOutChannelsNameToEnumTable[] = {
1153a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO),
1163a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
1173a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
1183a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
1193a4311c68348f728558e87b5db67d47605783890Eric Laurent};
1203a4311c68348f728558e87b5db67d47605783890Eric Laurent
1213a4311c68348f728558e87b5db67d47605783890Eric Laurentconst StringToEnum sInChannelsNameToEnumTable[] = {
1223a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO),
1233a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO),
1243a4311c68348f728558e87b5db67d47605783890Eric Laurent    STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK),
1253a4311c68348f728558e87b5db67d47605783890Eric Laurent};
1263a4311c68348f728558e87b5db67d47605783890Eric Laurent
1273a4311c68348f728558e87b5db67d47605783890Eric Laurent
1283a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::stringToEnum(const struct StringToEnum *table,
1293a4311c68348f728558e87b5db67d47605783890Eric Laurent                                              size_t size,
1303a4311c68348f728558e87b5db67d47605783890Eric Laurent                                              const char *name)
1313a4311c68348f728558e87b5db67d47605783890Eric Laurent{
1323a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i < size; i++) {
1333a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (strcmp(table[i].name, name) == 0) {
1343a4311c68348f728558e87b5db67d47605783890Eric Laurent            ALOGV("stringToEnum() found %s", table[i].name);
1353a4311c68348f728558e87b5db67d47605783890Eric Laurent            return table[i].value;
1363a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
1373a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
1383a4311c68348f728558e87b5db67d47605783890Eric Laurent    return 0;
1393a4311c68348f728558e87b5db67d47605783890Eric Laurent}
1403a4311c68348f728558e87b5db67d47605783890Eric Laurent
1413a4311c68348f728558e87b5db67d47605783890Eric Laurentconst char *AudioPolicyManager::enumToString(const struct StringToEnum *table,
1423a4311c68348f728558e87b5db67d47605783890Eric Laurent                                              size_t size,
1433a4311c68348f728558e87b5db67d47605783890Eric Laurent                                              uint32_t value)
1443a4311c68348f728558e87b5db67d47605783890Eric Laurent{
1453a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i < size; i++) {
1463a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (table[i].value == value) {
1473a4311c68348f728558e87b5db67d47605783890Eric Laurent            return table[i].name;
1483a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
1493a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
1503a4311c68348f728558e87b5db67d47605783890Eric Laurent    return "";
1513a4311c68348f728558e87b5db67d47605783890Eric Laurent}
1523a4311c68348f728558e87b5db67d47605783890Eric Laurent
1533a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::stringToBool(const char *value)
1543a4311c68348f728558e87b5db67d47605783890Eric Laurent{
1553a4311c68348f728558e87b5db67d47605783890Eric Laurent    return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0));
1563a4311c68348f728558e87b5db67d47605783890Eric Laurent}
1573a4311c68348f728558e87b5db67d47605783890Eric Laurent
1583a4311c68348f728558e87b5db67d47605783890Eric Laurent
1593a4311c68348f728558e87b5db67d47605783890Eric Laurent// ----------------------------------------------------------------------------
160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AudioPolicyInterface implementation
161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
164e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
1653b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                          audio_policy_dev_state_t state,
166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                  const char *device_address)
167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1683a4311c68348f728558e87b5db67d47605783890Eric Laurent    String8 address = String8(device_address);
169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address);
171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // connect/disconnect only 1 device at a time
173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle output devices
176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_output_device(device)) {
177d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        SortedVector <audio_io_handle_t> outputs;
178d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
1793a4311c68348f728558e87b5db67d47605783890Eric Laurent        sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device,
1803a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                            address,
1812f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent                                                            0);
1823a4311c68348f728558e87b5db67d47605783890Eric Laurent        ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
1833a4311c68348f728558e87b5db67d47605783890Eric Laurent
184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // save a copy of the opened output descriptors before any output is opened or closed
185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mPreviousOutputs = mOutputs;
187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        switch (state)
188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle output device connection
1903b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE:
1913a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device already connected: %x", device);
193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setDeviceConnectionState() connecting device %x", device);
196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1973a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (checkOutputsForDevice(device, state, outputs, address) != NO_ERROR) {
198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
200d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                  outputs.size());
202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // register new device as available
2033a4311c68348f728558e87b5db67d47605783890Eric Laurent            index = mAvailableOutputDevices.add(devDesc);
2043a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
2053a4311c68348f728558e87b5db67d47605783890Eric Laurent                mAvailableOutputDevices[index]->mId = nextUniqueId();
2063a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
2073a4311c68348f728558e87b5db67d47605783890Eric Laurent                return NO_MEMORY;
208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            break;
211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle output device disconnection
2123b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
2133a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index < 0) {
214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device not connected: %x", device);
215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setDeviceConnectionState() disconnecting device %x", device);
219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // remove device from available output devices
2203a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.remove(devDesc);
2213a4311c68348f728558e87b5db67d47605783890Eric Laurent
2223a4311c68348f728558e87b5db67d47605783890Eric Laurent            checkOutputsForDevice(device, state, outputs, address);
223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // not currently handling multiple simultaneous submixes: ignoring remote submix
224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            //   case and address
225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } break;
226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("setDeviceConnectionState() invalid state: %x", state);
229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2323a4311c68348f728558e87b5db67d47605783890Eric Laurent        // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
2333a4311c68348f728558e87b5db67d47605783890Eric Laurent        // output is suspended before any tracks are moved to it
234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkA2dpSuspend();
235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkOutputForAllStrategies();
236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // outputs must be closed after checkOutputForAllStrategies() is executed
237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputs.isEmpty()) {
238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < outputs.size(); i++) {
239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]);
240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // close unused outputs after device disconnection or direct outputs that have been
241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // opened by checkOutputsForDevice() to query dynamic parameters
2423b73df74357b33869b39a1d69427673c780bd805Eric Laurent                if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                         (desc->mDirectOpenCount == 0))) {
245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    closeOutput(outputs[i]);
246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2483a4311c68348f728558e87b5db67d47605783890Eric Laurent            // check again after closing A2DP output to reset mA2dpSuspended if needed
2493a4311c68348f728558e87b5db67d47605783890Eric Laurent            checkA2dpSuspend();
250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        updateDevicesAndOutputs();
253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // do not force device change on duplicated output because if device is 0, it will
255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // also force a device 0 for the two outputs it is duplicated to which may override
256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // a valid device selection on those outputs.
257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setOutputDevice(mOutputs.keyAt(i),
258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            getNewDevice(mOutputs.keyAt(i), true /*fromCache*/),
259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            !mOutputs.valueAt(i)->isDuplicated(),
260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            0);
261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET) {
264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_WIRED_HEADSET;
265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO ||
266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                   device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                   device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else {
270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return NO_ERROR;
271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
272d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }  // end if is output device
273d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle input devices
275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_input_device(device)) {
276d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        SortedVector <audio_io_handle_t> inputs;
277d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2783a4311c68348f728558e87b5db67d47605783890Eric Laurent        sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device,
2793a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                            address,
2802f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent                                                            0);
281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2823a4311c68348f728558e87b5db67d47605783890Eric Laurent        ssize_t index = mAvailableInputDevices.indexOf(devDesc);
283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        switch (state)
284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle input device connection
2863b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
2873a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device already connected: %d", device);
289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
291d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (checkInputsForDevice(device, state, inputs, address) != NO_ERROR) {
292d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                return INVALID_OPERATION;
293d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
294d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2953a4311c68348f728558e87b5db67d47605783890Eric Laurent            index = mAvailableInputDevices.add(devDesc);
2963a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
2973a4311c68348f728558e87b5db67d47605783890Eric Laurent                mAvailableInputDevices[index]->mId = nextUniqueId();
2983a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
2993a4311c68348f728558e87b5db67d47605783890Eric Laurent                return NO_MEMORY;
3003a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
301d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } break;
302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle input device disconnection
3043b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
3053a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index < 0) {
306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device not connected: %d", device);
307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
309d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            checkInputsForDevice(device, state, inputs, address);
3103a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.remove(devDesc);
311d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } break;
312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("setDeviceConnectionState() invalid state: %x", state);
315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
318d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        closeAllInputs();
319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
321d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } // end if is input device
322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW("setDeviceConnectionState() invalid device: %x", device);
324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return BAD_VALUE;
325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
327e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                  const char *device_address)
329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3303b73df74357b33869b39a1d69427673c780bd805Eric Laurent    audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 address = String8(device_address);
3323a4311c68348f728558e87b5db67d47605783890Eric Laurent    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device,
3333a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                        String8(device_address),
3342f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent                                                        0);
3353a4311c68348f728558e87b5db67d47605783890Eric Laurent    ssize_t index;
3363a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceVector *deviceVector;
3373a4311c68348f728558e87b5db67d47605783890Eric Laurent
338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_output_device(device)) {
3393a4311c68348f728558e87b5db67d47605783890Eric Laurent        deviceVector = &mAvailableOutputDevices;
340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (audio_is_input_device(device)) {
3413a4311c68348f728558e87b5db67d47605783890Eric Laurent        deviceVector = &mAvailableInputDevices;
3423a4311c68348f728558e87b5db67d47605783890Eric Laurent    } else {
3433a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGW("getDeviceConnectionState() invalid device type %08x", device);
3443a4311c68348f728558e87b5db67d47605783890Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3473a4311c68348f728558e87b5db67d47605783890Eric Laurent    index = deviceVector->indexOf(devDesc);
3483a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (index >= 0) {
3493a4311c68348f728558e87b5db67d47605783890Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_AVAILABLE;
3503a4311c68348f728558e87b5db67d47605783890Eric Laurent    } else {
3513a4311c68348f728558e87b5db67d47605783890Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
3523a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
355e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setPhoneState(audio_mode_t state)
356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setPhoneState() state %d", state);
358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t newDevice = AUDIO_DEVICE_NONE;
3593b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state < 0 || state >= AUDIO_MODE_CNT) {
360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("setPhoneState() invalid state %d", state);
361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (state == mPhoneState ) {
365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("setPhoneState() setting same state %d", state);
366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if leaving call state, handle special case of active streams
370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // pertaining to sonification strategy see handleIncallSonification()
371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isInCall()) {
372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setPhoneState() in call state management: new state is %d", state);
3733b73df74357b33869b39a1d69427673c780bd805Eric Laurent        for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
3743b73df74357b33869b39a1d69427673c780bd805Eric Laurent            handleIncallSonification((audio_stream_type_t)stream, false, true);
375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // store previous phone state for management of sonification strategy below
379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int oldState = mPhoneState;
380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPhoneState = state;
381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    bool force = false;
382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // are we entering or starting a call
384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!isStateInCall(oldState) && isStateInCall(state)) {
385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("  Entering call in setPhoneState()");
386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // force routing command to audio hardware when starting a call
387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // even if no device change is needed
388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        force = true;
389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j];
392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (isStateInCall(oldState) && !isStateInCall(state)) {
394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("  Exiting call in setPhoneState()");
395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // force routing command to audio hardware when exiting a call
396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // even if no device change is needed
397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        force = true;
398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    sVolumeProfiles[AUDIO_STREAM_DTMF][j];
401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (isStateInCall(state) && (state != oldState)) {
403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("  Switching between telephony and VoIP in setPhoneState()");
404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // force routing command to audio hardware when switching between telephony and VoIP
405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // even if no device change is needed
406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        force = true;
407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check for device and output changes triggered by new phone state
410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/);
411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkA2dpSuspend();
412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForAllStrategies();
413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // force routing command to audio hardware when ending call
418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // even if no device change is needed
419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) {
420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        newDevice = hwOutputDesc->device();
421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int delayMs = 0;
424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(state)) {
425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        nsecs_t sysTime = systemTime();
426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // mute media and sonification strategies and delay device switch by the largest
429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // latency of any output where either strategy is active.
430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // This avoid sending the ring tone or music tail into the earpiece or headset.
431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if ((desc->isStrategyActive(STRATEGY_MEDIA,
432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                     SONIFICATION_HEADSET_MUSIC_DELAY,
433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                     sysTime) ||
434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    desc->isStrategyActive(STRATEGY_SONIFICATION,
435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                         SONIFICATION_HEADSET_MUSIC_DELAY,
436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                         sysTime)) &&
437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    (delayMs < (int)desc->mLatency*2)) {
438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                delayMs = desc->mLatency*2;
439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i));
444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS,
445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // change routing is necessary
450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    setOutputDevice(mPrimaryOutput, newDevice, force, delayMs);
451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if entering in call state, handle special case of active streams
453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // pertaining to sonification strategy see handleIncallSonification()
454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(state)) {
455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setPhoneState() in call state management: new state is %d", state);
4563b73df74357b33869b39a1d69427673c780bd805Eric Laurent        for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
4573b73df74357b33869b39a1d69427673c780bd805Eric Laurent            handleIncallSonification((audio_stream_type_t)stream, true, true);
458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
4623b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state == AUDIO_MODE_RINGTONE &&
4633b73df74357b33869b39a1d69427673c780bd805Eric Laurent        isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mLimitRingtoneVolume = true;
465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mLimitRingtoneVolume = false;
467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
470e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
4713b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                         audio_policy_forced_cfg_t config)
472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    bool forceVolumeReeval = false;
476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch(usage) {
4773b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
4783b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
4793b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_NONE) {
480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        forceVolumeReeval = true;
484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mForceUse[usage] = config;
485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
4863b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_POLICY_FORCE_FOR_MEDIA:
4873b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
4883b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
4893b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
4903b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
4913b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_NO_BT_A2DP) {
492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mForceUse[usage] = config;
496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
4973b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_POLICY_FORCE_FOR_RECORD:
4983b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
4993b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_NONE) {
500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mForceUse[usage] = config;
504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
5053b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_POLICY_FORCE_FOR_DOCK:
5063b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
5073b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
5083b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
5093b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
5103b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        forceVolumeReeval = true;
514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mForceUse[usage] = config;
515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
5163b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_POLICY_FORCE_FOR_SYSTEM:
5173b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (config != AUDIO_POLICY_FORCE_NONE &&
5183b73df74357b33869b39a1d69427673c780bd805Eric Laurent            config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        forceVolumeReeval = true;
522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mForceUse[usage] = config;
523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("setForceUse() invalid usage %d", usage);
526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check for device and output changes triggered by new force usage
530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkA2dpSuspend();
531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForAllStrategies();
532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_io_handle_t output = mOutputs.keyAt(i);
535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_devices_t newDevice = getNewDevice(output, true /*fromCache*/);
536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            applyStreamVolumes(output, newDevice, 0, true);
539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t activeInput = getActiveInput();
543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (activeInput != 0) {
544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) {
547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setForceUse() changing device from %x to %x for input %d",
548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    inputDesc->mDevice, newDevice, activeInput);
549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            inputDesc->mDevice = newDevice;
550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioParameter param = AudioParameter();
551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->setParameters(activeInput, param.toString());
553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
558e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return mForceUse[usage];
561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
563e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setSystemProperty(const char* property, const char* value)
564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setSystemProperty() property %s, value %s", property, value);
566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Find a direct output profile compatible with the parameters passed, even if the input flags do
569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// not explicitly request a direct output
570e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile *AudioPolicyManager::getProfileForDirectOutput(
571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_devices_t device,
572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               uint32_t samplingRate,
573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_format_t format,
574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_channel_mask_t channelMask,
575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_output_flags_t flags)
576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++) {
578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            IOProfile *profile = mHwModules[i]->mOutputProfiles[j];
5833a4311c68348f728558e87b5db67d47605783890Eric Laurent            bool found = false;
584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (profile->isCompatibleProfile(device, samplingRate, format,
586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           channelMask,
587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
5883a4311c68348f728558e87b5db67d47605783890Eric Laurent                    found = true;
589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (profile->isCompatibleProfile(device, samplingRate, format,
592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           channelMask,
593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           AUDIO_OUTPUT_FLAG_DIRECT)) {
5943a4311c68348f728558e87b5db67d47605783890Eric Laurent                    found = true;
595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
5973a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (found && (mAvailableOutputDevices.types() & profile->mSupportedDevices.types())) {
5983a4311c68348f728558e87b5db67d47605783890Eric Laurent                return profile;
5993a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
605e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    uint32_t samplingRate,
607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    audio_format_t format,
608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    audio_channel_mask_t channelMask,
6093b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                    audio_output_flags_t flags,
610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    const audio_offload_info_t *offloadInfo)
611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t output = 0;
613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t latency = 0;
6143b73df74357b33869b39a1d69427673c780bd805Eric Laurent    routing_strategy strategy = getStrategy(stream);
615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          device, stream, samplingRate, format, channelMask, flags);
618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mCurOutput != 0) {
621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mTestOutputs[mCurOutput] == 0) {
625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("getOutput() opening test output");
626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mDevice = mTestDevice;
628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mSamplingRate = mTestSamplingRate;
629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mFormat = mTestFormat;
630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mChannelMask = mTestChannels;
631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mLatency = mTestLatencyMs;
6323b73df74357b33869b39a1d69427673c780bd805Eric Laurent            outputDesc->mFlags =
6333b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mRefCount[stream] = 0;
635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice,
636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            &outputDesc->mSamplingRate,
637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            &outputDesc->mFormat,
638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            &outputDesc->mChannelMask,
639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            &outputDesc->mLatency,
640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            outputDesc->mFlags,
641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo);
642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (mTestOutputs[mCurOutput]) {
643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioParameter outputCmd = AudioParameter();
644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputCmd.addInt(String8("set_id"),mCurOutput);
645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                addOutput(mTestOutputs[mCurOutput], outputDesc);
647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mTestOutputs[mCurOutput];
650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open a direct output if required by specified parameters
654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //force direct flag if offload flag is set: offloading implies a direct output stream
655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and all common behaviors are driven by checking only the direct flag
656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // this should normally be set appropriately in the policy configuration file
657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
6583b73df74357b33869b39a1d69427673c780bd805Eric Laurent        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not allow offloading if one non offloadable effect is enabled. This prevents from
662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // creating an offloaded track and tearing it down immediately after start when audioflinger
663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // detects there is an active non offloadable effect.
664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // FIXME: We should check the audio session here but we do not have it in this context.
665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // This may prevent offloading in rare situations where effects are left active by apps
666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the background.
667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    IOProfile *profile = NULL;
668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            !isNonOffloadableEffectEnabled()) {
670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        profile = getProfileForDirectOutput(device,
671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           samplingRate,
672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           format,
673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           channelMask,
674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           (audio_output_flags_t)flags);
675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (profile != NULL) {
678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *outputDesc = NULL;
679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (!desc->isDuplicated() && (profile == desc->mProfile)) {
683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc = desc;
684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // reuse direct output if currently open and configured with same parameters
685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if ((samplingRate == outputDesc->mSamplingRate) &&
686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (format == outputDesc->mFormat) &&
687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (channelMask == outputDesc->mChannelMask)) {
688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->mDirectOpenCount++;
689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    return mOutputs.keyAt(i);
691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // close direct output if currently open and configured with different parameters
695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc != NULL) {
696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            closeOutput(outputDesc->mId);
697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc = new AudioOutputDescriptor(profile);
699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mDevice = device;
700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mSamplingRate = samplingRate;
701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mFormat = format;
702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mChannelMask = channelMask;
703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mLatency = 0;
704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags);
705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mRefCount[stream] = 0;
706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mStopTime[stream] = 0;
707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mDirectOpenCount = 1;
708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        output = mpClientInterface->openOutput(profile->mModule->mHandle,
709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        &outputDesc->mDevice,
710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        &outputDesc->mSamplingRate,
711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        &outputDesc->mFormat,
712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        &outputDesc->mChannelMask,
713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        &outputDesc->mLatency,
714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        outputDesc->mFlags,
715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        offloadInfo);
716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // only accept an output with the requested parameters
718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (output == 0 ||
719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (format != AUDIO_FORMAT_DEFAULT && format != outputDesc->mFormat) ||
721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (channelMask != 0 && channelMask != outputDesc->mChannelMask)) {
722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    "format %d %d, channelMask %04x %04x", output, samplingRate,
724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->mChannelMask);
726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (output != 0) {
727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->closeOutput(output);
728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            delete outputDesc;
730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return 0;
731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_io_handle_t srcOutput = getOutputForEffect();
733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        addOutput(output, outputDesc);
734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_io_handle_t dstOutput = getOutputForEffect();
735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (dstOutput == output) {
736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mPreviousOutputs = mOutputs;
739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("getOutput() returns new direct output %d", output);
740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return output;
741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // ignoring channel mask due to downmix capability in mixer
744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open a non direct output
746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // for non direct outputs, only PCM is supported
748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_linear_pcm(format)) {
749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // get which output is suitable for the specified stream. The actual
750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // routing change will happen when startOutput() will be called
751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        output = selectOutput(outputs, flags);
754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getOutput() returns output %d", output);
759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return output;
761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
763e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
7643b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                       audio_output_flags_t flags)
765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // select one output among several that provide a path to a particular device or set of
767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // devices (the list was previously build by getOutputsForDevice()).
768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // The priority is as follows:
769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: the output with the highest number of requested policy flags
770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: the primary output
771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 3: the first output in the list
772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 0) {
774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 1) {
777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputs[0];
778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int maxCommonFlags = 0;
781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t outputFlags = 0;
782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t outputPrimary = 0;
783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs.size(); i++) {
785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]);
786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputDesc->isDuplicated()) {
7873b73df74357b33869b39a1d69427673c780bd805Eric Laurent            int commonFlags = popcount(outputDesc->mProfile->mFlags & flags);
788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (commonFlags > maxCommonFlags) {
789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputFlags = outputs[i];
790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                maxCommonFlags = commonFlags;
791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputPrimary = outputs[i];
795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputFlags != 0) {
800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputFlags;
801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputPrimary != 0) {
803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputPrimary;
804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs[0];
807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
809e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startOutput(audio_io_handle_t output,
8103b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                             audio_stream_type_t stream,
811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             int session)
812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session);
814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("startOutput() unknown output %d", output);
817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // increment usage count for this stream on the requested output:
823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // NOTE that the usage count is the same for duplicated output and hardware output which is
824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    outputDesc->changeRefCount(stream, 1);
826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->mRefCount[stream] == 1) {
828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/);
829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        routing_strategy strategy = getStrategy(stream);
830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            (strategy == STRATEGY_SONIFICATION_RESPECTFUL);
832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        uint32_t waitMs = 0;
833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool force = false;
834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (desc != outputDesc) {
837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // force a device change if any other output is managed by the same hw
838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // module and has a current device selection that differs from selected device.
839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // In this case, the audio HAL must receive the new device selection so that it can
840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // change the device currently selected by the other active output.
841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (outputDesc->sharesHwModuleWith(desc) &&
842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    desc->device() != newDevice) {
843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    force = true;
844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // wait for audio on other active outputs to be presented when starting
846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // a notification so that audio focus effect can propagate.
847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                uint32_t latency = desc->latency();
848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    waitMs = latency;
850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        uint32_t muteWaitMs = setOutputDevice(output, newDevice, force);
854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle special case for sonification while in call
856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (isInCall()) {
857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            handleIncallSonification(stream, true, false);
858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // apply volume rules for current stream and device if necessary
861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkAndSetVolume(stream,
862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          mStreams[stream].getVolumeIndex(newDevice),
863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          output,
864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          newDevice);
865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // update the outputs if starting an output with a stream that can affect notification
867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // routing
868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        handleNotificationRoutingForStream(stream);
869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (waitMs > muteWaitMs) {
870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            usleep((waitMs - muteWaitMs) * 2 * 1000);
871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
877e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
8783b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                            audio_stream_type_t stream,
879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int session)
880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopOutput() unknown output %d", output);
885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle special case for sonification while in call
891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isInCall()) {
892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        handleIncallSonification(stream, false, false);
893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->mRefCount[stream] > 0) {
896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // decrement usage count of this stream on the output
897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->changeRefCount(stream, -1);
898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // store time at which the stream was stopped - see isStreamActive()
899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mRefCount[stream] == 0) {
900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStopTime[stream] = systemTime();
901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/);
902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // delay the device switch by twice the latency because stopOutput() is executed when
903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // the track stop() command is received and at that time the audio track buffer can
904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // still contain data that needs to be drained. The latency only covers the audio HAL
905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // and kernel buffers. Also the latency does not always include additional delay in the
906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // audio path (audio DSP, CODEC ...)
907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setOutputDevice(output, newDevice, false, outputDesc->mLatency*2);
908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // force restoring the device selection on other active outputs if it differs from the
910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // one being selected for this output
911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < mOutputs.size(); i++) {
912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                audio_io_handle_t curOutput = mOutputs.keyAt(i);
913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *desc = mOutputs.valueAt(i);
914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (curOutput != output &&
915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        desc->isActive() &&
916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputDesc->sharesHwModuleWith(desc) &&
917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (newDevice != desc->device())) {
918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    setOutputDevice(curOutput,
919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    getNewDevice(curOutput, false /*fromCache*/),
920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    true,
921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    outputDesc->mLatency*2);
922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // update the outputs if stopping one with a stream that can affect notification routing
925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            handleNotificationRoutingForStream(stream);
926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopOutput() refcount is already 0 for output %d", output);
930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
934e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::releaseOutput(audio_io_handle_t output)
935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseOutput() %d", output);
937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("releaseOutput() releasing unknown output %d", output);
940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int testIndex = testOutputIndex(output);
945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (testIndex != 0) {
946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->isActive()) {
948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->closeOutput(output);
949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            delete mOutputs.valueAt(index);
950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mOutputs.removeItem(output);
951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mTestOutputs[testIndex] = 0;
952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *desc = mOutputs.valueAt(index);
9583b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (desc->mDirectOpenCount <= 0) {
960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("releaseOutput() invalid open count %d for output %d",
961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                              desc->mDirectOpenCount, output);
962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (--desc->mDirectOpenCount == 0) {
965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            closeOutput(output);
966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // If effects where present on the output, audioflinger moved them to the primary
967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // output by default: move them back to the appropriate output.
968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t dstOutput = getOutputForEffect();
969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (dstOutput != mPrimaryOutput) {
970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput);
971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
977e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,
978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    uint32_t samplingRate,
979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    audio_format_t format,
980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    audio_channel_mask_t channelMask,
9813b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                    audio_in_acoustics_t acoustics)
982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t input = 0;
984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = getDeviceForInputSource(inputSource);
985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x",
987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          inputSource, samplingRate, format, channelMask, acoustics);
988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("getInput() could not find device for inputSource %d", inputSource);
991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // adapt channel selection to input source
995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch(inputSource) {
996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_UPLINK:
997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_DOWNLINK:
1000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK;
1001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
1002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_CALL:
1003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK;
1004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
1005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
1006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
1007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    IOProfile *profile = getInputProfile(device,
1010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                         samplingRate,
1011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                         format,
1012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                         channelMask);
1013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (profile == NULL) {
1014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d, "
1015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                "channelMask %04x",
1016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                device, samplingRate, format, channelMask);
1017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
1018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (profile->mModule->mHandle == 0) {
1021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGE("getInput(): HW module %s not opened", profile->mModule->mName);
1022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
1023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile);
1026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mInputSource = inputSource;
1028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mDevice = device;
1029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mSamplingRate = samplingRate;
1030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mFormat = format;
1031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mChannelMask = channelMask;
1032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mRefCount = 0;
1033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    input = mpClientInterface->openInput(profile->mModule->mHandle,
1034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    &inputDesc->mDevice,
1035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    &inputDesc->mSamplingRate,
1036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    &inputDesc->mFormat,
1037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    &inputDesc->mChannelMask);
1038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // only accept input with the exact requested set of parameters
1040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (input == 0 ||
1041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        (samplingRate != inputDesc->mSamplingRate) ||
1042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        (format != inputDesc->mFormat) ||
1043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        (channelMask != inputDesc->mChannelMask)) {
1044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGI("getInput() failed opening input: samplingRate %d, format %d, channelMask %x",
1045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                samplingRate, format, channelMask);
1046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (input != 0) {
1047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->closeInput(input);
1048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete inputDesc;
1050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
1051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1052d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    addInput(input, inputDesc);
1053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return input;
1054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1056e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startInput(audio_io_handle_t input)
1057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("startInput() input %d", input);
1059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("startInput() unknown input %d", input);
1062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mTestInput == 0)
1068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
1070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // refuse 2 active AudioRecord clients at the same time except if the active input
1071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // uses AUDIO_SOURCE_HOTWORD in which case it is closed.
1072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_io_handle_t activeInput = getActiveInput();
1073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!isVirtualInputDevice(inputDesc->mDevice) && activeInput != 0) {
1074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput);
1075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
1076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("startInput() preempting already started low-priority input %d", activeInput);
1077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                stopInput(activeInput);
1078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                releaseInput(activeInput);
1079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
1080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("startInput() input %d failed: other input already started", input);
1081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
1082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
1087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) {
1088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        inputDesc->mDevice = newDevice;
1089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // automatically enable the remote submix output when input is started
1092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
10943b73df74357b33869b39a1d69427673c780bd805Eric Laurent                AUDIO_POLICY_DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS);
1095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioParameter param = AudioParameter();
1098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
1099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int aliasSource = (inputDesc->mInputSource == AUDIO_SOURCE_HOTWORD) ?
1101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                        AUDIO_SOURCE_VOICE_RECOGNITION : inputDesc->mInputSource;
1102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    param.addInt(String8(AudioParameter::keyInputSource), aliasSource);
1104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
1105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->setParameters(input, param.toString());
1107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    inputDesc->mRefCount = 1;
1109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1112e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopInput(audio_io_handle_t input)
1113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("stopInput() input %d", input);
1115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopInput() unknown input %d", input);
1118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (inputDesc->mRefCount == 0) {
1123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopInput() input %d already stopped", input);
1124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
1126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // automatically disable the remote submix output when input is stopped
1127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
11293b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS);
1130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioParameter param = AudioParameter();
1133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        param.addInt(String8(AudioParameter::keyRouting), 0);
1134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mpClientInterface->setParameters(input, param.toString());
1135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        inputDesc->mRefCount = 0;
1136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
1137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1140e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::releaseInput(audio_io_handle_t input)
1141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseInput() %d", input);
1143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("releaseInput() releasing unknown input %d", input);
1146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
1147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->closeInput(input);
1149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    delete mInputs.valueAt(index);
1150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mInputs.removeItem(input);
1151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseInput() exit");
1152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1154d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::closeAllInputs() {
1155d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    for(size_t input_index = 0; input_index < mInputs.size(); input_index++) {
1156d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        mpClientInterface->closeInput(mInputs.keyAt(input_index));
1157d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }
1158d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    mInputs.clear();
1159d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
1160d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
1161e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
1162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int indexMin,
1163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int indexMax)
1164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
1166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (indexMin < 0 || indexMin >= indexMax) {
1167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax);
1168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
1169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mStreams[stream].mIndexMin = indexMin;
1171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mStreams[stream].mIndexMax = indexMax;
1172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1174e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
1175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      int index,
1176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      audio_devices_t device)
1177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
1180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device)) {
1183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Force max volume if stream cannot be muted
1187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
1188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
1190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          stream, device, index);
1191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
1193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // clear all device specific values
1194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_OUT_DEFAULT) {
1195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[stream].mIndexCur.clear();
1196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mStreams[stream].mIndexCur.add(device, index);
1198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // compute and apply stream volume on all outputs according to connected device
1200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    status_t status = NO_ERROR;
1201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
1202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_devices_t curDevice =
1203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForVolume(mOutputs.valueAt(i)->device());
1204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) {
1205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
1206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (volStatus != NO_ERROR) {
1207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                status = volStatus;
1208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return status;
1212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1214e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
1215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      int *index,
1216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      audio_devices_t device)
1217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index == NULL) {
1219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device)) {
1222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to
1225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // the strategy the stream belongs to.
1226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_OUT_DEFAULT) {
1227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
1228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    device = getDeviceForVolume(device);
1230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    *index =  mStreams[stream].getVolumeIndex(device);
1232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
1233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1236e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutputForEffects(
1237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            const SortedVector<audio_io_handle_t>& outputs)
1238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // select one output among several suitable for global effects.
1240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // The priority is as follows:
1241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: An offloaded output. If the effect ends up not being offloadable,
1242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //    AudioFlinger will invalidate the track and the offloaded output
1243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //    will be closed causing the effect to be moved to a PCM output.
1244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: A deep buffer output
1245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 3: the first output in the list
1246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 0) {
1248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
1249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t outputOffloaded = 0;
1252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t outputDeepBuffer = 0;
1253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs.size(); i++) {
1255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]);
1256d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags);
1257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
1258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputOffloaded = outputs[i];
1259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
1261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDeepBuffer = outputs[i];
1262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d",
1266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          outputOffloaded, outputDeepBuffer);
1267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputOffloaded != 0) {
1268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputOffloaded;
1269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDeepBuffer != 0) {
1271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputDeepBuffer;
1272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs[0];
1275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1277e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc)
1278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // apply simple rule where global effects are attached to the same output as MUSIC streams
1280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
12813b73df74357b33869b39a1d69427673c780bd805Eric Laurent    routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
1282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
1283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs);
1284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t output = selectOutputForEffects(dstOutputs);
1286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getOutputForEffect() got output %d for fx %s flags %x",
1287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          output, (desc == NULL) ? "unspecified" : desc->name,  (desc == NULL) ? 0 : desc->flags);
1288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return output;
1290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1292e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
1293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                audio_io_handle_t io,
1294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                uint32_t strategy,
1295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                int session,
1296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                int id)
1297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(io);
1299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        index = mInputs.indexOfKey(io);
1301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (index < 0) {
1302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("registerEffect() unknown io %d", io);
1303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return INVALID_OPERATION;
1304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) {
1308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB",
1309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                desc->name, desc->memoryUsage);
1310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mTotalEffectsMemory += desc->memoryUsage;
1313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d",
1314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc->name, io, strategy, session, id);
1315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory);
1316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    EffectDescriptor *pDesc = new EffectDescriptor();
1318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t));
1319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    pDesc->mIo = io;
1320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    pDesc->mStrategy = (routing_strategy)strategy;
1321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    pDesc->mSession = session;
1322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    pDesc->mEnabled = false;
1323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mEffects.add(id, pDesc);
1325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1329e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::unregisterEffect(int id)
1330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mEffects.indexOfKey(id);
1332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("unregisterEffect() unknown effect ID %d", id);
1334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    EffectDescriptor *pDesc = mEffects.valueAt(index);
1338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    setEffectEnabled(pDesc, false);
1340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) {
1342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("unregisterEffect() memory %d too big for total %d",
1343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
1344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        pDesc->mDesc.memoryUsage = mTotalEffectsMemory;
1345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mTotalEffectsMemory -= pDesc->mDesc.memoryUsage;
1347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d",
1348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
1349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mEffects.removeItem(id);
1351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    delete pDesc;
1352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1356e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(int id, bool enabled)
1357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mEffects.indexOfKey(id);
1359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("unregisterEffect() unknown effect ID %d", id);
1361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return setEffectEnabled(mEffects.valueAt(index), enabled);
1365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1367e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setEffectEnabled(EffectDescriptor *pDesc, bool enabled)
1368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (enabled == pDesc->mEnabled) {
1370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setEffectEnabled(%s) effect already %s",
1371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             enabled?"true":"false", enabled?"enabled":"disabled");
1372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (enabled) {
1376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) {
1377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS",
1378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                 pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10);
1379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return INVALID_OPERATION;
1380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad;
1382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad);
1383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
1384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) {
1385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("setEffectEnabled(false) CPU load %d too high for total %d",
1386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad);
1387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad;
1388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad;
1390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad);
1391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    pDesc->mEnabled = enabled;
1393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1396e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isNonOffloadableEffectEnabled()
1397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mEffects.size(); i++) {
1399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const EffectDescriptor * const pDesc = mEffects.valueAt(i);
1400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (pDesc->mEnabled && (pDesc->mStrategy == STRATEGY_MEDIA) &&
1401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ((pDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) {
1402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d",
1403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                  pDesc->mDesc.name, pDesc->mSession);
1404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
1405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
1408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1410e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
1411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    nsecs_t sysTime = systemTime();
1413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
1414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
14153b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
1416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
1417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
1420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1422e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream,
14233b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                    uint32_t inPastMs) const
1424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    nsecs_t sysTime = systemTime();
1426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
1427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
1428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
14293b73df74357b33869b39a1d69427673c780bd805Eric Laurent                outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
1430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
1431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
1434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1436e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isSourceActive(audio_source_t source) const
1437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
1439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const AudioInputDescriptor * inputDescriptor = mInputs.valueAt(i);
1440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((inputDescriptor->mInputSource == (int)source ||
14413b73df74357b33869b39a1d69427673c780bd805Eric Laurent                (source == AUDIO_SOURCE_VOICE_RECOGNITION &&
1442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                 inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD))
1443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             && (inputDescriptor->mRefCount > 0)) {
1444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
1445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
1448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1451e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::dump(int fd)
1452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
1454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
1455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
1456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
1458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
1459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput);
1461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
1462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
1463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
14643b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for communications %d\n",
14653b73df74357b33869b39a1d69427673c780bd805Eric Laurent             mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]);
1466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
14673b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA]);
1468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
14693b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD]);
1470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
14713b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK]);
1472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
14733b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM]);
1474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
1475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
14763a4311c68348f728558e87b5db67d47605783890Eric Laurent    snprintf(buffer, SIZE, " Available output devices:\n");
14773a4311c68348f728558e87b5db67d47605783890Eric Laurent    result.append(buffer);
14783a4311c68348f728558e87b5db67d47605783890Eric Laurent    write(fd, result.string(), result.size());
14793a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceDescriptor::dumpHeader(fd, 2);
14803a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
14813a4311c68348f728558e87b5db67d47605783890Eric Laurent        mAvailableOutputDevices[i]->dump(fd, 2);
14823a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
14833a4311c68348f728558e87b5db67d47605783890Eric Laurent    snprintf(buffer, SIZE, "\n Available input devices:\n");
14843a4311c68348f728558e87b5db67d47605783890Eric Laurent    write(fd, buffer, strlen(buffer));
14853a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceDescriptor::dumpHeader(fd, 2);
14863a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
14873a4311c68348f728558e87b5db67d47605783890Eric Laurent        mAvailableInputDevices[i]->dump(fd, 2);
14883a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
1489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nHW Modules dump:\n");
1491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++) {
1493d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1);
1494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, buffer, strlen(buffer));
1495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mHwModules[i]->dump(fd);
1496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nOutputs dump:\n");
1499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
1501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
1502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, buffer, strlen(buffer));
1503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mOutputs.valueAt(i)->dump(fd);
1504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nInputs dump:\n");
1507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
1509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
1510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, buffer, strlen(buffer));
1511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mInputs.valueAt(i)->dump(fd);
1512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nStreams dump:\n");
1515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE,
1517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             " Stream  Can be muted  Index Min  Index Max  Index Cur [device : index]...\n");
1518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
15193b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
1520d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        snprintf(buffer, SIZE, " %02zu      ", i);
1521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, buffer, strlen(buffer));
1522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[i].dump(fd);
1523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n",
1526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory);
1527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "Registered effects:\n");
1530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, buffer, strlen(buffer));
1531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mEffects.size(); i++) {
1532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i));
1533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, buffer, strlen(buffer));
1534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mEffects.valueAt(i)->dump(fd);
1535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This function checks for the parameters which can be offloaded.
1542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This can be enhanced depending on the capability of the DSP and policy
1543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// of the system.
1544e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
1545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
1547d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent     " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
1548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.sample_rate, offloadInfo.channel_mask,
1549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.format,
1550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
1551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.has_video);
1552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check if offload has been disabled
1554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char propValue[PROPERTY_VALUE_MAX];
1555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (property_get("audio.offload.disable", propValue, "0")) {
1556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (atoi(propValue) != 0) {
1557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("offload disabled by audio.offload.disable=%s", propValue );
1558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
1559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check if stream type is music, then only allow offload as of now.
1563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
1564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
1565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
1566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
1567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //TODO: enable audio offloading with video when ready
1570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (offloadInfo.has_video)
1571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
1572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("isOffloadSupported: has_video == true, returning false");
1573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
1574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //If duration is less than minimum value defined in property, return false
1577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
1578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
1579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
1580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
1581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
1583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
1584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
1585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not allow offloading if one non offloadable effect is enabled. This prevents from
1588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // creating an offloaded track and tearing it down immediately after start when audioflinger
1589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // detects there is an active non offloadable effect.
1590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // FIXME: We should check the audio session here but we do not have it in this context.
1591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // This may prevent offloading in rare situations where effects are left active by apps
1592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the background.
1593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isNonOffloadableEffectEnabled()) {
1594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
1595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // See if there is a profile to support this.
1598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // AUDIO_DEVICE_NONE
1599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    IOProfile *profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
1600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.sample_rate,
1601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.format,
1602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.channel_mask,
1603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
1604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("isOffloadSupported() profile %sfound", profile != NULL ? "" : "NOT ");
1605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return (profile != NULL);
1606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
1609e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent// AudioPolicyManager
1610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
1611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
16123a4311c68348f728558e87b5db67d47605783890Eric Laurentuint32_t AudioPolicyManager::nextUniqueId()
16133a4311c68348f728558e87b5db67d47605783890Eric Laurent{
16143a4311c68348f728558e87b5db67d47605783890Eric Laurent    return android_atomic_inc(&mNextUniqueId);
16153a4311c68348f728558e87b5db67d47605783890Eric Laurent}
16163a4311c68348f728558e87b5db67d47605783890Eric Laurent
1617e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
1618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    :
1619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    Thread(false),
1621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPrimaryOutput((audio_io_handle_t)0),
16233b73df74357b33869b39a1d69427673c780bd805Eric Laurent    mPhoneState(AUDIO_MODE_NORMAL),
1624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
1625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),
16263a4311c68348f728558e87b5db67d47605783890Eric Laurent    mA2dpSuspended(false),
16273a4311c68348f728558e87b5db67d47605783890Eric Laurent    mSpeakerDrcEnabled(false), mNextUniqueId(0)
1628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface = clientInterface;
1630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
16313b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
16323b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
1633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
16353a4311c68348f728558e87b5db67d47605783890Eric Laurent    mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
1636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) {
1637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) {
1638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("could not load audio policy configuration file, setting defaults");
1639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            defaultAudioPolicyConfig();
1640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
16423a4311c68348f728558e87b5db67d47605783890Eric Laurent    // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
1643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // must be done after reading the policy
1645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    initializeVolumeCurves();
1646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open all output streams needed to access attached devices
16483a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
16493a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
1650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++) {
1651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
1652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
1653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("could not open HW module %s", mHwModules[i]->mName);
1654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
1655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // open all output streams needed to access attached devices
1657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // except for direct output streams that are only opened when they are actually
1658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // required by an app.
16593a4311c68348f728558e87b5db67d47605783890Eric Laurent        // This also validates mAvailableOutputDevices list
1660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
1661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
1662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j];
1663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
16643a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (outProfile->mSupportedDevices.isEmpty()) {
16653a4311c68348f728558e87b5db67d47605783890Eric Laurent                ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName);
16663a4311c68348f728558e87b5db67d47605783890Eric Laurent                continue;
16673a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
16683a4311c68348f728558e87b5db67d47605783890Eric Laurent
16693a4311c68348f728558e87b5db67d47605783890Eric Laurent            audio_devices_t profileTypes = outProfile->mSupportedDevices.types();
16703a4311c68348f728558e87b5db67d47605783890Eric Laurent            if ((profileTypes & outputDeviceTypes) &&
1671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {
1672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile);
16733a4311c68348f728558e87b5db67d47605783890Eric Laurent
16743a4311c68348f728558e87b5db67d47605783890Eric Laurent                outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice->mType & profileTypes);
1675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                audio_io_handle_t output = mpClientInterface->openOutput(
1676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                outProfile->mModule->mHandle,
1677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mDevice,
1678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mSamplingRate,
1679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mFormat,
1680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mChannelMask,
1681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mLatency,
1682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                outputDesc->mFlags);
1683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (output == 0) {
16843a4311c68348f728558e87b5db67d47605783890Eric Laurent                    ALOGW("Cannot open output stream for device %08x on hw module %s",
16853a4311c68348f728558e87b5db67d47605783890Eric Laurent                          outputDesc->mDevice,
16863a4311c68348f728558e87b5db67d47605783890Eric Laurent                          mHwModules[i]->mName);
1687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    delete outputDesc;
1688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else {
16895b61dddd0dba28922068da2487894761486aec6cEric Laurent                    for (size_t k = 0; k  < outProfile->mSupportedDevices.size(); k++) {
16905b61dddd0dba28922068da2487894761486aec6cEric Laurent                        audio_devices_t type = outProfile->mSupportedDevices[k]->mType;
16913a4311c68348f728558e87b5db67d47605783890Eric Laurent                        ssize_t index =
16925b61dddd0dba28922068da2487894761486aec6cEric Laurent                                mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]);
16933a4311c68348f728558e87b5db67d47605783890Eric Laurent                        // give a valid ID to an attached device once confirmed it is reachable
16943a4311c68348f728558e87b5db67d47605783890Eric Laurent                        if ((index >= 0) && (mAvailableOutputDevices[index]->mId == 0)) {
16953a4311c68348f728558e87b5db67d47605783890Eric Laurent                            mAvailableOutputDevices[index]->mId = nextUniqueId();
16963a4311c68348f728558e87b5db67d47605783890Eric Laurent                        }
16973a4311c68348f728558e87b5db67d47605783890Eric Laurent                    }
1698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (mPrimaryOutput == 0 &&
1699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
1700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mPrimaryOutput = output;
1701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
1702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    addOutput(output, outputDesc);
1703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    setOutputDevice(output,
17043a4311c68348f728558e87b5db67d47605783890Eric Laurent                                    outputDesc->mDevice,
1705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                    true);
1706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
17093a4311c68348f728558e87b5db67d47605783890Eric Laurent        // open input streams needed to access attached devices to validate
17103a4311c68348f728558e87b5db67d47605783890Eric Laurent        // mAvailableInputDevices list
17113a4311c68348f728558e87b5db67d47605783890Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
17123a4311c68348f728558e87b5db67d47605783890Eric Laurent        {
17133a4311c68348f728558e87b5db67d47605783890Eric Laurent            const IOProfile *inProfile = mHwModules[i]->mInputProfiles[j];
17143a4311c68348f728558e87b5db67d47605783890Eric Laurent
17153a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (inProfile->mSupportedDevices.isEmpty()) {
17163a4311c68348f728558e87b5db67d47605783890Eric Laurent                ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName);
17173a4311c68348f728558e87b5db67d47605783890Eric Laurent                continue;
17183a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
1719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
17203a4311c68348f728558e87b5db67d47605783890Eric Laurent            audio_devices_t profileTypes = inProfile->mSupportedDevices.types();
17213a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (profileTypes & inputDeviceTypes) {
17223a4311c68348f728558e87b5db67d47605783890Eric Laurent                AudioInputDescriptor *inputDesc = new AudioInputDescriptor(inProfile);
17233a4311c68348f728558e87b5db67d47605783890Eric Laurent
17243a4311c68348f728558e87b5db67d47605783890Eric Laurent                inputDesc->mInputSource = AUDIO_SOURCE_MIC;
17253a4311c68348f728558e87b5db67d47605783890Eric Laurent                inputDesc->mDevice = inProfile->mSupportedDevices[0]->mType;
17263a4311c68348f728558e87b5db67d47605783890Eric Laurent                audio_io_handle_t input = mpClientInterface->openInput(
17273a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                    inProfile->mModule->mHandle,
17283a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                    &inputDesc->mDevice,
17293a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                    &inputDesc->mSamplingRate,
17303a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                    &inputDesc->mFormat,
17313a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                    &inputDesc->mChannelMask);
17323a4311c68348f728558e87b5db67d47605783890Eric Laurent
17333a4311c68348f728558e87b5db67d47605783890Eric Laurent                if (input != 0) {
17345b61dddd0dba28922068da2487894761486aec6cEric Laurent                    for (size_t k = 0; k  < inProfile->mSupportedDevices.size(); k++) {
17355b61dddd0dba28922068da2487894761486aec6cEric Laurent                        audio_devices_t type = inProfile->mSupportedDevices[k]->mType;
17363a4311c68348f728558e87b5db67d47605783890Eric Laurent                        ssize_t index =
17375b61dddd0dba28922068da2487894761486aec6cEric Laurent                                mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]);
17383a4311c68348f728558e87b5db67d47605783890Eric Laurent                        // give a valid ID to an attached device once confirmed it is reachable
17393a4311c68348f728558e87b5db67d47605783890Eric Laurent                        if ((index >= 0) && (mAvailableInputDevices[index]->mId == 0)) {
17403a4311c68348f728558e87b5db67d47605783890Eric Laurent                            mAvailableInputDevices[index]->mId = nextUniqueId();
17413a4311c68348f728558e87b5db67d47605783890Eric Laurent                        }
17423a4311c68348f728558e87b5db67d47605783890Eric Laurent                    }
17433a4311c68348f728558e87b5db67d47605783890Eric Laurent                    mpClientInterface->closeInput(input);
17443a4311c68348f728558e87b5db67d47605783890Eric Laurent                } else {
17453a4311c68348f728558e87b5db67d47605783890Eric Laurent                    ALOGW("Cannot open input stream for device %08x on hw module %s",
17463a4311c68348f728558e87b5db67d47605783890Eric Laurent                          inputDesc->mDevice,
17473a4311c68348f728558e87b5db67d47605783890Eric Laurent                          mHwModules[i]->mName);
17483a4311c68348f728558e87b5db67d47605783890Eric Laurent                }
17493a4311c68348f728558e87b5db67d47605783890Eric Laurent                delete inputDesc;
17503a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
17513a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
17523a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
17533a4311c68348f728558e87b5db67d47605783890Eric Laurent    // make sure all attached devices have been allocated a unique ID
17543a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i  < mAvailableOutputDevices.size();) {
17553a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (mAvailableOutputDevices[i]->mId == 0) {
17563a4311c68348f728558e87b5db67d47605783890Eric Laurent            ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mType);
17573a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
17583a4311c68348f728558e87b5db67d47605783890Eric Laurent            continue;
17593a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
17603a4311c68348f728558e87b5db67d47605783890Eric Laurent        i++;
17613a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
17623a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i  < mAvailableInputDevices.size();) {
17633a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (mAvailableInputDevices[i]->mId == 0) {
17643a4311c68348f728558e87b5db67d47605783890Eric Laurent            ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mType);
17653a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.remove(mAvailableInputDevices[i]);
17663a4311c68348f728558e87b5db67d47605783890Eric Laurent            continue;
17673a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
17683a4311c68348f728558e87b5db67d47605783890Eric Laurent        i++;
17693a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
17703a4311c68348f728558e87b5db67d47605783890Eric Laurent    // make sure default device is reachable
17713a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
17723a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mType);
17733a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
1774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
1776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
1778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mPrimaryOutput != 0) {
1781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioParameter outputCmd = AudioParameter();
1782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputCmd.addInt(String8("set_id"), 0);
1783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
1784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestDevice = AUDIO_DEVICE_OUT_SPEAKER;
1786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestSamplingRate = 44100;
17873b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mTestFormat = AUDIO_FORMAT_PCM_16_BIT;
17883b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mTestChannels =  AUDIO_CHANNEL_OUT_STEREO;
1789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestLatencyMs = 0;
1790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mCurOutput = 0;
1791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mDirectOutput = false;
1792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
1793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mTestOutputs[i] = 0;
1794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const size_t SIZE = 256;
1797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        char buffer[SIZE];
1798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "AudioPolicyManagerTest");
1799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        run(buffer, ANDROID_PRIORITY_AUDIO);
1800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1804e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::~AudioPolicyManager()
1805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    exit();
1808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mOutputs.size(); i++) {
1810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mpClientInterface->closeOutput(mOutputs.keyAt(i));
1811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete mOutputs.valueAt(i);
1812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
1813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mInputs.size(); i++) {
1814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mpClientInterface->closeInput(mInputs.keyAt(i));
1815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete mInputs.valueAt(i);
1816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
1817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mHwModules.size(); i++) {
1818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete mHwModules[i];
1819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
18203a4311c68348f728558e87b5db67d47605783890Eric Laurent   mAvailableOutputDevices.clear();
18213a4311c68348f728558e87b5db67d47605783890Eric Laurent   mAvailableInputDevices.clear();
1822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1824e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::initCheck()
1825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR;
1827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1830e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::threadLoop()
1831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("entering threadLoop()");
1833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (!exitPending())
1834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
1835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        String8 command;
1836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        int valueInt;
1837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        String8 value;
1838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        Mutex::Autolock _l(mLock);
1840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mWaitWorkCV.waitRelative(mLock, milliseconds(50));
1841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
1843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioParameter param = AudioParameter(command);
1844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
1846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            valueInt != 0) {
1847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("Test command %s received", command.string());
1848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            String8 target;
1849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("target"), target) != NO_ERROR) {
1850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                target = "Manager";
1851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
1853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_output"));
1854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mCurOutput = valueInt;
1855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
1857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_direct"));
1858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "false") {
1859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mDirectOutput = false;
1860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "true") {
1861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mDirectOutput = true;
1862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
1865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_input"));
1866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mTestInput = valueInt;
1867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
1870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_format"));
18713b73df74357b33869b39a1d69427673c780bd805Eric Laurent                int format = AUDIO_FORMAT_INVALID;
1872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "PCM 16 bits") {
18733b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_PCM_16_BIT;
1874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "PCM 8 bits") {
18753b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_PCM_8_BIT;
1876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "Compressed MP3") {
18773b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_MP3;
1878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
18793b73df74357b33869b39a1d69427673c780bd805Eric Laurent                if (format != AUDIO_FORMAT_INVALID) {
1880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
1881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestFormat = format;
1882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
1883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
1884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputParam.addInt(String8("format"), format);
1885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
1886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
1887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
1890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_channels"));
1891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                int channels = 0;
1892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "Channels Stereo") {
18943b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    channels =  AUDIO_CHANNEL_OUT_STEREO;
1895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "Channels Mono") {
18963b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    channels =  AUDIO_CHANNEL_OUT_MONO;
1897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (channels != 0) {
1899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
1900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestChannels = channels;
1901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
1902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
1903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputParam.addInt(String8("channels"), channels);
1904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
1905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
1906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
1909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_sampleRate"));
1910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (valueInt >= 0 && valueInt <= 96000) {
1911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    int samplingRate = valueInt;
1912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
1913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestSamplingRate = samplingRate;
1914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
1915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
1916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputParam.addInt(String8("sampling_rate"), samplingRate);
1917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
1918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
1919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
1923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_reopen"));
1924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput);
1926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->closeOutput(mPrimaryOutput);
1927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle;
1929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                delete mOutputs.valueFor(mPrimaryOutput);
1931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mOutputs.removeItem(mPrimaryOutput);
1932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
1934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
1935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mPrimaryOutput = mpClientInterface->openOutput(moduleHandle,
1936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mDevice,
1937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mSamplingRate,
1938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mFormat,
1939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mChannelMask,
1940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                &outputDesc->mLatency,
1941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                outputDesc->mFlags);
1942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (mPrimaryOutput == 0) {
1943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
1944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
1945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else {
1946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    AudioParameter outputCmd = AudioParameter();
1947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputCmd.addInt(String8("set_id"), 0);
1948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
1949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    addOutput(mPrimaryOutput, outputDesc);
1950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->setParameters(0, String8("test_cmd_policy="));
1955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
1958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1960e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::exit()
1961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
1963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AutoMutex _l(mLock);
1964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        requestExit();
1965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mWaitWorkCV.signal();
1966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    requestExitAndWait();
1968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1970e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::testOutputIndex(audio_io_handle_t output)
1971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
1973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (output == mTestOutputs[i]) return i;
1974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
1976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---
1980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1981e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc)
1982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    outputDesc->mId = id;
1984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mOutputs.add(id, outputDesc);
1985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1987d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::addInput(audio_io_handle_t id, AudioInputDescriptor *inputDesc)
1988d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
1989d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    inputDesc->mId = id;
1990d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    mInputs.add(id, inputDesc);
1991d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
1992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
19933a4311c68348f728558e87b5db67d47605783890Eric LaurentString8 AudioPolicyManager::addressToParameter(audio_devices_t device, const String8 address)
19943a4311c68348f728558e87b5db67d47605783890Eric Laurent{
19953a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
19963a4311c68348f728558e87b5db67d47605783890Eric Laurent        return String8("a2dp_sink_address=")+address;
19973a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
19983a4311c68348f728558e87b5db67d47605783890Eric Laurent    return address;
19993a4311c68348f728558e87b5db67d47605783890Eric Laurent}
20003a4311c68348f728558e87b5db67d47605783890Eric Laurent
2001e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device,
20023b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                       audio_policy_dev_state_t state,
2003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       SortedVector<audio_io_handle_t>& outputs,
20043a4311c68348f728558e87b5db67d47605783890Eric Laurent                                                       const String8 address)
2005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *desc;
2007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
20083b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
2009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // first list already open outputs that can be routed to this device
2010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
2011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = mOutputs.valueAt(i);
20123a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) {
2013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
2014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputs.add(mOutputs.keyAt(i));
2015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // then look for output profiles that can be routed to this device
2018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        SortedVector<IOProfile *> profiles;
2019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mHwModules.size(); i++)
2020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
2021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (mHwModules[i]->mHandle == 0) {
2022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
2023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
2025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            {
20263a4311c68348f728558e87b5db67d47605783890Eric Laurent                if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) {
2027d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i);
2028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    profiles.add(mHwModules[i]->mOutputProfiles[j]);
2029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (profiles.isEmpty() && outputs.isEmpty()) {
2034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
2035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
2036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // open outputs for matching profiles if needed. Direct outputs are also opened to
2039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
2040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
2041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            IOProfile *profile = profiles[profile_index];
2042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // nothing to do if one output is already opened for this profile
2044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            size_t j;
2045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (j = 0; j < mOutputs.size(); j++) {
2046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                desc = mOutputs.valueAt(j);
2047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (!desc->isDuplicated() && desc->mProfile == profile) {
2048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    break;
2049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (j != mOutputs.size()) {
2052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
2053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
20553a4311c68348f728558e87b5db67d47605783890Eric Laurent            ALOGV("opening output for device %08x with params %s", device, address.string());
2056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = new AudioOutputDescriptor(profile);
2057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc->mDevice = device;
2058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
2059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            offloadInfo.sample_rate = desc->mSamplingRate;
2060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            offloadInfo.format = desc->mFormat;
2061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            offloadInfo.channel_mask = desc->mChannelMask;
2062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle,
2064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &desc->mDevice,
2065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &desc->mSamplingRate,
2066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &desc->mFormat,
2067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &desc->mChannelMask,
2068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &desc->mLatency,
2069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       desc->mFlags,
2070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       &offloadInfo);
2071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (output != 0) {
2072d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                // Here is where the out_set_parameters() for card & device gets called
20733a4311c68348f728558e87b5db67d47605783890Eric Laurent                if (!address.isEmpty()) {
20743a4311c68348f728558e87b5db67d47605783890Eric Laurent                    mpClientInterface->setParameters(output, addressToParameter(device, address));
2075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2077d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                // Here is where we step through and resolve any "dynamic" fields
2078d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                String8 reply;
2079d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                char *value;
2080d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mSamplingRates[0] == 0) {
2081d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(output,
2082d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
2083d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice() direct output sup sampling rates %s",
2084d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                              reply.string());
2085d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2086d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
2087d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        loadSamplingRates(value + 1, profile);
2088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2089d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2090d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
2091d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(output,
2092d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                   String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
2093d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice() direct output sup formats %s",
2094d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                              reply.string());
2095d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2096d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
2097d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        loadFormats(value + 1, profile);
2098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2099d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2100d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mChannelMasks[0] == 0) {
2101d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(output,
2102d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                  String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
2103d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice() direct output sup channel masks %s",
2104d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                              reply.string());
2105d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2106d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
2107d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        loadOutChannels(value + 1, profile);
2108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2109d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2110d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (((profile->mSamplingRates[0] == 0) &&
2111d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                         (profile->mSamplingRates.size() < 2)) ||
2112d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                     ((profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) &&
2113d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                         (profile->mFormats.size() < 2)) ||
2114d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                     ((profile->mChannelMasks[0] == 0) &&
2115d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                         (profile->mChannelMasks.size() < 2))) {
2116d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGW("checkOutputsForDevice() direct output missing param");
2117d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeOutput(output);
2118d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    output = 0;
2119d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                } else if (profile->mSamplingRates[0] == 0) {
2120d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeOutput(output);
2121d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    desc->mSamplingRate = profile->mSamplingRates[1];
2122d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    offloadInfo.sample_rate = desc->mSamplingRate;
2123d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    output = mpClientInterface->openOutput(
2124d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    profile->mModule->mHandle,
2125d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &desc->mDevice,
2126d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &desc->mSamplingRate,
2127d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &desc->mFormat,
2128d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &desc->mChannelMask,
2129d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &desc->mLatency,
2130d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    desc->mFlags,
2131d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                    &offloadInfo);
2132d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2133d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2134d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (output != 0) {
2135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    addOutput(output, desc);
2136d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) {
2137d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        audio_io_handle_t duplicatedOutput = 0;
2138d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2139d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        // set initial stream volume for device
2140d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        applyStreamVolumes(output, device, 0, true);
2141d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2142d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        //TODO: configure audio effect output stage here
2143d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2144d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        // open a duplicating output thread for the new output and the primary output
2145d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        duplicatedOutput = mpClientInterface->openDuplicateOutput(output,
2146d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                                                  mPrimaryOutput);
2147d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        if (duplicatedOutput != 0) {
2148d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            // add duplicated output descriptor
2149d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL);
2150d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput);
2151d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mOutput2 = mOutputs.valueFor(output);
2152d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mSamplingRate = desc->mSamplingRate;
2153d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mFormat = desc->mFormat;
2154d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mChannelMask = desc->mChannelMask;
2155d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mLatency = desc->mLatency;
2156d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            addOutput(duplicatedOutput, dupOutputDesc);
2157d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            applyStreamVolumes(duplicatedOutput, device, 0, true);
2158d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        } else {
2159d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
2160d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                    mPrimaryOutput, output);
2161d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            mpClientInterface->closeOutput(output);
2162d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            mOutputs.removeItem(output);
2163d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            output = 0;
2164d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        }
2165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (output == 0) {
2169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("checkOutputsForDevice() could not open output for device %x", device);
2170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                delete desc;
2171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                profiles.removeAt(profile_index);
2172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                profile_index--;
2173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
2174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputs.add(output);
2175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("checkOutputsForDevice(): adding output %d", output);
2176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (profiles.isEmpty()) {
2180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
2181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
2182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2183d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } else { // Disconnect
2184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // check if one opened output is not needed any more after disconnecting one device
2185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
2186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = mOutputs.valueAt(i);
2187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (!desc->isDuplicated() &&
21883a4311c68348f728558e87b5db67d47605783890Eric Laurent                    !(desc->mProfile->mSupportedDevices.types() &
21893a4311c68348f728558e87b5db67d47605783890Eric Laurent                            mAvailableOutputDevices.types())) {
2190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i));
2191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputs.add(mOutputs.keyAt(i));
2192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2194d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Clear any profiles associated with the disconnected device.
2195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mHwModules.size(); i++)
2196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
2197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (mHwModules[i]->mHandle == 0) {
2198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
2199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
2201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            {
2202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                IOProfile *profile = mHwModules[i]->mOutputProfiles[j];
2203d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mSupportedDevices.types() & device) {
2204d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice(): "
2205d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            "clearing direct output profile %zu on module %zu", j, i);
2206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (profile->mSamplingRates[0] == 0) {
2207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mSamplingRates.clear();
2208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mSamplingRates.add(0);
2209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
2211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mFormats.clear();
2212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
2213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (profile->mChannelMasks[0] == 0) {
2215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mChannelMasks.clear();
2216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        profile->mChannelMasks.add(0);
2217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
2223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2225d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentstatus_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device,
2226d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                      audio_policy_dev_state_t state,
2227d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                      SortedVector<audio_io_handle_t>& inputs,
2228d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                      const String8 address)
2229d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
2230d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    AudioInputDescriptor *desc;
2231d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
2232d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // first list already open inputs that can be routed to this device
2233d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
2234d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = mInputs.valueAt(input_index);
2235d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (desc->mProfile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) {
2236d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
2237d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent               inputs.add(mInputs.keyAt(input_index));
2238d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2239d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2240d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2241d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // then look for input profiles that can be routed to this device
2242d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        SortedVector<IOProfile *> profiles;
2243d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++)
2244d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        {
2245d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (mHwModules[module_idx]->mHandle == 0) {
2246d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
2247d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2248d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (size_t profile_index = 0;
2249d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index < mHwModules[module_idx]->mInputProfiles.size();
2250d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index++)
2251d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            {
2252d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (mHwModules[module_idx]->mInputProfiles[profile_index]->mSupportedDevices.types()
2253d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        & (device & ~AUDIO_DEVICE_BIT_IN)) {
2254d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkInputsForDevice(): adding profile %d from module %d",
2255d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                          profile_index, module_idx);
2256d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    profiles.add(mHwModules[module_idx]->mInputProfiles[profile_index]);
2257d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2258d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2259d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2260d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2261d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        if (profiles.isEmpty() && inputs.isEmpty()) {
2262d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
2263d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            return BAD_VALUE;
2264d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2265d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2266d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // open inputs for matching profiles if needed. Direct inputs are also opened to
2267d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
2268d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
2269d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2270d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            IOProfile *profile = profiles[profile_index];
2271d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            // nothing to do if one input is already opened for this profile
2272d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            size_t input_index;
2273d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (input_index = 0; input_index < mInputs.size(); input_index++) {
2274d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                desc = mInputs.valueAt(input_index);
2275d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (desc->mProfile == profile) {
2276d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    break;
2277d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2278d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2279d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (input_index != mInputs.size()) {
2280d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
2281d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2282d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2283d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGV("opening input for device 0x%X with params %s", device, address.string());
2284d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = new AudioInputDescriptor(profile);
2285d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc->mDevice = device;
2286d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2287d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle,
2288d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            &desc->mDevice,
2289d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            &desc->mSamplingRate,
2290d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            &desc->mFormat,
2291d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            &desc->mChannelMask);
2292d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2293d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (input != 0) {
2294d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (!address.isEmpty()) {
2295d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->setParameters(input, addressToParameter(device, address));
2296d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2297d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2298d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                // Here is where we step through and resolve any "dynamic" fields
2299d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                String8 reply;
2300d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                char *value;
2301d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mSamplingRates[0] == 0) {
2302d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(input,
2303d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                            String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
2304d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkInputsForDevice() direct input sup sampling rates %s",
2305d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                              reply.string());
2306d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2307d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
2308d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        loadSamplingRates(value + 1, profile);
2309d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2310d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2311d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
2312d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(input,
2313d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                   String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
2314d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string());
2315d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2316d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
2317d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        loadFormats(value + 1, profile);
2318d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2319d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2320d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mChannelMasks[0] == 0) {
2321d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    reply = mpClientInterface->getParameters(input,
2322d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                                                  String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
2323d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkInputsForDevice() direct input sup channel masks %s",
2324d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                              reply.string());
2325d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    value = strpbrk((char *)reply.string(), "=");
2326d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (value != NULL) {
2327d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        loadInChannels(value + 1, profile);
2328d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2329d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2330d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) ||
2331d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                     ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) ||
2332d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                     ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) {
2333d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGW("checkInputsForDevice() direct input missing param");
2334d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeInput(input);
2335d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    input = 0;
2336d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2337d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2338d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (input != 0) {
2339d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    addInput(input, desc);
2340d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2341d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            } // endif input != 0
2342d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2343d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (input == 0) {
2344d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
2345d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                delete desc;
2346d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                profiles.removeAt(profile_index);
2347d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                profile_index--;
2348d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            } else {
2349d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                inputs.add(input);
2350d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): adding input %d", input);
2351d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2352d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } // end scan profiles
2353d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2354d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        if (profiles.isEmpty()) {
2355d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
2356d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            return BAD_VALUE;
2357d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2358d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } else {
2359d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Disconnect
2360d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // check if one opened input is not needed any more after disconnecting one device
2361d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
2362d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = mInputs.valueAt(input_index);
2363d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types())) {
2364d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): disconnecting adding input %d",
2365d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                      mInputs.keyAt(input_index));
2366d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                inputs.add(mInputs.keyAt(input_index));
2367d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2368d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2369d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Clear any profiles associated with the disconnected device.
2370d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) {
2371d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (mHwModules[module_index]->mHandle == 0) {
2372d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
2373d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2374d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (size_t profile_index = 0;
2375d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index < mHwModules[module_index]->mInputProfiles.size();
2376d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index++) {
2377d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                IOProfile *profile = mHwModules[module_index]->mInputProfiles[profile_index];
2378d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (profile->mSupportedDevices.types() & device) {
2379d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkInputsForDevice(): clearing direct input profile %d on module %d",
2380d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                          profile_index, module_index);
2381d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (profile->mSamplingRates[0] == 0) {
2382d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mSamplingRates.clear();
2383d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mSamplingRates.add(0);
2384d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2385d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
2386d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mFormats.clear();
2387d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
2388d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2389d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    if (profile->mChannelMasks[0] == 0) {
2390d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mChannelMasks.clear();
2391d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        profile->mChannelMasks.add(0);
2392d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    }
2393d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
2394d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
2395d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
2396d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } // end disconnect
2397d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2398d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    return NO_ERROR;
2399d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
2400d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2401d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2402e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::closeOutput(audio_io_handle_t output)
2403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("closeOutput(%d)", output);
2405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
2407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc == NULL) {
2408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("closeOutput() unknown output %d", output);
2409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
2410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // look for duplicated outputs connected to the output being removed.
2413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
2414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i);
2415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (dupOutputDesc->isDuplicated() &&
2416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                (dupOutputDesc->mOutput1 == outputDesc ||
2417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                dupOutputDesc->mOutput2 == outputDesc)) {
2418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *outputDesc2;
2419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (dupOutputDesc->mOutput1 == outputDesc) {
2420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc2 = dupOutputDesc->mOutput2;
2421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
2422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc2 = dupOutputDesc->mOutput1;
2423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // As all active tracks on duplicated output will be deleted,
2425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // and as they were also referenced on the other output, the reference
2426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // count for their stream type must be adjusted accordingly on
2427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // the other output.
24283b73df74357b33869b39a1d69427673c780bd805Eric Laurent            for (int j = 0; j < AUDIO_STREAM_CNT; j++) {
2429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                int refCount = dupOutputDesc->mRefCount[j];
24303b73df74357b33869b39a1d69427673c780bd805Eric Laurent                outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount);
2431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i);
2433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
2434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->closeOutput(duplicatedOutput);
2436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            delete mOutputs.valueFor(duplicatedOutput);
2437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mOutputs.removeItem(duplicatedOutput);
2438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioParameter param;
2442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    param.add(String8("closing"), String8("true"));
2443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->setParameters(output, param.toString());
2444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->closeOutput(output);
2446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    delete outputDesc;
2447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mOutputs.removeItem(output);
2448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPreviousOutputs = mOutputs;
2449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2451e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device,
2452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs)
2453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> outputs;
2455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("getOutputsForDevice() device %04x", device);
2457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < openOutputs.size(); i++) {
2458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("output %d isDuplicated=%d device=%04x",
2459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices());
2460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
2461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
2462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputs.add(openOutputs.keyAt(i));
2463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs;
2466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2468e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
2469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                   SortedVector<audio_io_handle_t>& outputs2)
2470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs1.size() != outputs2.size()) {
2472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs1.size(); i++) {
2475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputs1[i] != outputs2[i]) {
2476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
2477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return true;
2480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2482e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
2483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
2485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
2486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
2487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
2488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!vectorsEqual(srcOutputs,dstOutputs)) {
2490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
2491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              strategy, srcOutputs[0], dstOutputs[0]);
2492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // mute strategy while moving tracks from one output to another
2493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < srcOutputs.size(); i++) {
2494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]);
2495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (desc->isStrategyActive(strategy)) {
2496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                setStrategyMute(strategy, true, srcOutputs[i]);
2497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice);
2498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Move effects associated to this strategy from previous output to new output
2502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strategy == STRATEGY_MEDIA) {
2503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs);
2504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            SortedVector<audio_io_handle_t> moved;
2505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < mEffects.size(); i++) {
2506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                EffectDescriptor *desc = mEffects.valueAt(i);
2507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX &&
2508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        desc->mIo != fxOutput) {
2509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (moved.indexOf(desc->mIo) < 0) {
2510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        ALOGV("checkOutputForStrategy() moving effect %d to output %d",
2511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              mEffects.keyAt(i), fxOutput);
2512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, desc->mIo,
2513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       fxOutput);
2514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        moved.add(desc->mIo);
2515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    desc->mIo = fxOutput;
2517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Move tracks associated to this strategy from previous output to new output
25213b73df74357b33869b39a1d69427673c780bd805Eric Laurent        for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
25223b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (getStrategy((audio_stream_type_t)i) == strategy) {
25233b73df74357b33869b39a1d69427673c780bd805Eric Laurent                mpClientInterface->invalidateStream((audio_stream_type_t)i);
2524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2529e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForAllStrategies()
2530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
2532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_PHONE);
2533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_SONIFICATION);
2534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
2535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_MEDIA);
2536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_DTMF);
2537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2539e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getA2dpOutput()
2540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
2542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
2543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
2544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return mOutputs.keyAt(i);
2545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
2549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2551e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkA2dpSuspend()
2552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t a2dpOutput = getA2dpOutput();
2554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (a2dpOutput == 0) {
25553a4311c68348f728558e87b5db67d47605783890Eric Laurent        mA2dpSuspended = false;
2556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
2557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
25593a4311c68348f728558e87b5db67d47605783890Eric Laurent    bool isScoConnected =
25603a4311c68348f728558e87b5db67d47605783890Eric Laurent            (mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) != 0;
2561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // suspend A2DP output if:
2562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (NOT already suspended) &&
2563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      ((SCO device is connected &&
2564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //       (forced usage for communication || for record is SCO))) ||
2565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (phone state is ringing || in call)
2566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //
2567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // restore A2DP output if:
2568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (Already suspended) &&
2569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      ((SCO device is NOT connected ||
2570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //       (forced usage NOT for communication && NOT for record is SCO))) &&
2571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (phone state is NOT ringing && NOT in call)
2572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //
2573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mA2dpSuspended) {
25743a4311c68348f728558e87b5db67d47605783890Eric Laurent        if ((!isScoConnected ||
25753b73df74357b33869b39a1d69427673c780bd805Eric Laurent             ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO) &&
25763b73df74357b33869b39a1d69427673c780bd805Eric Laurent              (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] != AUDIO_POLICY_FORCE_BT_SCO))) &&
25773b73df74357b33869b39a1d69427673c780bd805Eric Laurent             ((mPhoneState != AUDIO_MODE_IN_CALL) &&
25783b73df74357b33869b39a1d69427673c780bd805Eric Laurent              (mPhoneState != AUDIO_MODE_RINGTONE))) {
2579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->restoreOutput(a2dpOutput);
2581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mA2dpSuspended = false;
2582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
25843a4311c68348f728558e87b5db67d47605783890Eric Laurent        if ((isScoConnected &&
25853b73df74357b33869b39a1d69427673c780bd805Eric Laurent             ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) ||
25863b73df74357b33869b39a1d69427673c780bd805Eric Laurent              (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO))) ||
25873b73df74357b33869b39a1d69427673c780bd805Eric Laurent             ((mPhoneState == AUDIO_MODE_IN_CALL) ||
25883b73df74357b33869b39a1d69427673c780bd805Eric Laurent              (mPhoneState == AUDIO_MODE_RINGTONE))) {
2589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->suspendOutput(a2dpOutput);
2591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mA2dpSuspended = true;
2592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2596e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getNewDevice(audio_io_handle_t output, bool fromCache)
2597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = AUDIO_DEVICE_NONE;
2599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
2601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check the following by order of priority to request a routing change if necessary:
2602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: the strategy enforced audible is active on the output:
2603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy enforced audible
2604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: we are in call or the strategy phone is active on the output:
2605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy phone
2606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 3: the strategy sonification is active on the output:
2607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy sonification
2608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 4: the strategy "respectful" sonification is active on the output:
2609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy "respectful" sonification
2610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 5: the strategy media is active on the output:
2611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy media
2612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 6: the strategy DTMF is active on the output:
2613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy DTMF
2614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) {
2615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
2616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (isInCall() ||
2617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->isStrategyActive(STRATEGY_PHONE)) {
2618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
2619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) {
2620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
2621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) {
2622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
2623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) {
2624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
2625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) {
2626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
2627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getNewDevice() selected device %x", device);
2630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
2631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2633e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
2634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return (uint32_t)getStrategy(stream);
2635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2637e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
2638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t devices;
2639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // By checking the range of stream before calling getStrategy, we avoid
2640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // getStrategy's behavior for invalid streams.  getStrategy would do a ALOGE
2641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and then return STRATEGY_MEDIA, but we want to return the empty set.
26423b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_CNT) {
2643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        devices = AUDIO_DEVICE_NONE;
2644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
2645e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent        AudioPolicyManager::routing_strategy strategy = getStrategy(stream);
2646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        devices = getDeviceForStrategy(strategy, true /*fromCache*/);
2647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return devices;
2649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2651e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(
26523b73df74357b33869b39a1d69427673c780bd805Eric Laurent        audio_stream_type_t stream) {
2653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // stream to strategy mapping
2654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch (stream) {
26553b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_VOICE_CALL:
26563b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_BLUETOOTH_SCO:
2657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_PHONE;
26583b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_RING:
26593b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_ALARM:
2660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_SONIFICATION;
26613b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_NOTIFICATION:
2662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_SONIFICATION_RESPECTFUL;
26633b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_DTMF:
2664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_DTMF;
2665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
2666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGE("unknown stream type");
26673b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_SYSTEM:
2668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
2669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // while key clicks are played produces a poor result
26703b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_TTS:
26713b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_MUSIC:
2672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_MEDIA;
26733b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_ENFORCED_AUDIBLE:
2674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return STRATEGY_ENFORCED_AUDIBLE;
2675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2678e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
2679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch(stream) {
26803b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_MUSIC:
2681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
2682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        updateDevicesAndOutputs();
2683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
2684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
2685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
2686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2689e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
2690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                             bool fromCache)
2691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t device = AUDIO_DEVICE_NONE;
2693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (fromCache) {
2695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
2696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              strategy, mDeviceForStrategy[strategy]);
2697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mDeviceForStrategy[strategy];
2698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
26993a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
2700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch (strategy) {
2701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_SONIFICATION_RESPECTFUL:
2703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (isInCall()) {
2704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
27053b73df74357b33869b39a1d69427673c780bd805Eric Laurent        } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
2706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
2707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // while media is playing on a remote device, use the the sonification behavior.
2708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // Note that we test this usecase before testing if media is playing because
2709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            //   the isStreamActive() method only informs about the activity of a stream, not
2710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            //   if it's for local playback. Note also that we use the same delay between both tests
2711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
27123b73df74357b33869b39a1d69427673c780bd805Eric Laurent        } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
2713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // while media is playing (or has recently played), use the same device
2714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
2715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else {
2716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // when media is not playing anymore, fall back on the sonification behavior
2717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
2718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
2721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_DTMF:
2723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!isInCall()) {
2724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // when off call, DTMF strategy follows the same rules as MEDIA strategy
2725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
2726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            break;
2727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // when in call, DTMF and PHONE strategies follow the same rules
2729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // FALL THROUGH
2730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_PHONE:
2732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // for phone strategy, we first consider the forced use and then the available devices by order
2733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // of priority
27343b73df74357b33869b39a1d69427673c780bd805Eric Laurent        switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
27353b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_FORCE_BT_SCO:
2736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (!isInCall() || strategy != STRATEGY_DTMF) {
27373a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
2738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
2739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
27403a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
2741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
27423a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
2743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
2744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // if SCO device is requested but no SCO device is available, fall back to default case
2745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // FALL THROUGH
2746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:    // FORCE_NONE
2748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
27493a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (!isInCall() &&
27503b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
2751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    (getA2dpOutput() != 0) && !mA2dpSuspended) {
27523a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
2753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27543a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
2755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
2756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
27573a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
2758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
27593a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
2760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
27613b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (mPhoneState != AUDIO_MODE_IN_CALL) {
27623a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
2763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27643a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
2765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27663a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
2767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27683a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
2769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27703a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
2771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
2772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
27733a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE;
2774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
27753a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = mDefaultOutputDevice->mType;
2776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device == AUDIO_DEVICE_NONE) {
2777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
2778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            break;
2780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
27813b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_FORCE_SPEAKER:
2782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
2783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // A2DP speaker when forcing to speaker output
27843a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (!isInCall() &&
27853b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
2786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    (getA2dpOutput() != 0) && !mA2dpSuspended) {
27873a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
2788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
2789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
27903b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (mPhoneState != AUDIO_MODE_IN_CALL) {
27913a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
2792e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27933a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
2794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27953a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
2796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27973a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
2798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
27993a4311c68348f728558e87b5db67d47605783890Eric Laurent                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
2800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (device) break;
2801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
28023a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
2803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device) break;
28043a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = mDefaultOutputDevice->mType;
2805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device == AUDIO_DEVICE_NONE) {
2806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
2807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            break;
2809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    break;
2811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_SONIFICATION:
2813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
2815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handleIncallSonification().
2816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (isInCall()) {
2817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
2818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            break;
2819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // FALL THROUGH
2821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_ENFORCED_AUDIBLE:
2823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
2824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // except:
2825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        //   - when in call where it doesn't default to STRATEGY_PHONE behavior
2826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        //   - in countries where not enforced in which case it follows STRATEGY_MEDIA
2827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((strategy == STRATEGY_SONIFICATION) ||
28293b73df74357b33869b39a1d69427673c780bd805Eric Laurent                (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
28303a4311c68348f728558e87b5db67d47605783890Eric Laurent            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
2831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device == AUDIO_DEVICE_NONE) {
2832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
2833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // The second device used for sonification is the same as the device used by media strategy
2836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // FALL THROUGH
2837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case STRATEGY_MEDIA: {
2839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        uint32_t device2 = AUDIO_DEVICE_NONE;
2840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strategy != STRATEGY_SONIFICATION) {
2841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // no sonification on remote submix (e.g. WFD)
28423a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
2843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device2 == AUDIO_DEVICE_NONE) &&
28453b73df74357b33869b39a1d69427673c780bd805Eric Laurent                (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
2846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                (getA2dpOutput() != 0) && !mA2dpSuspended) {
28473a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
2848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device2 == AUDIO_DEVICE_NONE) {
28493a4311c68348f728558e87b5db67d47605783890Eric Laurent                device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
2850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (device2 == AUDIO_DEVICE_NONE) {
28523a4311c68348f728558e87b5db67d47605783890Eric Laurent                device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
2853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28563a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
2857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28593a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
2860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28623a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
2863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28653a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
2866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28683a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
2869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
2871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // no sonification on aux digital (e.g. HDMI)
28723a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
2873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device2 == AUDIO_DEVICE_NONE) &&
28753b73df74357b33869b39a1d69427673c780bd805Eric Laurent                (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
28763a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
2877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device2 == AUDIO_DEVICE_NONE) {
28793a4311c68348f728558e87b5db67d47605783890Eric Laurent            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
2880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
2883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
2884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device |= device2;
2885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device) break;
28863a4311c68348f728558e87b5db67d47605783890Eric Laurent        device = mDefaultOutputDevice->mType;
2887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device == AUDIO_DEVICE_NONE) {
2888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
2889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } break;
2891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
2893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
2894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
2895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
2898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
2899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2901e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::updateDevicesAndOutputs()
2902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < NUM_STRATEGIES; i++) {
2904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
2905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPreviousOutputs = mOutputs;
2907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2909e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc,
2910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       audio_devices_t prevDevice,
2911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       uint32_t delayMs)
2912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // mute/unmute strategies using an incompatible device combination
2914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if muting, wait for the audio in pcm buffer to be drained before proceeding
2915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if unmuting, unmute only after the specified delay
2916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isDuplicated()) {
2917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
2918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t muteWaitMs = 0;
2921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = outputDesc->device();
29223b73df74357b33869b39a1d69427673c780bd805Eric Laurent    bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2);
2923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // temporary mute output if device selection changes to avoid volume bursts due to
2924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // different per device volumes
2925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    bool tempMute = outputDesc->isActive() && (device != prevDevice);
2926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < NUM_STRATEGIES; i++) {
2928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
2929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool mute = shouldMute && (curDevice & device) && (curDevice != device);
2930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool doMute = false;
2931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
2933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            doMute = true;
2934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStrategyMutedByDevice[i] = true;
2935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
2936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            doMute = true;
2937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStrategyMutedByDevice[i] = false;
2938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (doMute || tempMute) {
2940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mOutputs.size(); j++) {
2941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioOutputDescriptor *desc = mOutputs.valueAt(j);
2942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // skip output if it does not share any device with current output
2943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if ((desc->supportedDevices() & outputDesc->supportedDevices())
2944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        == AUDIO_DEVICE_NONE) {
2945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    continue;
2946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                audio_io_handle_t curOutput = mOutputs.keyAt(j);
2948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d",
2949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                      mute ? "muting" : "unmuting", i, curDevice, curOutput);
2950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs);
2951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (desc->isStrategyActive((routing_strategy)i)) {
2952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    // do tempMute only for current output
2953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (tempMute && (desc == outputDesc)) {
2954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        setStrategyMute((routing_strategy)i, true, curOutput);
2955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        setStrategyMute((routing_strategy)i, false, curOutput,
2956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            desc->latency() * 2, device);
2957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if ((tempMute && (desc == outputDesc)) || mute) {
2959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        if (muteWaitMs < desc->latency()) {
2960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            muteWaitMs = desc->latency();
2961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        }
2962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
2963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
2964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // FIXME: should not need to double latency if volume could be applied immediately by the
2969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // audioflinger mixer. We must account for the delay between now and the next time
2970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // the audioflinger thread for this output will process a buffer (which corresponds to
2971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // one buffer size, usually 1/2 or 1/4 of the latency).
2972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    muteWaitMs *= 2;
2973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // wait for the PCM output buffers to empty before proceeding with the rest of the command
2974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (muteWaitMs > delayMs) {
2975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        muteWaitMs -= delayMs;
2976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        usleep(muteWaitMs * 1000);
2977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
2978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
2980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2982e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output,
2983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             audio_devices_t device,
2984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             bool force,
2985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             int delayMs)
2986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs);
2988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
2989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioParameter param;
2990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t muteWaitMs;
2991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isDuplicated()) {
2993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs);
2994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs);
2995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
2996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
2998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // output profile
2999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((device != AUDIO_DEVICE_NONE) &&
30003a4311c68348f728558e87b5db67d47605783890Eric Laurent            ((device & outputDesc->mProfile->mSupportedDevices.types()) == 0)) {
3001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
3002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // filter devices according to output selected
30053a4311c68348f728558e87b5db67d47605783890Eric Laurent    device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices.types());
3006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t prevDevice = outputDesc->mDevice;
3008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setOutputDevice() prevDevice %04x", prevDevice);
3010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device != AUDIO_DEVICE_NONE) {
3012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mDevice = device;
3013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
3015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not change the routing if:
3017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //  - the requested device is AUDIO_DEVICE_NONE
3018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //  - the requested device is the same as current device and force is not specified.
3019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Doing this check here allows the caller to call setOutputDevice() without conditions
3020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) {
3021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output);
3022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
3023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setOutputDevice() changing device");
3026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do the routing
3027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    param.addInt(String8(AudioParameter::keyRouting), (int)device);
3028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->setParameters(output, param.toString(), delayMs);
3029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // update stream volumes according to new device
3031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    applyStreamVolumes(output, device, delayMs);
3032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return muteWaitMs;
3034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3036e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile *AudioPolicyManager::getInputProfile(audio_devices_t device,
3037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   uint32_t samplingRate,
3038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   audio_format_t format,
3039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   audio_channel_mask_t channelMask)
3040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Choose an input profile based on the requested capture parameters: select the first available
3042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // profile supporting all requested parameters.
3043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++)
3045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
3046e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
3047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
3048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
3050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
3051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            IOProfile *profile = mHwModules[i]->mInputProfiles[j];
3052d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            // profile->log();
3053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (profile->isCompatibleProfile(device, samplingRate, format,
3054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             channelMask, AUDIO_OUTPUT_FLAG_NONE)) {
3055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return profile;
3056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NULL;
3060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3062e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
3063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t device = AUDIO_DEVICE_NONE;
30653a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() &
30663a4311c68348f728558e87b5db67d47605783890Eric Laurent                                            ~AUDIO_DEVICE_BIT_IN;
3067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch (inputSource) {
3068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_UPLINK:
30693a4311c68348f728558e87b5db67d47605783890Eric Laurent      if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
3070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          device = AUDIO_DEVICE_IN_VOICE_CALL;
3071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          break;
3072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent      }
3073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent      // FALL THROUGH
3074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_DEFAULT:
3076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_MIC:
3077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_RECOGNITION:
3078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_HOTWORD:
3079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_COMMUNICATION:
30803b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
30813a4311c68348f728558e87b5db67d47605783890Eric Laurent                availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
3082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
30833a4311c68348f728558e87b5db67d47605783890Eric Laurent        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
3084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_WIRED_HEADSET;
3085d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
3086d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            device = AUDIO_DEVICE_IN_USB_DEVICE;
30873a4311c68348f728558e87b5db67d47605783890Eric Laurent        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
3088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
3089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
3091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_CAMCORDER:
30923a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
3093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_BACK_MIC;
30943a4311c68348f728558e87b5db67d47605783890Eric Laurent        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
3095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
3096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
3098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_DOWNLINK:
3099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_VOICE_CALL:
31003a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
3101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_VOICE_CALL;
3102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
3104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    case AUDIO_SOURCE_REMOTE_SUBMIX:
31053a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
3106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
3107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
3109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
3110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
3111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
3112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
3114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
3115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3117e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device)
3118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((device & AUDIO_DEVICE_BIT_IN) != 0) {
3120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device &= ~AUDIO_DEVICE_BIT_IN;
3121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0))
3122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
3123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
3125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3127e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs)
3128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
3130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const AudioInputDescriptor * input_descriptor = mInputs.valueAt(i);
3131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((input_descriptor->mRefCount > 0)
3132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) {
3133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return mInputs.keyAt(i);
3134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
3137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3140e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device)
3141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
3143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // this happens when forcing a route update and no track is active on an output.
3144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // In this case the returned category is not important.
3145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device =  AUDIO_DEVICE_OUT_SPEAKER;
31463b73df74357b33869b39a1d69427673c780bd805Eric Laurent    } else if (popcount(device) > 1) {
3147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Multiple device selection is either:
3148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        //  - speaker + one other device: give priority to speaker in this case.
3149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        //  - one A2DP device + another device: happens with duplicated output. In this case
3150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // retain the device on the A2DP output as the other must not correspond to an active
3151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // selection if not the speaker.
3152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (device & AUDIO_DEVICE_OUT_SPEAKER) {
3153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = AUDIO_DEVICE_OUT_SPEAKER;
3154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else {
3155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP);
3156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
31593b73df74357b33869b39a1d69427673c780bd805Eric Laurent    ALOGW_IF(popcount(device) != 1,
3160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "getDeviceForVolume() invalid device combination: %08x",
3161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device);
3162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
3164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3166e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device)
3167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch(getDeviceForVolume(device)) {
3169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_EARPIECE:
3170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return DEVICE_CATEGORY_EARPIECE;
3171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_WIRED_HEADSET:
3172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
3173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
3174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
3175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
3176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
3177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return DEVICE_CATEGORY_HEADSET;
3178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_SPEAKER:
3179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
3180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
3181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_AUX_DIGITAL:
3182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_USB_ACCESSORY:
3183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_USB_DEVICE:
3184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        case AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
3185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
3186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return DEVICE_CATEGORY_SPEAKER;
3187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3190e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
3191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        int indexInUi)
3192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    device_category deviceCategory = getDeviceCategory(device);
3194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory];
3195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // the volume index in the UI is relative to the min and max volume indices for this stream type
3197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int nbSteps = 1 + curve[VOLMAX].mIndex -
3198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            curve[VOLMIN].mIndex;
3199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) /
3200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (streamDesc.mIndexMax - streamDesc.mIndexMin);
3201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // find what part of the curve this index volume belongs to, or if it's out of bounds
3203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int segment = 0;
3204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (volIdx < curve[VOLMIN].mIndex) {         // out of bounds
3205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0.0f;
3206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (volIdx < curve[VOLKNEE1].mIndex) {
3207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        segment = 0;
3208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (volIdx < curve[VOLKNEE2].mIndex) {
3209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        segment = 1;
3210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (volIdx <= curve[VOLMAX].mIndex) {
3211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        segment = 2;
3212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {                                                               // out of bounds
3213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 1.0f;
3214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // linear interpolation in the attenuation table in dB
3217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    float decibels = curve[segment].mDBAttenuation +
3218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ((float)(volIdx - curve[segment].mIndex)) *
3219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ( (curve[segment+1].mDBAttenuation -
3220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        curve[segment].mDBAttenuation) /
3221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ((float)(curve[segment+1].mIndex -
3222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                            curve[segment].mIndex)) );
3223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 )
3225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f",
3227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            curve[segment].mIndex, volIdx,
3228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            curve[segment+1].mIndex,
3229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            curve[segment].mDBAttenuation,
3230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            decibels,
3231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            curve[segment+1].mDBAttenuation,
3232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            amplification);
3233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return amplification;
3235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3237e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3238e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sDefaultVolumeCurve[AudioPolicyManager::VOLCNT] = {
3239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f}
3240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3242e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3243e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT] = {
3244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f}
3245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3247e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3248e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT] = {
3249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f}
3250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3252e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3253e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = {
3254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f}
3255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3257e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3258e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
3259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f}
3260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks
3263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets.
3264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java).
3265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset.
3266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3267e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3268e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
3269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f}
3270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3272e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3273e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
3274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f}
3275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3277e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3278e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
3279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f}
3280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3282e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3283e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = {
3284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f}
3285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3287e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3288e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    AudioPolicyManager::sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = {
3289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f}
3290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3292e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentconst AudioPolicyManager::VolumeCurvePoint
3293e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent            *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT]
3294e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent                                                   [AudioPolicyManager::DEVICE_CATEGORY_CNT] = {
3295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_VOICE_CALL
3296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
3297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVoiceVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_SYSTEM
3301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
3302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_RING
3306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
3307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_MUSIC
3311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
3312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_ALARM
3316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
3317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_NOTIFICATION
3321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
3322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_BLUETOOTH_SCO
3326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
3327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultVoiceVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_ENFORCED_AUDIBLE
3331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
3332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {  // AUDIO_STREAM_DTMF
3336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
3337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultSystemVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    { // AUDIO_STREAM_TTS
3341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
3342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
3343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EARPIECE
3344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    },
3345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent};
3346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3347e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initializeVolumeCurves()
3348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
3350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
3351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mStreams[i].mVolumeCurve[j] =
3352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    sVolumeProfiles[i][j];
3353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check availability of DRC on speaker path: if available, override some of the speaker curves
3357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mSpeakerDrcEnabled) {
3358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
3359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                sDefaultSystemVolumeCurveDrc;
3360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
3361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                sSpeakerSonificationVolumeCurveDrc;
3362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
3363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                sSpeakerSonificationVolumeCurveDrc;
3364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
3365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                sSpeakerSonificationVolumeCurveDrc;
3366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3369e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::computeVolume(audio_stream_type_t stream,
3370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int index,
3371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            audio_io_handle_t output,
3372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            audio_devices_t device)
3373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    float volume = 1.0;
3375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
3376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    StreamDescriptor &streamDesc = mStreams[stream];
3377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
3379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = outputDesc->device();
3380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if volume is not 0 (not muted), force media volume to max on digital output
33833b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (stream == AUDIO_STREAM_MUSIC &&
3384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        index != mStreams[stream].mIndexMin &&
3385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        (device == AUDIO_DEVICE_OUT_AUX_DIGITAL ||
3386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET ||
3387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         device == AUDIO_DEVICE_OUT_USB_ACCESSORY ||
3388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         device == AUDIO_DEVICE_OUT_USB_DEVICE)) {
3389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 1.0;
3390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    volume = volIndexToAmpl(device, streamDesc, index);
3393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if a headset is connected, apply the following rules to ring tones and notifications
3395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // to avoid sound level bursts in user's ears:
3396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // - always attenuate ring tones and notifications volume by 6dB
3397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // - if music is playing, always limit the volume to current music volume,
3398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // with a minimum threshold at -36dB so that notification is always perceived.
33993b73df74357b33869b39a1d69427673c780bd805Eric Laurent    const routing_strategy stream_strategy = getStrategy(stream);
3400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
3401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
3402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_WIRED_HEADSET |
3403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) &&
3404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ((stream_strategy == STRATEGY_SONIFICATION)
3405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
34063b73df74357b33869b39a1d69427673c780bd805Eric Laurent                || (stream == AUDIO_STREAM_SYSTEM)
3407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
34083b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) &&
3409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        streamDesc.mCanBeMuted) {
3410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
3411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // when the phone is ringing we must consider that music could have been paused just before
3412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // by the music application and behave as if music was active if the last music track was
3413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // just stopped
34143b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
3415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mLimitRingtoneVolume) {
3416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
34173b73df74357b33869b39a1d69427673c780bd805Eric Laurent            float musicVol = computeVolume(AUDIO_STREAM_MUSIC,
34183b73df74357b33869b39a1d69427673c780bd805Eric Laurent                               mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice),
3419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                               output,
3420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                               musicDevice);
3421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ?
3422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
3423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (volume > minVol) {
3424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                volume = minVol;
3425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
3426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return volume;
3431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3433e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
3434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   int index,
3435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   audio_io_handle_t output,
3436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   audio_devices_t device,
3437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   int delayMs,
3438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   bool force)
3439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do not change actual stream volume if the stream is muted
3442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
3443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("checkAndSetVolume() stream %d muted count %d",
3444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              stream, mOutputs.valueFor(output)->mMuteCount[stream]);
3445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
3446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do not change in call volume if bluetooth is connected and vice versa
34493b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if ((stream == AUDIO_STREAM_VOICE_CALL &&
34503b73df74357b33869b39a1d69427673c780bd805Eric Laurent            mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) ||
34513b73df74357b33869b39a1d69427673c780bd805Eric Laurent        (stream == AUDIO_STREAM_BLUETOOTH_SCO &&
34523b73df74357b33869b39a1d69427673c780bd805Eric Laurent                mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO)) {
3453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
34543b73df74357b33869b39a1d69427673c780bd805Eric Laurent             stream, mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]);
3455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
3456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    float volume = computeVolume(stream, index, output, device);
3459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // We actually change the volume if:
3460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // - the float value returned by computeVolume() changed
3461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // - the force flag is set
3462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
3463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            force) {
3464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mOutputs.valueFor(output)->mCurVolume[stream] = volume;
3465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
3466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
3467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // enabled
34683b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
34693b73df74357b33869b39a1d69427673c780bd805Eric Laurent            mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs);
3470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
34713b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mpClientInterface->setStreamVolume(stream, volume, output, delayMs);
3472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
34743b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (stream == AUDIO_STREAM_VOICE_CALL ||
34753b73df74357b33869b39a1d69427673c780bd805Eric Laurent        stream == AUDIO_STREAM_BLUETOOTH_SCO) {
3476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        float voiceVolume;
3477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Force voice volume to max for bluetooth SCO as volume is managed by the headset
34783b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (stream == AUDIO_STREAM_VOICE_CALL) {
3479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
3480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else {
3481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            voiceVolume = 1.0;
3482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {
3485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
3486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mLastVoiceVolume = voiceVolume;
3487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
3491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3493e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output,
3494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                audio_devices_t device,
3495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                int delayMs,
3496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                bool force)
3497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("applyStreamVolumes() for output %d and device %x", output, device);
3499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
35003b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
35013b73df74357b33869b39a1d69427673c780bd805Eric Laurent        checkAndSetVolume((audio_stream_type_t)stream,
3502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          mStreams[stream].getVolumeIndex(device),
3503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          output,
3504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          device,
3505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          delayMs,
3506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          force);
3507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3510e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStrategyMute(routing_strategy strategy,
3511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             bool on,
3512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             audio_io_handle_t output,
3513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             int delayMs,
3514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             audio_devices_t device)
3515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
35173b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
35183b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (getStrategy((audio_stream_type_t)stream) == strategy) {
35193b73df74357b33869b39a1d69427673c780bd805Eric Laurent            setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device);
3520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3524e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
3525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           bool on,
3526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           audio_io_handle_t output,
3527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           int delayMs,
3528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           audio_devices_t device)
3529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    StreamDescriptor &streamDesc = mStreams[stream];
3531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
3532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
3533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = outputDesc->device();
3534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x",
3537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          stream, on, output, outputDesc->mMuteCount[stream], device);
3538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (on) {
3540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mMuteCount[stream] == 0) {
3541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (streamDesc.mCanBeMuted &&
35423b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
35433b73df74357b33869b39a1d69427673c780bd805Eric Laurent                     (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) {
3544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                checkAndSetVolume(stream, 0, output, device, delayMs);
3545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
3548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mMuteCount[stream]++;
3549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
3550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mMuteCount[stream] == 0) {
3551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setStreamMute() unmuting non muted stream!");
3552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
3553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (--outputDesc->mMuteCount[stream] == 0) {
3555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            checkAndSetVolume(stream,
3556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              streamDesc.getVolumeIndex(device),
3557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              output,
3558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              device,
3559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              delayMs);
3560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3564e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
35653b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                      bool starting, bool stateChange)
3566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if the stream pertains to sonification strategy and we are in call we must
3568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // mute the stream if it is low visibility. If it is high visibility, we must play a tone
3569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the device used for phone strategy and play the tone if the selected device does not
3570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // interfere with the device used for phone strategy
3571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
3572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // many times as there are active tracks on the output
35733b73df74357b33869b39a1d69427673c780bd805Eric Laurent    const routing_strategy stream_strategy = getStrategy(stream);
3574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((stream_strategy == STRATEGY_SONIFICATION) ||
3575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
3576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput);
3577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
3578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                stream, starting, outputDesc->mDevice, stateChange);
3579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mRefCount[stream]) {
3580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            int muteCount = 1;
3581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (stateChange) {
3582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                muteCount = outputDesc->mRefCount[stream];
3583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
35843b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (audio_is_low_visibility(stream)) {
3585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
3586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                for (int i = 0; i < muteCount; i++) {
3587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    setStreamMute(stream, starting, mPrimaryOutput);
3588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
3590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("handleIncallSonification() high visibility");
3591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (outputDesc->device() &
3592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
3593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
3594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    for (int i = 0; i < muteCount; i++) {
3595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        setStreamMute(stream, starting, mPrimaryOutput);
3596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
3597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (starting) {
35993b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
36003b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                 AUDIO_STREAM_VOICE_CALL);
3601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else {
3602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mpClientInterface->stopTone();
3603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3609e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isInCall()
3610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return isStateInCall(mPhoneState);
3612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3614e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isStateInCall(int state) {
36153b73df74357b33869b39a1d69427673c780bd805Eric Laurent    return ((state == AUDIO_MODE_IN_CALL) ||
36163b73df74357b33869b39a1d69427673c780bd805Eric Laurent            (state == AUDIO_MODE_IN_COMMUNICATION));
3617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3619e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsCpuLoad()
3620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return MAX_EFFECTS_CPU_LOAD;
3622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3624e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getMaxEffectsMemory()
3625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return MAX_EFFECTS_MEMORY;
3627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioOutputDescriptor class implementation
3630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3631e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor(
3632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const IOProfile *profile)
3633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    : mId(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT),
3634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent      mChannelMask(0), mLatency(0),
3635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE),
3636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0)
3637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // clear usage count for all stream types
36393b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
3640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mRefCount[i] = 0;
3641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mCurVolume[i] = -1.0;
3642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mMuteCount[i] = 0;
3643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStopTime[i] = 0;
3644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < NUM_STRATEGIES; i++) {
3646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mStrategyMutedByDevice[i] = false;
3647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (profile != NULL) {
3649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mSamplingRate = profile->mSamplingRates[0];
3650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mFormat = profile->mFormats[0];
3651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mChannelMask = profile->mChannelMasks[0];
3652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mFlags = profile->mFlags;
3653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3656e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::device() const
3657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isDuplicated()) {
3659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
3660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
3661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mDevice;
3662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3665e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::AudioOutputDescriptor::latency()
3666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isDuplicated()) {
3668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
3669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
3670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mLatency;
3671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3674e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith(
3675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const AudioOutputDescriptor *outputDesc)
3676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isDuplicated()) {
3678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
3679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (outputDesc->isDuplicated()){
3680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2);
3681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
3682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return (mProfile->mModule == outputDesc->mProfile->mModule);
3683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3686e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
36873b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                                   int delta)
3688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // forward usage count change to attached outputs
3690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isDuplicated()) {
3691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mOutput1->changeRefCount(stream, delta);
3692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mOutput2->changeRefCount(stream, delta);
3693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((delta + (int)mRefCount[stream]) < 0) {
36953b73df74357b33869b39a1d69427673c780bd805Eric Laurent        ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
36963b73df74357b33869b39a1d69427673c780bd805Eric Laurent              delta, stream, mRefCount[stream]);
3697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mRefCount[stream] = 0;
3698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
3699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mRefCount[stream] += delta;
3701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
3702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3704e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::AudioOutputDescriptor::supportedDevices()
3705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isDuplicated()) {
3707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
3708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
37093a4311c68348f728558e87b5db67d47605783890Eric Laurent        return mProfile->mSupportedDevices.types() ;
3710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3713e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isActive(uint32_t inPastMs) const
3714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return isStrategyActive(NUM_STRATEGIES, inPastMs);
3716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3718e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy,
3719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       uint32_t inPastMs,
3720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       nsecs_t sysTime) const
3721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((sysTime == 0) && (inPastMs != 0)) {
3723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sysTime = systemTime();
3724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
37253b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
37263b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (((getStrategy((audio_stream_type_t)i) == strategy) ||
3727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                (NUM_STRATEGIES == strategy)) &&
37283b73df74357b33869b39a1d69427673c780bd805Eric Laurent                isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
3729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
3730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
3733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3735e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
3736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       uint32_t inPastMs,
3737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                                       nsecs_t sysTime) const
3738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mRefCount[stream] != 0) {
3740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return true;
3741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (inPastMs == 0) {
3743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
3744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (sysTime == 0) {
3746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        sysTime = systemTime();
3747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
3749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return true;
3750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
3752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3755e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd)
3756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
3758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
3759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
3760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
3762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
3764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
3766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
3768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
3770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Devices %08x\n", device());
3772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
3774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
37753b73df74357b33869b39a1d69427673c780bd805Eric Laurent    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
37763b73df74357b33869b39a1d69427673c780bd805Eric Laurent        snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n",
37773b73df74357b33869b39a1d69427673c780bd805Eric Laurent                 i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
3778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(buffer);
3779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
3781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
3783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- AudioInputDescriptor class implementation
3786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3787e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const IOProfile *profile)
3788d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    : mId(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(0),
3789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent      mDevice(AUDIO_DEVICE_NONE), mRefCount(0),
37903b73df74357b33869b39a1d69427673c780bd805Eric Laurent      mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile)
3791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
37923a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (profile != NULL) {
37933a4311c68348f728558e87b5db67d47605783890Eric Laurent        mSamplingRate = profile->mSamplingRates[0];
37943a4311c68348f728558e87b5db67d47605783890Eric Laurent        mFormat = profile->mFormats[0];
37953a4311c68348f728558e87b5db67d47605783890Eric Laurent        mChannelMask = profile->mChannelMasks[0];
37963a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
3797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3799e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::AudioInputDescriptor::dump(int fd)
3800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
3802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
3803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
3804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
3806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
3808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
3810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
3812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
3814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
3816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
3818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- StreamDescriptor class implementation
3821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3822e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::StreamDescriptor::StreamDescriptor()
3823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    :   mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
3824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0);
3826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3828e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::StreamDescriptor::getVolumeIndex(audio_devices_t device)
3829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3830e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent    device = AudioPolicyManager::getDeviceForVolume(device);
3831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT
3832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mIndexCur.indexOfKey(device) < 0) {
3833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = AUDIO_DEVICE_OUT_DEFAULT;
3834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return mIndexCur.valueFor(device);
3836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3838e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::StreamDescriptor::dump(int fd)
3839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
3841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
3842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
3843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "%s         %02d         %02d         ",
3845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
3846e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mIndexCur.size(); i++) {
3848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "%04x : %02d, ",
3849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                 mIndexCur.keyAt(i),
3850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                 mIndexCur.valueAt(i));
3851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(buffer);
3852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append("\n");
3854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
3856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- EffectDescriptor class implementation
3859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3860e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::EffectDescriptor::dump(int fd)
3861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
3863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
3864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
3865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " I/O: %d\n", mIo);
3867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy);
3869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Session: %d\n", mSession);
3871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " Name: %s\n",  mDesc.name);
3873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, " %s\n",  mEnabled ? "Enabled" : "Disabled");
3875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
3877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
3879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// --- IOProfile class implementation
3882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3883e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::HwModule(const char *name)
3884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0)
3885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3888e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::HwModule::~HwModule()
3889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputProfiles.size(); i++) {
38913a4311c68348f728558e87b5db67d47605783890Eric Laurent        mOutputProfiles[i]->mSupportedDevices.clear();
38923a4311c68348f728558e87b5db67d47605783890Eric Laurent        delete mOutputProfiles[i];
3893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mInputProfiles.size(); i++) {
38953a4311c68348f728558e87b5db67d47605783890Eric Laurent        mInputProfiles[i]->mSupportedDevices.clear();
38963a4311c68348f728558e87b5db67d47605783890Eric Laurent        delete mInputProfiles[i];
3897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    free((void *)mName);
3899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3901e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::HwModule::dump(int fd)
3902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
3904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
3905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
3906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "  - name: %s\n", mName);
3908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "  - handle: %d\n", mHandle);
3910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
3912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mOutputProfiles.size()) {
3913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, "  - outputs:\n", strlen("  - outputs:\n"));
3914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputProfiles.size(); i++) {
3915d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            snprintf(buffer, SIZE, "    output %zu:\n", i);
3916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            write(fd, buffer, strlen(buffer));
3917e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mOutputProfiles[i]->dump(fd);
3918e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3919e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mInputProfiles.size()) {
3921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        write(fd, "  - inputs:\n", strlen("  - inputs:\n"));
3922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mInputProfiles.size(); i++) {
3923d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            snprintf(buffer, SIZE, "    input %zu:\n", i);
3924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            write(fd, buffer, strlen(buffer));
3925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mInputProfiles[i]->dump(fd);
3926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3930e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile::IOProfile(HwModule *module)
3931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    : mFlags((audio_output_flags_t)0), mModule(module)
3932e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3933e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3935e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::IOProfile::~IOProfile()
3936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// checks if the IO profile is compatible with specified parameters.
3940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Sampling rate, format and channel mask must be specified in order to
3941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// get a valid a match
3942e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device,
3943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                            uint32_t samplingRate,
3944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                            audio_format_t format,
3945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                            audio_channel_mask_t channelMask,
3946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                            audio_output_flags_t flags) const
3947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (samplingRate == 0 || !audio_is_valid_format(format) || channelMask == 0) {
3949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
3950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
3951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
39523a4311c68348f728558e87b5db67d47605783890Eric Laurent     if ((mSupportedDevices.types() & device) != device) {
3953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
3954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
3955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     if ((mFlags & flags) != flags) {
3956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
3957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
3958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     size_t i;
3959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     for (i = 0; i < mSamplingRates.size(); i++)
3960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     {
3961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         if (mSamplingRates[i] == samplingRate) {
3962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             break;
3963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         }
3964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
3965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     if (i == mSamplingRates.size()) {
3966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
3967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
3968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     for (i = 0; i < mFormats.size(); i++)
3969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     {
3970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         if (mFormats[i] == format) {
3971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             break;
3972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         }
3973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
3974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     if (i == mFormats.size()) {
3975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
3976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
3977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     for (i = 0; i < mChannelMasks.size(); i++)
3978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     {
3979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         if (mChannelMasks[i] == channelMask) {
3980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent             break;
3981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         }
3982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
3983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     if (i == mChannelMasks.size()) {
3984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent         return false;
3985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     }
3986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     return true;
3987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3989e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::IOProfile::dump(int fd)
3990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
3992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
3993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
3994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "    - sampling rates: ");
3996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
3997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mSamplingRates.size(); i++) {
3998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "%d", mSamplingRates[i]);
3999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(buffer);
4000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(i == (mSamplingRates.size() - 1) ? "\n" : ", ");
4001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "    - channel masks: ");
4004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mChannelMasks.size(); i++) {
4006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]);
4007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(buffer);
4008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(i == (mChannelMasks.size() - 1) ? "\n" : ", ");
4009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "    - formats: ");
4012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mFormats.size(); i++) {
4014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "0x%08x", mFormats[i]);
4015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(buffer);
4016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        result.append(i == (mFormats.size() - 1) ? "\n" : ", ");
4017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
40193a4311c68348f728558e87b5db67d47605783890Eric Laurent    snprintf(buffer, SIZE, "    - devices:\n");
4020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
40213a4311c68348f728558e87b5db67d47605783890Eric Laurent    write(fd, result.string(), result.size());
40223a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceDescriptor::dumpHeader(fd, 6);
40233a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i < mSupportedDevices.size(); i++) {
40243a4311c68348f728558e87b5db67d47605783890Eric Laurent        mSupportedDevices[i]->dump(fd, 6);
40253a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
40263a4311c68348f728558e87b5db67d47605783890Eric Laurent
4027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "    - flags: 0x%04x\n", mFlags);
4028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
4029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    write(fd, result.string(), result.size());
4031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4033d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::IOProfile::log()
4034d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
4035d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    const size_t SIZE = 256;
4036d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    char buffer[SIZE];
4037d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    String8 result;
4038d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4039d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    ALOGV("    - sampling rates: ");
4040d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    for (size_t i = 0; i < mSamplingRates.size(); i++) {
4041d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        ALOGV("  %d", mSamplingRates[i]);
4042d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }
4043d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4044d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    ALOGV("    - channel masks: ");
4045d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    for (size_t i = 0; i < mChannelMasks.size(); i++) {
4046d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        ALOGV("  0x%04x", mChannelMasks[i]);
4047d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }
4048d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4049d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    ALOGV("    - formats: ");
4050d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    for (size_t i = 0; i < mFormats.size(); i++) {
4051d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        ALOGV("  0x%08x", mFormats[i]);
4052d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }
4053d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4054d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    ALOGV("    - devices: 0x%04x\n", mSupportedDevices.types());
4055d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    ALOGV("    - flags: 0x%04x\n", mFlags);
4056d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
4057d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4058d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
40593a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- DeviceDescriptor implementation
4060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
40613a4311c68348f728558e87b5db67d47605783890Eric Laurentbool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
40623a4311c68348f728558e87b5db67d47605783890Eric Laurent{
40633a4311c68348f728558e87b5db67d47605783890Eric Laurent    // Devices are considered equal if they:
40643a4311c68348f728558e87b5db67d47605783890Eric Laurent    // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
40653a4311c68348f728558e87b5db67d47605783890Eric Laurent    // - have the same address or one device does not specify the address
40663a4311c68348f728558e87b5db67d47605783890Eric Laurent    // - have the same channel mask or one device does not specify the channel mask
40673a4311c68348f728558e87b5db67d47605783890Eric Laurent    return (mType == other->mType) &&
40683a4311c68348f728558e87b5db67d47605783890Eric Laurent           (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) &&
40692f8a36fc8df14cba33fa7c5c1c9d5a52f8a133c2Eric Laurent           (mChannelMask == 0 || other->mChannelMask == 0 ||
40703a4311c68348f728558e87b5db67d47605783890Eric Laurent                mChannelMask == other->mChannelMask);
40713a4311c68348f728558e87b5db67d47605783890Eric Laurent}
4072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
40733a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::refreshTypes()
40743a4311c68348f728558e87b5db67d47605783890Eric Laurent{
40753a4311c68348f728558e87b5db67d47605783890Eric Laurent    mTypes = AUDIO_DEVICE_NONE;
40763a4311c68348f728558e87b5db67d47605783890Eric Laurent    for(size_t i = 0; i < size(); i++) {
40773a4311c68348f728558e87b5db67d47605783890Eric Laurent        mTypes |= itemAt(i)->mType;
40783a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
40793a4311c68348f728558e87b5db67d47605783890Eric Laurent    ALOGV("DeviceVector::refreshTypes() mTypes %08x", mTypes);
40803a4311c68348f728558e87b5db67d47605783890Eric Laurent}
4081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
40823a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
40833a4311c68348f728558e87b5db67d47605783890Eric Laurent{
40843a4311c68348f728558e87b5db67d47605783890Eric Laurent    for(size_t i = 0; i < size(); i++) {
40853a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (item->equals(itemAt(i))) {
40863a4311c68348f728558e87b5db67d47605783890Eric Laurent            return i;
40873a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
40883a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
40893a4311c68348f728558e87b5db67d47605783890Eric Laurent    return -1;
40903a4311c68348f728558e87b5db67d47605783890Eric Laurent}
4091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
40923a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::add(const sp<DeviceDescriptor>& item)
40933a4311c68348f728558e87b5db67d47605783890Eric Laurent{
40943a4311c68348f728558e87b5db67d47605783890Eric Laurent    ssize_t ret = indexOf(item);
4095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
40963a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (ret < 0) {
40973a4311c68348f728558e87b5db67d47605783890Eric Laurent        ret = SortedVector::add(item);
40983a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (ret >= 0) {
40993a4311c68348f728558e87b5db67d47605783890Eric Laurent            refreshTypes();
41003a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
41013a4311c68348f728558e87b5db67d47605783890Eric Laurent    } else {
41023a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGW("DeviceVector::add device %08x already in", item->mType);
41033a4311c68348f728558e87b5db67d47605783890Eric Laurent        ret = -1;
41043a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
41053a4311c68348f728558e87b5db67d47605783890Eric Laurent    return ret;
41063a4311c68348f728558e87b5db67d47605783890Eric Laurent}
4107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
41083a4311c68348f728558e87b5db67d47605783890Eric Laurentssize_t AudioPolicyManager::DeviceVector::remove(const sp<DeviceDescriptor>& item)
41093a4311c68348f728558e87b5db67d47605783890Eric Laurent{
41103a4311c68348f728558e87b5db67d47605783890Eric Laurent    size_t i;
41113a4311c68348f728558e87b5db67d47605783890Eric Laurent    ssize_t ret = indexOf(item);
4112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
41133a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (ret < 0) {
41143a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGW("DeviceVector::remove device %08x not in", item->mType);
41153a4311c68348f728558e87b5db67d47605783890Eric Laurent    } else {
41163a4311c68348f728558e87b5db67d47605783890Eric Laurent        ret = SortedVector::removeAt(ret);
41173a4311c68348f728558e87b5db67d47605783890Eric Laurent        if (ret >= 0) {
41183a4311c68348f728558e87b5db67d47605783890Eric Laurent            refreshTypes();
41193a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
41203a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
41213a4311c68348f728558e87b5db67d47605783890Eric Laurent    return ret;
41223a4311c68348f728558e87b5db67d47605783890Eric Laurent}
4123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
41243a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceVector::loadDevicesFromType(audio_devices_t types)
4125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
41263a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceVector deviceList;
41273a4311c68348f728558e87b5db67d47605783890Eric Laurent
41283a4311c68348f728558e87b5db67d47605783890Eric Laurent    uint32_t role_bit = AUDIO_DEVICE_BIT_IN & types;
41293a4311c68348f728558e87b5db67d47605783890Eric Laurent    types &= ~role_bit;
41303a4311c68348f728558e87b5db67d47605783890Eric Laurent
41313a4311c68348f728558e87b5db67d47605783890Eric Laurent    while (types) {
41323a4311c68348f728558e87b5db67d47605783890Eric Laurent        uint32_t i = 31 - __builtin_clz(types);
41333a4311c68348f728558e87b5db67d47605783890Eric Laurent        uint32_t type = 1 << i;
41343a4311c68348f728558e87b5db67d47605783890Eric Laurent        types &= ~type;
41353a4311c68348f728558e87b5db67d47605783890Eric Laurent        add(new DeviceDescriptor(type | role_bit));
4136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
41393a4311c68348f728558e87b5db67d47605783890Eric Laurentvoid AudioPolicyManager::DeviceDescriptor::dumpHeader(int fd, int spaces)
4140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
41413a4311c68348f728558e87b5db67d47605783890Eric Laurent    const size_t SIZE = 256;
41423a4311c68348f728558e87b5db67d47605783890Eric Laurent    char buffer[SIZE];
41433a4311c68348f728558e87b5db67d47605783890Eric Laurent
41443a4311c68348f728558e87b5db67d47605783890Eric Laurent    snprintf(buffer, SIZE, "%*s%-48s %-2s %-8s %-32s \n",
41453a4311c68348f728558e87b5db67d47605783890Eric Laurent                         spaces, "", "Type", "ID", "Cnl Mask", "Address");
41463a4311c68348f728558e87b5db67d47605783890Eric Laurent    write(fd, buffer, strlen(buffer));
4147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
41493a4311c68348f728558e87b5db67d47605783890Eric Laurentstatus_t AudioPolicyManager::DeviceDescriptor::dump(int fd, int spaces) const
41503a4311c68348f728558e87b5db67d47605783890Eric Laurent{
41513a4311c68348f728558e87b5db67d47605783890Eric Laurent    const size_t SIZE = 256;
41523a4311c68348f728558e87b5db67d47605783890Eric Laurent    char buffer[SIZE];
41533a4311c68348f728558e87b5db67d47605783890Eric Laurent
41543a4311c68348f728558e87b5db67d47605783890Eric Laurent    snprintf(buffer, SIZE, "%*s%-48s %2d %08x %-32s \n",
41553a4311c68348f728558e87b5db67d47605783890Eric Laurent                         spaces, "",
41563a4311c68348f728558e87b5db67d47605783890Eric Laurent                         enumToString(sDeviceNameToEnumTable,
41573a4311c68348f728558e87b5db67d47605783890Eric Laurent                                      ARRAY_SIZE(sDeviceNameToEnumTable),
41583a4311c68348f728558e87b5db67d47605783890Eric Laurent                                      mType),
41593a4311c68348f728558e87b5db67d47605783890Eric Laurent                         mId, mChannelMask, mAddress.string());
41603a4311c68348f728558e87b5db67d47605783890Eric Laurent    write(fd, buffer, strlen(buffer));
41613a4311c68348f728558e87b5db67d47605783890Eric Laurent
41623a4311c68348f728558e87b5db67d47605783890Eric Laurent    return NO_ERROR;
41633a4311c68348f728558e87b5db67d47605783890Eric Laurent}
41643a4311c68348f728558e87b5db67d47605783890Eric Laurent
41653a4311c68348f728558e87b5db67d47605783890Eric Laurent
41663a4311c68348f728558e87b5db67d47605783890Eric Laurent// --- audio_policy.conf file parsing
41673a4311c68348f728558e87b5db67d47605783890Eric Laurent
4168e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_output_flags_t AudioPolicyManager::parseFlagNames(char *name)
4169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t flag = 0;
4171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // it is OK to cast name to non const here as we are not going to use it after
4173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // strtok() modifies it
4174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char *flagName = strtok(name, "|");
4175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (flagName != NULL) {
4176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strlen(flagName) != 0) {
4177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            flag |= stringToEnum(sFlagNameToEnumTable,
4178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                               ARRAY_SIZE(sFlagNameToEnumTable),
4179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                               flagName);
4180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        flagName = strtok(NULL, "|");
4182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //force direct flag if offload flag is set: offloading implies a direct output stream
4184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and all common behaviors are driven by checking only the direct flag
4185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // this should normally be set appropriately in the policy configuration file
4186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
4187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        flag |= AUDIO_OUTPUT_FLAG_DIRECT;
4188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return (audio_output_flags_t)flag;
4191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4193e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::parseDeviceNames(char *name)
4194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t device = 0;
4196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char *devName = strtok(name, "|");
4198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (devName != NULL) {
4199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strlen(devName) != 0) {
4200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            device |= stringToEnum(sDeviceNameToEnumTable,
4201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                 ARRAY_SIZE(sDeviceNameToEnumTable),
4202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                 devName);
42033a4311c68348f728558e87b5db67d47605783890Eric Laurent         }
4204e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        devName = strtok(NULL, "|");
42053a4311c68348f728558e87b5db67d47605783890Eric Laurent     }
4206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
4207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4209e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadSamplingRates(char *name, IOProfile *profile)
4210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char *str = strtok(name, "|");
4212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling
4214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // rates should be read from the output stream after it is opened for the first time
4215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
4216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        profile->mSamplingRates.add(0);
4217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (str != NULL) {
4221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        uint32_t rate = atoi(str);
4222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (rate != 0) {
4223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("loadSamplingRates() adding rate %d", rate);
4224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            profile->mSamplingRates.add(rate);
4225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        str = strtok(NULL, "|");
4227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return;
4229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4231e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadFormats(char *name, IOProfile *profile)
4232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char *str = strtok(name, "|");
4234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // by convention, "0' in the first entry in mFormats indicates the supported formats
4236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // should be read from the output stream after it is opened for the first time
4237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
4238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
4239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (str != NULL) {
4243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable,
4244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                             ARRAY_SIZE(sFormatNameToEnumTable),
4245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                             str);
4246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (format != AUDIO_FORMAT_DEFAULT) {
4247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            profile->mFormats.add(format);
4248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        str = strtok(NULL, "|");
4250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return;
4252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4254e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadInChannels(char *name, IOProfile *profile)
4255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const char *str = strtok(name, "|");
4257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("loadInChannels() %s", name);
4259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
4261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        profile->mChannelMasks.add(0);
4262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (str != NULL) {
4266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_channel_mask_t channelMask =
4267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable,
4268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   ARRAY_SIZE(sInChannelsNameToEnumTable),
4269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   str);
4270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (channelMask != 0) {
4271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("loadInChannels() adding channelMask %04x", channelMask);
4272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            profile->mChannelMasks.add(channelMask);
4273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        str = strtok(NULL, "|");
4275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return;
4277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4279e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadOutChannels(char *name, IOProfile *profile)
4280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const char *str = strtok(name, "|");
4282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("loadOutChannels() %s", name);
4284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // by convention, "0' in the first entry in mChannelMasks indicates the supported channel
4286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // masks should be read from the output stream after it is opened for the first time
4287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
4288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        profile->mChannelMasks.add(0);
4289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (str != NULL) {
4293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_channel_mask_t channelMask =
4294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable,
4295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   ARRAY_SIZE(sOutChannelsNameToEnumTable),
4296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                   str);
4297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (channelMask != 0) {
4298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            profile->mChannelMasks.add(channelMask);
4299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        str = strtok(NULL, "|");
4301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return;
4303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4305e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadInput(cnode *root, HwModule *module)
4306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *node = root->first_child;
4308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    IOProfile *profile = new IOProfile(module);
4310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (node) {
4312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
4313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            loadSamplingRates((char *)node->value, profile);
4314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
4315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            loadFormats((char *)node->value, profile);
4316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
4317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            loadInChannels((char *)node->value, profile);
4318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
43193a4311c68348f728558e87b5db67d47605783890Eric Laurent            profile->mSupportedDevices.loadDevicesFromType(parseDeviceNames((char *)node->value));
4320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->next;
4322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
43233a4311c68348f728558e87b5db67d47605783890Eric Laurent    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
4324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadInput() invalid supported devices");
4325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mChannelMasks.size() == 0,
4326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadInput() invalid supported channel masks");
4327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mSamplingRates.size() == 0,
4328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadInput() invalid supported sampling rates");
4329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mFormats.size() == 0,
4330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadInput() invalid supported formats");
43313a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (!profile->mSupportedDevices.isEmpty() &&
4332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mChannelMasks.size() != 0) &&
4333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mSamplingRates.size() != 0) &&
4334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mFormats.size() != 0)) {
4335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43363a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGV("loadInput() adding input Supported Devices %04x",
43373a4311c68348f728558e87b5db67d47605783890Eric Laurent              profile->mSupportedDevices.types());
4338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        module->mInputProfiles.add(profile);
4340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
4341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
4342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete profile;
4343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
4344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4347e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadOutput(cnode *root, HwModule *module)
4348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *node = root->first_child;
4350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    IOProfile *profile = new IOProfile(module);
4352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (node) {
4354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
4355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            loadSamplingRates((char *)node->value, profile);
4356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
4357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            loadFormats((char *)node->value, profile);
4358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
4359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            loadOutChannels((char *)node->value, profile);
4360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
43613a4311c68348f728558e87b5db67d47605783890Eric Laurent            profile->mSupportedDevices.loadDevicesFromType(parseDeviceNames((char *)node->value));
4362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(node->name, FLAGS_TAG) == 0) {
4363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            profile->mFlags = parseFlagNames((char *)node->value);
4364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->next;
4366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
43673a4311c68348f728558e87b5db67d47605783890Eric Laurent    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
4368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadOutput() invalid supported devices");
4369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mChannelMasks.size() == 0,
4370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadOutput() invalid supported channel masks");
4371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mSamplingRates.size() == 0,
4372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadOutput() invalid supported sampling rates");
4373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF(profile->mFormats.size() == 0,
4374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "loadOutput() invalid supported formats");
43753a4311c68348f728558e87b5db67d47605783890Eric Laurent    if (!profile->mSupportedDevices.isEmpty() &&
4376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mChannelMasks.size() != 0) &&
4377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mSamplingRates.size() != 0) &&
4378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            (profile->mFormats.size() != 0)) {
4379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43803a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x",
43813a4311c68348f728558e87b5db67d47605783890Eric Laurent              profile->mSupportedDevices.types(), profile->mFlags);
4382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        module->mOutputProfiles.add(profile);
4384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
4385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
4386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete profile;
4387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
4388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4391e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModule(cnode *root)
4392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *node = config_find(root, OUTPUTS_TAG);
4394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    status_t status = NAME_NOT_FOUND;
4395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    HwModule *module = new HwModule(root->name);
4397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (node != NULL) {
4399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->first_child;
4400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        while (node) {
4401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("loadHwModule() loading output %s", node->name);
4402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            status_t tmpStatus = loadOutput(node, module);
4403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (status == NAME_NOT_FOUND || status == NO_ERROR) {
4404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                status = tmpStatus;
4405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            node = node->next;
4407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    node = config_find(root, INPUTS_TAG);
4410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (node != NULL) {
4411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->first_child;
4412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        while (node) {
4413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("loadHwModule() loading input %s", node->name);
4414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            status_t tmpStatus = loadInput(node, module);
4415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (status == NAME_NOT_FOUND || status == NO_ERROR) {
4416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                status = tmpStatus;
4417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            node = node->next;
4419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (status == NO_ERROR) {
4422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mHwModules.add(module);
4423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
4424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        delete module;
4425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4428e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadHwModules(cnode *root)
4429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *node = config_find(root, AUDIO_HW_MODULE_TAG);
4431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (node == NULL) {
4432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    node = node->first_child;
4436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (node) {
4437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("loadHwModules() loading module %s", node->name);
4438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        loadHwModule(node);
4439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->next;
4440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4443e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::loadGlobalConfig(cnode *root)
4444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *node = config_find(root, GLOBAL_CONFIG_TAG);
4446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (node == NULL) {
4447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    node = node->first_child;
4450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (node) {
4451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) {
44523a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.loadDevicesFromType(parseDeviceNames((char *)node->value));
44533a4311c68348f728558e87b5db67d47605783890Eric Laurent            ALOGV("loadGlobalConfig() Attached Output Devices %08x",
44543a4311c68348f728558e87b5db67d47605783890Eric Laurent                  mAvailableOutputDevices.types());
4455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) {
44563a4311c68348f728558e87b5db67d47605783890Eric Laurent            audio_devices_t device = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable,
4457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                              ARRAY_SIZE(sDeviceNameToEnumTable),
4458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                              (char *)node->value);
44593a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (device != AUDIO_DEVICE_NONE) {
44603a4311c68348f728558e87b5db67d47605783890Eric Laurent                mDefaultOutputDevice = new DeviceDescriptor(device);
44613a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
44623a4311c68348f728558e87b5db67d47605783890Eric Laurent                ALOGW("loadGlobalConfig() default device not specified");
44633a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
44643a4311c68348f728558e87b5db67d47605783890Eric Laurent            ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", mDefaultOutputDevice->mType);
4465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) {
44663a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.loadDevicesFromType(parseDeviceNames((char *)node->value));
44673a4311c68348f728558e87b5db67d47605783890Eric Laurent            ALOGV("loadGlobalConfig() Available InputDevices %08x", mAvailableInputDevices.types());
4468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) {
4469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mSpeakerDrcEnabled = stringToBool((char *)node->value);
4470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled);
4471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        node = node->next;
4473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4476e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::loadAudioPolicyConfig(const char *path)
4477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    cnode *root;
4479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char *data;
4480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    data = (char *)load_file(path, NULL);
4482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (data == NULL) {
4483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return -ENODEV;
4484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    root = config_node("", "");
4486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    config_load(root, data);
4487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    loadGlobalConfig(root);
4489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    loadHwModules(root);
4490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    config_free(root);
4492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    free(root);
4493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    free(data);
4494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGI("loadAudioPolicyConfig() loaded %s\n", path);
4496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
4498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4500e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::defaultAudioPolicyConfig(void)
4501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    HwModule *module;
4503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    IOProfile *profile;
45043a4311c68348f728558e87b5db67d47605783890Eric Laurent    sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
45053a4311c68348f728558e87b5db67d47605783890Eric Laurent    mAvailableOutputDevices.add(mDefaultOutputDevice);
45063a4311c68348f728558e87b5db67d47605783890Eric Laurent    mAvailableInputDevices.add(defaultInputDevice);
4507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    module = new HwModule("primary");
4509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile = new IOProfile(module);
4511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mSamplingRates.add(44100);
4512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
4513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO);
45143a4311c68348f728558e87b5db67d47605783890Eric Laurent    profile->mSupportedDevices.add(mDefaultOutputDevice);
4515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY;
4516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    module->mOutputProfiles.add(profile);
4517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile = new IOProfile(module);
4519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mSamplingRates.add(8000);
4520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
4521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO);
45223a4311c68348f728558e87b5db67d47605783890Eric Laurent    profile->mSupportedDevices.add(defaultInputDevice);
4523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    module->mInputProfiles.add(profile);
4524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mHwModules.add(module);
4526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; // namespace android
4529