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
175ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi#define LOG_TAG "APM_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
270d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok#define AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH 128
280d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok#define AUDIO_POLICY_XML_CONFIG_FILE_NAME "audio_policy_configuration.xml"
29150b9846f846165344910b9211739cdb3054ccf4Petri Gynther#define AUDIO_POLICY_A2DP_OFFLOAD_DISABLED_XML_CONFIG_FILE_NAME \
30150b9846f846165344910b9211739cdb3054ccf4Petri Gynther        "audio_policy_configuration_a2dp_offload_disabled.xml"
31f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie
32d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <inttypes.h>
33d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <math.h>
34d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
352110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie#include <AudioPolicyManagerInterface.h>
362110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie#include <AudioPolicyEngineInstance.h>
37d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <cutils/properties.h>
38e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#include <utils/Log.h>
393b73df74357b33869b39a1d69427673c780bd805Eric Laurent#include <media/AudioParameter.h>
40e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent#include <media/AudioPolicyHelper.h>
41df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent#include <soundtrigger/SoundTrigger.h>
42cbc8f617c1aebef5d041fa40dcd38a5466690b99Mikhail Naganov#include <system/audio.h>
439ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov#include <audio_policy_conf.h>
44d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include "AudioPolicyManager.h"
45d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#ifndef USE_XML_AUDIO_POLICY_CONF
4653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#include <ConfigParsingUtils.h>
47d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#include <StreamDescriptor.h>
48f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#endif
49d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#include <Serializer.h>
50a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie#include "TypeConverter.h"
5153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#include <policy.h>
52e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
533b73df74357b33869b39a1d69427673c780bd805Eric Laurentnamespace android {
54e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
55dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent//FIXME: workaround for truncated touch sounds
56dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent// to be removed when the problem is handled by system UI
57dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent#define TOUCH_SOUND_FIXED_DELAY_MS 100
58719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi
59719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi// Largest difference in dB on earpiece in call between the voice volume and another
60719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi// media / notification / system volume.
61719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Triviconstexpr float IN_CALL_EARPIECE_HEADROOM_DB = 3.f;
62719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi
63817729095966c338615a8a791d2dbf774fc034efjiabin#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
64817729095966c338615a8a791d2dbf774fc034efjiabin// Array of all surround formats.
65817729095966c338615a8a791d2dbf774fc034efjiabinstatic const audio_format_t SURROUND_FORMATS[] = {
66817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_AC3,
67817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_E_AC3,
68817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_DTS,
69817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_DTS_HD,
70817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_AAC_LC,
71817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_DOLBY_TRUEHD,
72817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_E_AC3_JOC,
73817729095966c338615a8a791d2dbf774fc034efjiabin};
74817729095966c338615a8a791d2dbf774fc034efjiabin// Array of all AAC formats. When AAC is enabled by users, all AAC formats should be enabled.
75817729095966c338615a8a791d2dbf774fc034efjiabinstatic const audio_format_t AAC_FORMATS[] = {
76817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_AAC_LC,
77817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_AAC_HE_V1,
78817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_AAC_HE_V2,
79817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_AAC_ELD,
80817729095966c338615a8a791d2dbf774fc034efjiabin    AUDIO_FORMAT_AAC_XHE,
81817729095966c338615a8a791d2dbf774fc034efjiabin};
82817729095966c338615a8a791d2dbf774fc034efjiabin
83e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
84e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AudioPolicyInterface implementation
85e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
86e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
87e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
88e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                      audio_policy_dev_state_t state,
89e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                      const char *device_address,
90e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                      const char *device_name)
91e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
92a7b4379046aca7ff9e08dc5f62ef0888423d6cc5jiabin    status_t status = setDeviceConnectionStateInt(device, state, device_address, device_name);
93a7b4379046aca7ff9e08dc5f62ef0888423d6cc5jiabin    nextAudioPortGeneration();
94a7b4379046aca7ff9e08dc5f62ef0888423d6cc5jiabin    return status;
95c73ca6ef04136f28306784ad35f444538f081957Eric Laurent}
96c73ca6ef04136f28306784ad35f444538f081957Eric Laurent
9744481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffievoid AudioPolicyManager::broadcastDeviceConnectionState(audio_devices_t device,
9844481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                                                        audio_policy_dev_state_t state,
9944481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                                                        const String8 &device_address)
10044481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie{
10144481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie    AudioParameter param(device_address);
10244481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie    const String8 key(state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE ?
103388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect);
10444481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie    param.addInt(key, device);
10544481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie    mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
10644481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie}
10744481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie
108c73ca6ef04136f28306784ad35f444538f081957Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
109a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent                                                         audio_policy_dev_state_t state,
110e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                         const char *device_address,
111e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                         const char *device_name)
112c73ca6ef04136f28306784ad35f444538f081957Eric Laurent{
113e743a47f445f02a0612018fa5640301304844fbfPaul McLean    ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
1147e22e94d0654d7ab4c31aee7f7120542e358a5abMikhail Naganov            device, state, device_address, device_name);
115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // connect/disconnect only 1 device at a time
117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
11953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    sp<DeviceDescriptor> devDesc =
12053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            mHwModules.getDeviceDescriptor(device, device_address, device_name);
121e743a47f445f02a0612018fa5640301304844fbfPaul McLean
122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle output devices
123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_output_device(device)) {
124d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        SortedVector <audio_io_handle_t> outputs;
125d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
1263a4311c68348f728558e87b5db67d47605783890Eric Laurent        ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
1273a4311c68348f728558e87b5db67d47605783890Eric Laurent
128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // save a copy of the opened output descriptors before any output is opened or closed
129e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mPreviousOutputs = mOutputs;
131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        switch (state)
132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle output device connection
1343ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
1353a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device already connected: %x", device);
137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setDeviceConnectionState() connecting device %x", device);
140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // register new device as available
1423a4311c68348f728558e87b5db67d47605783890Eric Laurent            index = mAvailableOutputDevices.add(devDesc);
1433a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
14453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                sp<HwModule> module = mHwModules.getModuleForDevice(device);
145cf817a2330936947df94c11859f48771f5596a59Eric Laurent                if (module == 0) {
146cf817a2330936947df94c11859f48771f5596a59Eric Laurent                    ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
147cf817a2330936947df94c11859f48771f5596a59Eric Laurent                          device);
148cf817a2330936947df94c11859f48771f5596a59Eric Laurent                    mAvailableOutputDevices.remove(devDesc);
149cf817a2330936947df94c11859f48771f5596a59Eric Laurent                    return INVALID_OPERATION;
150cf817a2330936947df94c11859f48771f5596a59Eric Laurent                }
151e743a47f445f02a0612018fa5640301304844fbfPaul McLean                mAvailableOutputDevices[index]->attach(module);
1523a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
1533a4311c68348f728558e87b5db67d47605783890Eric Laurent                return NO_MEMORY;
154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
15644481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            // Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
15744481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            // parameters on newly connected devices (instead of opening the outputs...)
15844481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
15944481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie
160a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent            if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
1610fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                mAvailableOutputDevices.remove(devDesc);
16244481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie
16344481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
16444481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                                               devDesc->mAddress);
1650fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                return INVALID_OPERATION;
1660fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            }
1672110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
1682110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
1692110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
1700fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            // outputs should never be empty here
1710fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
1720fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    "checkOutputsForDevice() returned no outputs but status OK");
1730fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
1740fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                  outputs.size());
1753ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent
1763ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent            } break;
177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle output device disconnection
1783b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
1793a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index < 0) {
180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device not connected: %x", device);
181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1845c477aa6205e2ebafec237411900d89a510cc105Paul McLean            ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
1855c477aa6205e2ebafec237411900d89a510cc105Paul McLean
186e743a47f445f02a0612018fa5640301304844fbfPaul McLean            // Send Disconnect to HALs
18744481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
1885c477aa6205e2ebafec237411900d89a510cc105Paul McLean
189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // remove device from available output devices
1903a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.remove(devDesc);
1913a4311c68348f728558e87b5db67d47605783890Eric Laurent
192a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent            checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
1932110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
1942110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
1952110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } break;
197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("setDeviceConnectionState() invalid state: %x", state);
200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2033a4311c68348f728558e87b5db67d47605783890Eric Laurent        // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
2043a4311c68348f728558e87b5db67d47605783890Eric Laurent        // output is suspended before any tracks are moved to it
205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkA2dpSuspend();
206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkOutputForAllStrategies();
207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // outputs must be closed after checkOutputForAllStrategies() is executed
208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputs.isEmpty()) {
209cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov            for (audio_io_handle_t output : outputs) {
210cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // close unused outputs after device disconnection or direct outputs that have been
212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // opened by checkOutputsForDevice() to query dynamic parameters
2133b73df74357b33869b39a1d69427673c780bd805Eric Laurent                if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                         (desc->mDirectOpenCount == 0))) {
216cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                    closeOutput(output);
217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2193a4311c68348f728558e87b5db67d47605783890Eric Laurent            // check again after closing A2DP output to reset mA2dpSuspended if needed
2203a4311c68348f728558e87b5db67d47605783890Eric Laurent            checkA2dpSuspend();
221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        updateDevicesAndOutputs();
22487ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
225c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
226c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            updateCallRouting(newDevice);
227c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
229c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
230c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
231c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
232c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                // do not force device change on duplicated output because if device is 0, it will
233c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                // also force a device 0 for the two outputs it is duplicated to which may override
234c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                // a valid device selection on those outputs.
235c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                bool force = !desc->isDuplicated()
23653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                        && (!device_distinguishes_on_address(device)
237c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                // always force when disconnecting (a non-duplicated device)
238c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
239c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setOutputDevice(desc, newDevice, force, 0);
240c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            }
241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
243d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
244d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            cleanUpForDevice(devDesc);
245d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
246d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
24772aa32f7dbbfb658097930b57659d8e50f24a953Eric Laurent        mpClientInterface->onAudioPortListUpdate();
248b71e58b64cd4992355cf6afaf3f3530f723bc72cEric Laurent        return NO_ERROR;
249d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }  // end if is output device
250d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle input devices
252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_input_device(device)) {
253d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        SortedVector <audio_io_handle_t> inputs;
254d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2553a4311c68348f728558e87b5db67d47605783890Eric Laurent        ssize_t index = mAvailableInputDevices.indexOf(devDesc);
256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        switch (state)
257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle input device connection
2593b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
2603a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device already connected: %d", device);
262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
26453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<HwModule> module = mHwModules.getModuleForDevice(device);
2656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (module == NULL) {
2666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
2676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                      device);
2686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
2696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
27044481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie
27144481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            // Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
27244481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            // parameters on newly connected devices (instead of opening the inputs...)
27344481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
27444481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie
2759080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean            if (checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress) != NO_ERROR) {
27644481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
27744481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                                               devDesc->mAddress);
278d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                return INVALID_OPERATION;
279d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
280d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2813a4311c68348f728558e87b5db67d47605783890Eric Laurent            index = mAvailableInputDevices.add(devDesc);
2823a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
283e743a47f445f02a0612018fa5640301304844fbfPaul McLean                mAvailableInputDevices[index]->attach(module);
2843a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
2853a4311c68348f728558e87b5db67d47605783890Eric Laurent                return NO_MEMORY;
2863a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
2873ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent
2882110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
2892110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
290d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } break;
291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle input device disconnection
2933b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
2943a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index < 0) {
295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device not connected: %d", device);
296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2985c477aa6205e2ebafec237411900d89a510cc105Paul McLean
2995c477aa6205e2ebafec237411900d89a510cc105Paul McLean            ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
3005c477aa6205e2ebafec237411900d89a510cc105Paul McLean
3015c477aa6205e2ebafec237411900d89a510cc105Paul McLean            // Set Disconnect to HALs
30244481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
3035c477aa6205e2ebafec237411900d89a510cc105Paul McLean
3049080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean            checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress);
3053a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.remove(devDesc);
3065c477aa6205e2ebafec237411900d89a510cc105Paul McLean
3072110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
3082110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
309d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } break;
310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("setDeviceConnectionState() invalid state: %x", state);
313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
316d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        closeAllInputs();
3175f5fca540ce22d2f9caff1c823b2d5b637904729Eric Laurent        // As the input device list can impact the output device selection, update
3185f5fca540ce22d2f9caff1c823b2d5b637904729Eric Laurent        // getDeviceForStrategy() cache
3195f5fca540ce22d2f9caff1c823b2d5b637904729Eric Laurent        updateDevicesAndOutputs();
320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
32187ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
322c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
323c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            updateCallRouting(newDevice);
324c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
325c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
326d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
327d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            cleanUpForDevice(devDesc);
328d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
329d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
330b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mpClientInterface->onAudioPortListUpdate();
331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
332d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } // end if is input device
333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW("setDeviceConnectionState() invalid device: %x", device);
335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return BAD_VALUE;
336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
338e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
33953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                                      const char *device_address)
340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
341634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    sp<DeviceDescriptor> devDesc =
342634b71478742310960f3fdb4241e70a0735712c4Eric Laurent            mHwModules.getDeviceDescriptor(device, device_address, "",
343634b71478742310960f3fdb4241e70a0735712c4Eric Laurent                                           (strlen(device_address) != 0)/*matchAddress*/);
344634b71478742310960f3fdb4241e70a0735712c4Eric Laurent
345634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    if (devDesc == 0) {
346634b71478742310960f3fdb4241e70a0735712c4Eric Laurent        ALOGW("getDeviceConnectionState() undeclared device, type %08x, address: %s",
347634b71478742310960f3fdb4241e70a0735712c4Eric Laurent              device, device_address);
348634b71478742310960f3fdb4241e70a0735712c4Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
349634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    }
35053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
3513a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceVector *deviceVector;
3523a4311c68348f728558e87b5db67d47605783890Eric Laurent
353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_output_device(device)) {
3543a4311c68348f728558e87b5db67d47605783890Eric Laurent        deviceVector = &mAvailableOutputDevices;
355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (audio_is_input_device(device)) {
3563a4311c68348f728558e87b5db67d47605783890Eric Laurent        deviceVector = &mAvailableInputDevices;
3573a4311c68348f728558e87b5db67d47605783890Eric Laurent    } else {
3583a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGW("getDeviceConnectionState() invalid device type %08x", device);
3593a4311c68348f728558e87b5db67d47605783890Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
361634b71478742310960f3fdb4241e70a0735712c4Eric Laurent
362634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    return (deviceVector->getDevice(device, String8(device_address)) != 0) ?
363634b71478742310960f3fdb4241e70a0735712c4Eric Laurent            AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
364a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent}
365a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent
366f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavovstatus_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device,
367f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                                      const char *device_address,
368f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                                      const char *device_name)
369f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov{
370f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    status_t status;
3713432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata    String8 reply;
3723432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata    AudioParameter param;
3733432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata    int isReconfigA2dpSupported = 0;
374f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
375f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s",
376f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov          device, device_address, device_name);
377f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
378c694ff449bef4ca1e45a6506f34e66c613757311Pavlin Radoslavov    // connect/disconnect only 1 device at a time
379c694ff449bef4ca1e45a6506f34e66c613757311Pavlin Radoslavov    if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
380c694ff449bef4ca1e45a6506f34e66c613757311Pavlin Radoslavov
381f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    // Check if the device is currently connected
382f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    sp<DeviceDescriptor> devDesc =
383f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov            mHwModules.getDeviceDescriptor(device, device_address, device_name);
384f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
385f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    if (index < 0) {
386f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        // Nothing to do: device is not connected
387f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        return NO_ERROR;
388f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    }
389f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
3903432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata    // For offloaded A2DP, Hw modules may have the capability to
3913432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata    // configure codecs. Check if any of the loaded hw modules
3923432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata    // supports this.
3933432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata    // If supported, send a set parameter to configure A2DP codecs
3943432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata    // and return. No need to toggle device state.
3953432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata    if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
3963432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata        reply = mpClientInterface->getParameters(
3973432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata                    AUDIO_IO_HANDLE_NONE,
3983432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata                    String8(AudioParameter::keyReconfigA2dpSupported));
3993432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata        AudioParameter repliedParameters(reply);
4003432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata        repliedParameters.getInt(
4013432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata                String8(AudioParameter::keyReconfigA2dpSupported), isReconfigA2dpSupported);
4023432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata        if (isReconfigA2dpSupported) {
4033432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata            const String8 key(AudioParameter::keyReconfigA2dp);
4043432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata            param.add(key, String8("true"));
4053432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata            mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
4063432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata            return NO_ERROR;
4073432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata        }
4083432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata    }
4093432e0439d3b09756f125dfa734951c654d63bafAniket Kumar Lata
410f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    // Toggle the device state: UNAVAILABLE -> AVAILABLE
411f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    // This will force reading again the device configuration
412f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    status = setDeviceConnectionState(device,
413f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                      AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
414f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                      device_address, device_name);
415f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    if (status != NO_ERROR) {
416f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        ALOGW("handleDeviceConfigChange() error disabling connection state: %d",
417f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov              status);
418f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        return status;
419f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    }
420f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
421f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    status = setDeviceConnectionState(device,
422f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                      AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
423f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                      device_address, device_name);
424f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    if (status != NO_ERROR) {
425f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        ALOGW("handleDeviceConfigChange() error enabling connection state: %d",
426f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov              status);
427f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        return status;
428f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    }
429f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
430f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    return NO_ERROR;
431f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov}
432f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
433dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurentuint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs)
434c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent{
435c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    bool createTxPatch = false;
436dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    uint32_t muteWaitMs = 0;
437c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
438a76c7de622e6e29f8559921d8d2e9ef93eb37d1fAndy Hung    if(!hasPrimaryOutput() || mPrimaryOutput->device() == AUDIO_DEVICE_OUT_STUB) {
439dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        return muteWaitMs;
44087ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    }
441c73ca6ef04136f28306784ad35f444538f081957Eric Laurent    audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
442c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice);
443c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
444c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // release existing RX patch if any
445c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    if (mCallRxPatch != 0) {
446c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
447c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mCallRxPatch.clear();
448c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
449c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // release TX patch if any
450c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    if (mCallTxPatch != 0) {
451c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
452c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mCallTxPatch.clear();
453c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
454c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
455c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // If the RX device is on the primary HW module, then use legacy routing method for voice calls
456c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // via setOutputDevice() on primary output.
457c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // Otherwise, create two audio patches for TX and RX path.
458c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    if (availablePrimaryOutputDevices() & rxDevice) {
459dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        muteWaitMs = setOutputDevice(mPrimaryOutput, rxDevice, true, delayMs);
460c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // If the TX device is also on the primary HW module, setOutputDevice() will take care
461c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // of it due to legacy implementation. If not, create a patch.
462c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        if ((availablePrimaryInputDevices() & txDevice & ~AUDIO_DEVICE_BIT_IN)
463c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                == AUDIO_DEVICE_NONE) {
464c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            createTxPatch = true;
465c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
4668ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    } else { // create RX path audio patch
467b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        mCallRxPatch = createTelephonyPatch(true /*isRx*/, rxDevice, delayMs);
468c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        createTxPatch = true;
469c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
4708ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    if (createTxPatch) { // create TX path audio patch
471b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        mCallTxPatch = createTelephonyPatch(false /*isRx*/, txDevice, delayMs);
472b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    }
473b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov
474b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    return muteWaitMs;
475b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov}
476c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
477b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganovsp<AudioPatch> AudioPolicyManager::createTelephonyPatch(
478b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        bool isRx, audio_devices_t device, uint32_t delayMs) {
479b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    struct audio_patch patch;
480b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    patch.num_sources = 1;
481b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    patch.num_sinks = 1;
482b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov
483b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    sp<DeviceDescriptor> txSourceDeviceDesc;
484b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    if (isRx) {
485b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        fillAudioPortConfigForDevice(mAvailableOutputDevices, device, &patch.sinks[0]);
486b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        fillAudioPortConfigForDevice(
487b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov                mAvailableInputDevices, AUDIO_DEVICE_IN_TELEPHONY_RX, &patch.sources[0]);
488b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    } else {
489b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        txSourceDeviceDesc = fillAudioPortConfigForDevice(
490b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov                mAvailableInputDevices, device, &patch.sources[0]);
491b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        fillAudioPortConfigForDevice(
492b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov                mAvailableOutputDevices, AUDIO_DEVICE_OUT_TELEPHONY_TX, &patch.sinks[0]);
493b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    }
494b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov
495b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    audio_devices_t outputDevice = isRx ? device : AUDIO_DEVICE_OUT_TELEPHONY_TX;
496b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(outputDevice, mOutputs);
497b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
498b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    // request to reuse existing output stream if one is already opened to reach the target device
499b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    if (output != AUDIO_IO_HANDLE_NONE) {
500b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
501b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        ALOG_ASSERT(!outputDesc->isDuplicated(),
502b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov                "%s() %#x device output %d is duplicated", __func__, outputDevice, output);
503b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        outputDesc->toAudioPortConfig(&patch.sources[1]);
504b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
505b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        patch.num_sources = 2;
506b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    }
507b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov
508b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    if (!isRx) {
509c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // terminate active capture if on the same HW module as the call TX source device
510c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // FIXME: would be better to refine to only inputs whose profile connects to the
511c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // call TX device but this information is not in the audio patch and logic here must be
512c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // symmetric to the one in startInput()
513cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        for (const auto& activeDesc : mInputs.getActiveInputs()) {
514fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            if (activeDesc->hasSameHwModuleAs(txSourceDeviceDesc)) {
515fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                AudioSessionCollection activeSessions =
516fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                        activeDesc->getAudioSessions(true /*activeOnly*/);
517fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                for (size_t j = 0; j < activeSessions.size(); j++) {
518fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                    audio_session_t activeSession = activeSessions.keyAt(j);
519fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                    stopInput(activeDesc->mIoHandle, activeSession);
520fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                    releaseInput(activeDesc->mIoHandle, activeSession);
521fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                }
522c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent            }
523c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        }
524b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    }
525c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent
526b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
527b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    status_t status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
528b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    ALOGW_IF(status != NO_ERROR,
529b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov            "%s() error %d creating %s audio patch", __func__, status, isRx ? "RX" : "TX");
530b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    sp<AudioPatch> audioPatch;
531b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    if (status == NO_ERROR) {
532b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        audioPatch = new AudioPatch(&patch, mUidCached);
533b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        audioPatch->mAfPatchHandle = afPatchHandle;
534b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        audioPatch->mUid = mUidCached;
535c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
536b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    return audioPatch;
537b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov}
538dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
539b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganovsp<DeviceDescriptor> AudioPolicyManager::fillAudioPortConfigForDevice(
540b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov        const DeviceVector& devices, audio_devices_t device, audio_port_config *config) {
541b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    DeviceVector deviceList = devices.getDevicesFromType(device);
542b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    ALOG_ASSERT(!deviceList.isEmpty(),
543b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov            "%s() selected device type %#x is not in devices list", __func__, device);
544b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    sp<DeviceDescriptor> deviceDesc = deviceList.itemAt(0);
545b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    deviceDesc->toAudioPortConfig(config);
546b567ba06331aeac314f74c87f2e7b9badb4d6518Mikhail Naganov    return deviceDesc;
547c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent}
548c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
549e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setPhoneState(audio_mode_t state)
550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setPhoneState() state %d", state);
5522110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    // store previous phone state for management of sonification strategy below
5532110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    int oldState = mEngine->getPhoneState();
554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5552110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->setPhoneState(state) != NO_ERROR) {
5562110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        ALOGW("setPhoneState() invalid or same state %d", state);
557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5592110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    /// Opens: can these line be executed after the switch of volume curves???
560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if leaving call state, handle special case of active streams
561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // pertaining to sonification strategy see handleIncallSonification()
56263dea1d5334acf3baa9448086dd504ead57d814bEric Laurent    if (isStateInCall(oldState)) {
563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setPhoneState() in call state management: new state is %d", state);
564794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
5653b73df74357b33869b39a1d69427673c780bd805Eric Laurent            handleIncallSonification((audio_stream_type_t)stream, false, true);
566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5672cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent
56863dea1d5334acf3baa9448086dd504ead57d814bEric Laurent        // force reevaluating accessibility routing when call stops
5692cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5722110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    /**
5732110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie     * Switching to or from incall state or switching between telephony and VoIP lead to force
5742110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie     * routing command.
5752110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie     */
5762110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    bool force = ((is_state_in_call(oldState) != is_state_in_call(state))
5772110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                  || (is_state_in_call(state) && (state != oldState)));
578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check for device and output changes triggered by new phone state
580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkA2dpSuspend();
581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForAllStrategies();
582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int delayMs = 0;
585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(state)) {
586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        nsecs_t sysTime = systemTime();
587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
588c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // mute media and sonification strategies and delay device switch by the largest
590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // latency of any output where either strategy is active.
591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // This avoid sending the ring tone or music tail into the earpiece or headset.
592ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie            if ((isStrategyActive(desc, STRATEGY_MEDIA,
593ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  SONIFICATION_HEADSET_MUSIC_DELAY,
594ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  sysTime) ||
595ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                 isStrategyActive(desc, STRATEGY_SONIFICATION,
596ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  SONIFICATION_HEADSET_MUSIC_DELAY,
597ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  sysTime)) &&
598c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    (delayMs < (int)desc->latency()*2)) {
599c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                delayMs = desc->latency()*2;
600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
601c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_MEDIA, true, desc);
602c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
604c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_SONIFICATION, true, desc);
605c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
61087ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    if (hasPrimaryOutput()) {
61187ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // Note that despite the fact that getNewOutputDevice() is called on the primary output,
61287ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // the device returned is not necessarily reachable via this output
61387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
61487ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // force routing command to audio hardware when ending call
61587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // even if no device change is needed
61687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
61787ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            rxDevice = mPrimaryOutput->device();
618c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
61987ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent
62087ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (state == AUDIO_MODE_IN_CALL) {
62187ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            updateCallRouting(rxDevice, delayMs);
62287ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        } else if (oldState == AUDIO_MODE_IN_CALL) {
62387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            if (mCallRxPatch != 0) {
62487ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
62587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mCallRxPatch.clear();
62687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            }
62787ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            if (mCallTxPatch != 0) {
62887ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
62987ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mCallTxPatch.clear();
63087ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            }
63187ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
63287ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        } else {
63387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
634c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
635c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
6362e2a8a993de1aa65a7e174ee1152240779350456Eric Laurent
6372e2a8a993de1aa65a7e174ee1152240779350456Eric Laurent    // reevaluate routing on all outputs in case tracks have been started during the call
6382e2a8a993de1aa65a7e174ee1152240779350456Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
6392e2a8a993de1aa65a7e174ee1152240779350456Eric Laurent        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
6402e2a8a993de1aa65a7e174ee1152240779350456Eric Laurent        audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
6412e2a8a993de1aa65a7e174ee1152240779350456Eric Laurent        if (state != AUDIO_MODE_IN_CALL || desc != mPrimaryOutput) {
642f60c824b23de449d3e31e69d5b91e3dba83067b1Yung Ti Su            setOutputDevice(desc, newDevice, (newDevice != AUDIO_DEVICE_NONE), 0 /*delayMs*/);
6432e2a8a993de1aa65a7e174ee1152240779350456Eric Laurent        }
6442e2a8a993de1aa65a7e174ee1152240779350456Eric Laurent    }
6452e2a8a993de1aa65a7e174ee1152240779350456Eric Laurent
646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if entering in call state, handle special case of active streams
647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // pertaining to sonification strategy see handleIncallSonification()
648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(state)) {
649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setPhoneState() in call state management: new state is %d", state);
650794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
6513b73df74357b33869b39a1d69427673c780bd805Eric Laurent            handleIncallSonification((audio_stream_type_t)stream, true, true);
652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
65363dea1d5334acf3baa9448086dd504ead57d814bEric Laurent
65463dea1d5334acf3baa9448086dd504ead57d814bEric Laurent        // force reevaluating accessibility routing when call starts
65563dea1d5334acf3baa9448086dd504ead57d814bEric Laurent        mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
6593b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state == AUDIO_MODE_RINGTONE &&
6603b73df74357b33869b39a1d69427673c780bd805Eric Laurent        isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mLimitRingtoneVolume = true;
662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mLimitRingtoneVolume = false;
664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
667887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Triviaudio_mode_t AudioPolicyManager::getPhoneState() {
668887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Trivi    return mEngine->getPhoneState();
669887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Trivi}
670887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Trivi
671e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
6723b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                         audio_policy_forced_cfg_t config)
673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
6742110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mEngine->getPhoneState());
6758dc87a60e69f462e0382d025c335e45699025b48Eric Laurent    if (config == mEngine->getForceUse(usage)) {
6768dc87a60e69f462e0382d025c335e45699025b48Eric Laurent        return;
6778dc87a60e69f462e0382d025c335e45699025b48Eric Laurent    }
6782110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
6792110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->setForceUse(usage, config) != NO_ERROR) {
6802110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        ALOGW("setForceUse() could not set force cfg %d for usage %d", config, usage);
6812110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        return;
682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
6832110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    bool forceVolumeReeval = (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ||
6842110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            (usage == AUDIO_POLICY_FORCE_FOR_DOCK) ||
6852110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM);
686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check for device and output changes triggered by new force usage
688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkA2dpSuspend();
689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForAllStrategies();
690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
69109bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
692dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    //FIXME: workaround for truncated touch sounds
693dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    // to be removed when the problem is handled by system UI
694dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    uint32_t delayMs = 0;
695dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    uint32_t waitMs = 0;
696dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    if (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) {
697dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        delayMs = TOUCH_SOUND_FIXED_DELAY_MS;
698dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    }
69987ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
700c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
701dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        waitMs = updateCallRouting(newDevice, delayMs);
702c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
704c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
705c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        audio_devices_t newDevice = getNewOutputDevice(outputDesc, true /*fromCache*/);
706c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
707dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            waitMs = setOutputDevice(outputDesc, newDevice, (newDevice != AUDIO_DEVICE_NONE),
708dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                                     delayMs);
709c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
711dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            applyStreamVolumes(outputDesc, newDevice, waitMs, true);
712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
715cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    for (const auto& activeDesc : mInputs.getActiveInputs()) {
716fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        audio_devices_t newDevice = getNewInputDevice(activeDesc);
717c171c7c47d099a52ade95c3c8d8907bf09bb88faEric Laurent        // Force new input selection if the new device can not be reached via current input
718fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        if (activeDesc->mProfile->getSupportedDevices().types() &
719fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
720fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            setInputDevice(activeDesc->mIoHandle, newDevice);
721c171c7c47d099a52ade95c3c8d8907bf09bb88faEric Laurent        } else {
722fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            closeInput(activeDesc->mIoHandle);
723c171c7c47d099a52ade95c3c8d8907bf09bb88faEric Laurent        }
724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
727e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setSystemProperty(const char* property, const char* value)
728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setSystemProperty() property %s, value %s", property, value);
730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Find a direct output profile compatible with the parameters passed, even if the input flags do
733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// not explicitly request a direct output
73456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivisp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_devices_t device,
736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               uint32_t samplingRate,
737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_format_t format,
738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_channel_mask_t channelMask,
739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_output_flags_t flags)
740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
741861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    // only retain flags that will drive the direct output profile selection
742861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    // if explicitly requested
743861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    static const uint32_t kRelevantFlags =
74484c621e937c82c25b5b6d633edee17616e08a61aHaynes Mathew George            (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
74584c621e937c82c25b5b6d633edee17616e08a61aHaynes Mathew George             AUDIO_OUTPUT_FLAG_VOIP_RX);
746861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    flags =
747861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
748861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent
749861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    sp<IOProfile> profile;
750861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent
751d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov    for (const auto& hwModule : mHwModules) {
752a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov        for (const auto& curProfile : hwModule->getOutputProfiles()) {
753861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            if (!curProfile->isCompatibleProfile(device, String8(""),
754f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                    samplingRate, NULL /*updatedSamplingRate*/,
755f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                    format, NULL /*updatedFormat*/,
756f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                    channelMask, NULL /*updatedChannelMask*/,
757861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                    flags)) {
758861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                continue;
759861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            }
760861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            // reject profiles not corresponding to a device currently available
761a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((mAvailableOutputDevices.types() & curProfile->getSupportedDevicesType()) == 0) {
762861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                continue;
763861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            }
764861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            // if several profiles are compatible, give priority to one with offload capability
765a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (profile != 0 && ((curProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0)) {
766861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                continue;
767861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            }
768861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            profile = curProfile;
769a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((profile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
770861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                break;
7713a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
774861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    return profile;
775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
777f4e63452b37c799c9387a6a88b46e6191f6a5f7eEric Laurentaudio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream)
778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
7793b73df74357b33869b39a1d69427673c780bd805Eric Laurent    routing_strategy strategy = getStrategy(stream);
780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
781c990152585f6b654ffe7e1dbff483d4ecddc019bAndy Hung
782c990152585f6b654ffe7e1dbff483d4ecddc019bAndy Hung    // Note that related method getOutputForAttr() uses getOutputForDevice() not selectOutput().
783c990152585f6b654ffe7e1dbff483d4ecddc019bAndy Hung    // We use selectOutput() here since we don't have the desired AudioTrack sample rate,
784c990152585f6b654ffe7e1dbff483d4ecddc019bAndy Hung    // format, flags, etc. This may result in some discrepancy for functions that utilize
785c990152585f6b654ffe7e1dbff483d4ecddc019bAndy Hung    // getOutput() solely on audio_stream_type such as AudioSystem::getOutputFrameCount()
786c990152585f6b654ffe7e1dbff483d4ecddc019bAndy Hung    // and AudioSystem::getOutputSamplingRate().
787c990152585f6b654ffe7e1dbff483d4ecddc019bAndy Hung
788f4e63452b37c799c9387a6a88b46e6191f6a5f7eEric Laurent    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
789f4e63452b37c799c9387a6a88b46e6191f6a5f7eEric Laurent    audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
791f4e63452b37c799c9387a6a88b46e6191f6a5f7eEric Laurent    ALOGV("getOutput() stream %d selected device %08x, output %d", stream, device, output);
792f4e63452b37c799c9387a6a88b46e6191f6a5f7eEric Laurent    return output;
793e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent}
794e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
795e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentstatus_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
796e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_io_handle_t *output,
797e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_session_t session,
798e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_stream_type_t *stream,
7998c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                              uid_t uid,
80020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                              const audio_config_t *config,
801766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar                                              audio_output_flags_t *flags,
8022ac7694396640821f6723672e25b2372220bf060Eric Laurent                                              audio_port_handle_t *selectedDeviceId,
80320b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                              audio_port_handle_t *portId)
804e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent{
805e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    audio_attributes_t attributes;
806e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if (attr != NULL) {
807e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        if (!isValidAttributes(attr)) {
808e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
809e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                  attr->usage, attr->content_type, attr->flags,
810e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                  attr->tags);
811e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            return BAD_VALUE;
812e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        }
813e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        attributes = *attr;
814e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    } else {
815e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) {
816e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            ALOGE("getOutputForAttr():  invalid stream type");
817e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            return BAD_VALUE;
818e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        }
819e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        stream_type_to_audio_attributes(*stream, &attributes);
8205bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
82120b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent
82220b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    // TODO: check for existing client for this port ID
82320b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    if (*portId == AUDIO_PORT_HANDLE_NONE) {
82420b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent        *portId = AudioPort::getNextUniqueId();
82520b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    }
82620b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent
827c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> desc;
828e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi    if (mPolicyMixes.getOutputForAttr(attributes, uid, desc) == NO_ERROR) {
829036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
83020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent        if (!audio_has_proportional_frames(config->format)) {
831036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie            return BAD_VALUE;
832275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
833036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        *stream = streamTypefromAttributesInt(&attributes);
834036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        *output = desc->mIoHandle;
835036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        ALOGV("getOutputForAttr() returns output %d", *output);
836036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        return NO_ERROR;
837275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
838275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
839275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
840275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        return BAD_VALUE;
841275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
842275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
8438c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x"
8448c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            " session %d selectedDeviceId %d",
8458c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            attributes.usage, attributes.content_type, attributes.tags, attributes.flags,
8462ac7694396640821f6723672e25b2372220bf060Eric Laurent            session, *selectedDeviceId);
8478c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
8488c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    *stream = streamTypefromAttributesInt(&attributes);
8498c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
8508c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // Explicit routing?
8518c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    sp<DeviceDescriptor> deviceDesc;
8522ac7694396640821f6723672e25b2372220bf060Eric Laurent    if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
853cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        deviceDesc = mAvailableOutputDevices.getDeviceFromId(*selectedDeviceId);
8548c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
8558c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc, uid);
8565bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
857e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);
8585bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
85993c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent
860e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
861766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
86293c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent    }
86393c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent
86449f36ba3b4624ddd3d7efa34c95128a73bda6208Glenn Kasten    ALOGV("getOutputForAttr() device 0x%x, sampling rate %d, format %#x, channel mask %#x, "
86549f36ba3b4624ddd3d7efa34c95128a73bda6208Glenn Kasten          "flags %#x",
866766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar          device, config->sample_rate, config->format, config->channel_mask, *flags);
8675bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
868c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung    *output = getOutputForDevice(device, session, *stream, config, flags);
869e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if (*output == AUDIO_IO_HANDLE_NONE) {
8708c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        mOutputRoutes.removeRoute(session);
871e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        return INVALID_OPERATION;
872e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
873aa9811945f575614b3482d09e4d969792701cebbPaul McLean
8742ac7694396640821f6723672e25b2372220bf060Eric Laurent    DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromType(device);
8752ac7694396640821f6723672e25b2372220bf060Eric Laurent    *selectedDeviceId = outputDevices.size() > 0 ? outputDevices.itemAt(0)->getId()
8762ac7694396640821f6723672e25b2372220bf060Eric Laurent            : AUDIO_PORT_HANDLE_NONE;
8772ac7694396640821f6723672e25b2372220bf060Eric Laurent
8782ac7694396640821f6723672e25b2372220bf060Eric Laurent    ALOGV("  getOutputForAttr() returns output %d selectedDeviceId %d", *output, *selectedDeviceId);
8792ac7694396640821f6723672e25b2372220bf060Eric Laurent
880e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    return NO_ERROR;
8815bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi}
8825bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
8835bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_io_handle_t AudioPolicyManager::getOutputForDevice(
8845bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_devices_t device,
885169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard        audio_session_t session,
8865bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_stream_type_t stream,
887fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        const audio_config_t *config,
888766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        audio_output_flags_t *flags)
8895bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{
890c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung    audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
891cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    status_t status;
8925bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open a direct output if required by specified parameters
894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //force direct flag if offload flag is set: offloading implies a direct output stream
895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and all common behaviors are driven by checking only the direct flag
896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // this should normally be set appropriately in the policy configuration file
897766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar    if ((*flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
898766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_DIRECT);
899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
900766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar    if ((*flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
901766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_DIRECT);
90293c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent    }
903e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    // only allow deep buffering for music stream type
904e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if (stream != AUDIO_STREAM_MUSIC) {
905766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        *flags = (audio_output_flags_t)(*flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
906439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda    } else if (/* stream == AUDIO_STREAM_MUSIC && */
907766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar            *flags == AUDIO_OUTPUT_FLAG_NONE &&
908439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda            property_get_bool("audio.deep_buffer.media", false /* default_value */)) {
909439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda        // use DEEP_BUFFER as default output for music stream type
910766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        *flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
911e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
912c36a8897ff877f4c5b2e0580830faef8b87dd74aRavi Kumar Alamanda    if (stream == AUDIO_STREAM_TTS) {
913766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        *flags = AUDIO_OUTPUT_FLAG_TTS;
91484c621e937c82c25b5b6d633edee17616e08a61aHaynes Mathew George    } else if (stream == AUDIO_STREAM_VOICE_CALL &&
915fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent               audio_is_linear_pcm(config->format)) {
916766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        *flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_VOIP_RX |
91784c621e937c82c25b5b6d633edee17616e08a61aHaynes Mathew George                                       AUDIO_OUTPUT_FLAG_DIRECT);
91884c621e937c82c25b5b6d633edee17616e08a61aHaynes Mathew George        ALOGV("Set VoIP and Direct output flags for PCM format");
919766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar    } else if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
920766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        stream == AUDIO_STREAM_MUSIC &&
921766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        audio_is_linear_pcm(config->format) &&
922766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        isInCall()) {
923766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        *flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
924c36a8897ff877f4c5b2e0580830faef8b87dd74aRavi Kumar Alamanda    }
925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
926766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar
927b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent    sp<IOProfile> profile;
928b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent
929b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent    // skip direct output selection if the request can obviously be attached to a mixed output
930c260784e37dea73a2090d4ccd91472d61d3b6230Eric Laurent    // and not explicitly requested
931766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar    if (((*flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
932fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            audio_is_linear_pcm(config->format) && config->sample_rate <= SAMPLE_RATE_HZ_MAX &&
933fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            audio_channel_count_from_out_mask(config->channel_mask) <= 2) {
934b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent        goto non_direct_output;
935b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent    }
936b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent
9372ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // Do not allow offloading if one non offloadable effect is enabled or MasterMono is enabled.
9382ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // This prevents creating an offloaded track and tearing it down immediately after start
9392ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // when audioflinger detects there is an active non offloadable effect.
940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // FIXME: We should check the audio session here but we do not have it in this context.
941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // This may prevent offloading in rare situations where effects are left active by apps
942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the background.
943b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent
944766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar    if (((*flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
9452ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            !(mEffects.isNonOffloadableEffectEnabled() || mMasterMono)) {
946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        profile = getProfileForDirectOutput(device,
947fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                           config->sample_rate,
948fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                           config->format,
949fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                           config->channel_mask,
950766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar                                           (audio_output_flags_t)*flags);
951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
9531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (profile != 0) {
954c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung        // exclusive outputs for MMAP and Offload are enforced by different session ids.
955c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung        for (size_t i = 0; i < mOutputs.size(); i++) {
956c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
957c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung            if (!desc->isDuplicated() && (profile == desc->mProfile)) {
958c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung                // reuse direct output if currently open by the same client
959c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung                // and configured with same parameters
960c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung                if ((config->sample_rate == desc->mSamplingRate) &&
9615659ed5327fbd6a412ecd65235eea68a5a59fd39Andy Hung                    (config->format == desc->mFormat) &&
962c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung                    (config->channel_mask == desc->mChannelMask) &&
963c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung                    (session == desc->mDirectClientSession)) {
964c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung                    desc->mDirectOpenCount++;
965c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung                    ALOGI("getOutputForDevice() reusing direct output %d for session %d",
966c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung                        mOutputs.keyAt(i), session);
967c88b06445e53ae806e94483a6ae8b2241fe3bf6fAndy Hung                    return mOutputs.keyAt(i);
968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
9713974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent
9723974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent        if (!profile->canOpenNewIo()) {
9733974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent            goto non_direct_output;
974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
975861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent
9763974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc =
9773974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                new SwAudioOutputDescriptor(profile, mpClientInterface);
97853b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent
97953b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent        DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromType(device);
98053b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent        String8 address = outputDevices.size() > 0 ? outputDevices.itemAt(0)->mAddress
98153b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent                : String8("");
98253b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent
983766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        status = outputDesc->open(config, device, address, stream, *flags, &output);
984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // only accept an output with the requested parameters
986cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        if (status != NO_ERROR ||
987fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            (config->sample_rate != 0 && config->sample_rate != outputDesc->mSamplingRate) ||
9885659ed5327fbd6a412ecd65235eea68a5a59fd39Andy Hung            (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->mFormat) ||
989fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            (config->channel_mask != 0 && config->channel_mask != outputDesc->mChannelMask)) {
990fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            ALOGV("getOutputForDevice() failed opening direct output: output %d sample rate %d %d,"
991fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    "format %d %d, channel mask %04x %04x", output, config->sample_rate,
992fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    outputDesc->mSamplingRate, config->format, outputDesc->mFormat,
993fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    config->channel_mask, outputDesc->mChannelMask);
994cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (output != AUDIO_IO_HANDLE_NONE) {
995fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                outputDesc->close();
996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
997a82797faddb37adb2d441737884576684c8515cbEric Laurent            // fall back to mixer output if possible when the direct output could not be open
998fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            if (audio_is_linear_pcm(config->format) &&
999fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    config->sample_rate  <= SAMPLE_RATE_HZ_MAX) {
100056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                goto non_direct_output;
100156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            }
1002cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            return AUDIO_IO_HANDLE_NONE;
1003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1004cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mRefCount[stream] = 0;
1005cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mStopTime[stream] = 0;
1006cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mDirectOpenCount = 1;
1007169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard        outputDesc->mDirectClientSession = session;
1008169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard
1009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        addOutput(output, outputDesc);
1010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mPreviousOutputs = mOutputs;
1011f4e63452b37c799c9387a6a88b46e6191f6a5f7eEric Laurent        ALOGV("getOutputForDevice() returns new direct output %d", output);
1012b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mpClientInterface->onAudioPortListUpdate();
1013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return output;
1014e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1016b732cf5af93c33fa183769210ce9954521fb68cdEric Laurentnon_direct_output:
101714cbfcae68582eca97f1a8168c584254515879eeEric Laurent
101814cbfcae68582eca97f1a8168c584254515879eeEric Laurent    // A request for HW A/V sync cannot fallback to a mixed output because time
101914cbfcae68582eca97f1a8168c584254515879eeEric Laurent    // stamps are embedded in audio data
10202d059936882d8d6b8f73dedd4f9a043bdd36405aPhil Burk    if ((*flags & (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ)) != 0) {
102114cbfcae68582eca97f1a8168c584254515879eeEric Laurent        return AUDIO_IO_HANDLE_NONE;
102214cbfcae68582eca97f1a8168c584254515879eeEric Laurent    }
102314cbfcae68582eca97f1a8168c584254515879eeEric Laurent
1024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // ignoring channel mask due to downmix capability in mixer
1025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open a non direct output
1027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // for non direct outputs, only PCM is supported
1029fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    if (audio_is_linear_pcm(config->format)) {
1030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // get which output is suitable for the specified stream. The actual
1031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // routing change will happen when startOutput() will be called
1032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
1033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
10348838a3895c365d443ee22e169ccf45956780c081Eric Laurent        // at this stage we should ignore the DIRECT flag as no direct output could be found earlier
1035766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
1036766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar        output = selectOutput(outputs, *flags, config->format);
1037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1038f4e63452b37c799c9387a6a88b46e6191f6a5f7eEric Laurent    ALOGW_IF((output == 0), "getOutputForDevice() could not find output for stream %d, "
103949f36ba3b4624ddd3d7efa34c95128a73bda6208Glenn Kasten            "sampling rate %d, format %#x, channels %#x, flags %#x",
1040766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar            stream, config->sample_rate, config->format, config->channel_mask, *flags);
1041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return output;
1043e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1045e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
10468838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                       audio_output_flags_t flags,
10478838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                       audio_format_t format)
1048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // select one output among several that provide a path to a particular device or set of
1050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // devices (the list was previously build by getOutputsForDevice()).
1051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // The priority is as follows:
1052e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: the output with the highest number of requested policy flags
1053e693002b0fb25099540588245892ed98103749baEric Laurent    // 2: the output with the bit depth the closest to the requested one
1054e693002b0fb25099540588245892ed98103749baEric Laurent    // 3: the primary output
1055e693002b0fb25099540588245892ed98103749baEric Laurent    // 4: the first output in the list
1056e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 0) {
1058cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        return AUDIO_IO_HANDLE_NONE;
1059e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1060e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 1) {
1061e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputs[0];
1062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int maxCommonFlags = 0;
1065cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    audio_io_handle_t outputForFlags = AUDIO_IO_HANDLE_NONE;
1066cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    audio_io_handle_t outputForPrimary = AUDIO_IO_HANDLE_NONE;
1067cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    audio_io_handle_t outputForFormat = AUDIO_IO_HANDLE_NONE;
1068e693002b0fb25099540588245892ed98103749baEric Laurent    audio_format_t bestFormat = AUDIO_FORMAT_INVALID;
1069e693002b0fb25099540588245892ed98103749baEric Laurent    audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID;
1070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1071cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    for (audio_io_handle_t output : outputs) {
1072cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
1073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputDesc->isDuplicated()) {
10748838a3895c365d443ee22e169ccf45956780c081Eric Laurent            // if a valid format is specified, skip output if not compatible
10758838a3895c365d443ee22e169ccf45956780c081Eric Laurent            if (format != AUDIO_FORMAT_INVALID) {
10768838a3895c365d443ee22e169ccf45956780c081Eric Laurent                if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
10775659ed5327fbd6a412ecd65235eea68a5a59fd39Andy Hung                    if (format != outputDesc->mFormat) {
10788838a3895c365d443ee22e169ccf45956780c081Eric Laurent                        continue;
10798838a3895c365d443ee22e169ccf45956780c081Eric Laurent                    }
10808838a3895c365d443ee22e169ccf45956780c081Eric Laurent                } else if (!audio_is_linear_pcm(format)) {
10818838a3895c365d443ee22e169ccf45956780c081Eric Laurent                    continue;
10828838a3895c365d443ee22e169ccf45956780c081Eric Laurent                }
1083e693002b0fb25099540588245892ed98103749baEric Laurent                if (AudioPort::isBetterFormatMatch(
1084e693002b0fb25099540588245892ed98103749baEric Laurent                        outputDesc->mFormat, bestFormat, format)) {
1085cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                    outputForFormat = output;
1086e693002b0fb25099540588245892ed98103749baEric Laurent                    bestFormat = outputDesc->mFormat;
1087e693002b0fb25099540588245892ed98103749baEric Laurent                }
10888838a3895c365d443ee22e169ccf45956780c081Eric Laurent            }
10898838a3895c365d443ee22e169ccf45956780c081Eric Laurent
1090a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            int commonFlags = popcount(outputDesc->mProfile->getFlags() & flags);
1091e693002b0fb25099540588245892ed98103749baEric Laurent            if (commonFlags >= maxCommonFlags) {
1092e693002b0fb25099540588245892ed98103749baEric Laurent                if (commonFlags == maxCommonFlags) {
1093c990152585f6b654ffe7e1dbff483d4ecddc019bAndy Hung                    if (format != AUDIO_FORMAT_INVALID
1094c990152585f6b654ffe7e1dbff483d4ecddc019bAndy Hung                            && AudioPort::isBetterFormatMatch(
1095c990152585f6b654ffe7e1dbff483d4ecddc019bAndy Hung                                    outputDesc->mFormat, bestFormatForFlags, format)) {
1096cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                        outputForFlags = output;
1097e693002b0fb25099540588245892ed98103749baEric Laurent                        bestFormatForFlags = outputDesc->mFormat;
1098e693002b0fb25099540588245892ed98103749baEric Laurent                    }
1099e693002b0fb25099540588245892ed98103749baEric Laurent                } else {
1100cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                    outputForFlags = output;
1101e693002b0fb25099540588245892ed98103749baEric Laurent                    maxCommonFlags = commonFlags;
1102e693002b0fb25099540588245892ed98103749baEric Laurent                    bestFormatForFlags = outputDesc->mFormat;
1103e693002b0fb25099540588245892ed98103749baEric Laurent                }
1104cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                ALOGV("selectOutput() commonFlags for output %d, %04x", output, commonFlags);
1105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1106a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
1107cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                outputForPrimary = output;
1108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1112cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    if (outputForFlags != AUDIO_IO_HANDLE_NONE) {
1113e693002b0fb25099540588245892ed98103749baEric Laurent        return outputForFlags;
1114e693002b0fb25099540588245892ed98103749baEric Laurent    }
1115cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    if (outputForFormat != AUDIO_IO_HANDLE_NONE) {
1116e693002b0fb25099540588245892ed98103749baEric Laurent        return outputForFormat;
1117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1118cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    if (outputForPrimary != AUDIO_IO_HANDLE_NONE) {
1119e693002b0fb25099540588245892ed98103749baEric Laurent        return outputForPrimary;
1120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1122e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs[0];
1123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1125e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startOutput(audio_io_handle_t output,
11263b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                             audio_stream_type_t stream,
1127e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                             audio_session_t session)
1128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1129aa9811945f575614b3482d09e4d969792701cebbPaul McLean    ALOGV("startOutput() output %d, stream %d, session %d",
1130aa9811945f575614b3482d09e4d969792701cebbPaul McLean          output, stream, session);
1131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
1132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("startOutput() unknown output %d", output);
1134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1137c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
1138c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1139733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent    status_t status = outputDesc->start();
1140733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent    if (status != NO_ERROR) {
1141733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        return status;
11423974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent    }
11433974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent
11448c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // Routing?
11458c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    mOutputRoutes.incRouteActivity(session);
11468c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
1147c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    audio_devices_t newDevice;
1148c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent    AudioMix *policyMix = NULL;
1149c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent    const char *address = NULL;
1150c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mPolicyMix != NULL) {
1151c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        policyMix = outputDesc->mPolicyMix;
1152c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        address = policyMix->mDeviceAddress.string();
1153c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
1154c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            newDevice = policyMix->mDeviceType;
1155c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        } else {
1156c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1157c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        }
11582157f5bc0c54a77318e75076365eff739e07056fEric Laurent    } else if (mOutputRoutes.getAndClearRouteChanged(session)) {
1159493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent        newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
1160f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent        if (newDevice != outputDesc->device()) {
1161f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent            checkStrategyRoute(getStrategy(stream), output);
1162f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent        }
1163c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    } else {
1164c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        newDevice = AUDIO_DEVICE_NONE;
1165c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1166c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1167c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    uint32_t delayMs = 0;
1168c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1169733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent    status = startSource(outputDesc, stream, newDevice, address, &delayMs);
1170c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1171c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (status != NO_ERROR) {
1172c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        mOutputRoutes.decRouteActivity(session);
1173733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        outputDesc->stop();
11748c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        return status;
1175c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1176c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // Automatically enable the remote submix input when output is started on a re routing mix
1177c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // of type MIX_TYPE_RECORDERS
1178c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent    if (audio_is_remote_submix_device(newDevice) && policyMix != NULL &&
1179c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            policyMix->mMixType == MIX_TYPE_RECORDERS) {
1180c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1181c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1182c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                    address,
1183c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    "remote-submix");
1184c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1185c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1186c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (delayMs != 0) {
1187c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        usleep(delayMs * 1000);
1188c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1189c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1190c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return status;
1191c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
1192c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1193e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t AudioPolicyManager::startSource(const sp<AudioOutputDescriptor>& outputDesc,
1194c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             audio_stream_type_t stream,
1195c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             audio_devices_t device,
1196c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                             const char *address,
1197c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             uint32_t *delayMs)
1198c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
1199d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    // cannot start playback of STREAM_TTS if any other output is being used
1200d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    uint32_t beaconMuteLatency = 0;
1201c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1202c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    *delayMs = 0;
1203d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if (stream == AUDIO_STREAM_TTS) {
1204d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        ALOGV("\t found BEACON stream");
12059459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent        if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
1206d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            return INVALID_OPERATION;
1207d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        } else {
1208d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
1209d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
1210d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    } else {
1211d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // some playback other than beacon starts
1212d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT);
1213d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
1214d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
121577305a67301c74438ee09fdb8f80b89a43712951Eric Laurent    // force device change if the output is inactive and no audio patch is already present.
12167c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent    // check active before incrementing usage count
121777305a67301c74438ee09fdb8f80b89a43712951Eric Laurent    bool force = !outputDesc->isActive() &&
121877305a67301c74438ee09fdb8f80b89a43712951Eric Laurent            (outputDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE);
12197c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent
1220b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi    // requiresMuteCheck is false when we can bypass mute strategy.
1221b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi    // It covers a common case when there is no materially active audio
1222b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi    // and muting would result in unnecessary delay and dropped audio.
1223b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi    const uint32_t outputLatencyMs = outputDesc->latency();
1224b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi    bool requiresMuteCheck = outputDesc->isActive(outputLatencyMs * 2);  // account for drain
1225b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi
1226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // increment usage count for this stream on the requested output:
1227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // NOTE that the usage count is the same for duplicated output and hardware output which is
1228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
1229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    outputDesc->changeRefCount(stream, 1);
1230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
123136829f97c0c547d9c6c918e248071cc616818616Eric Laurent    if (stream == AUDIO_STREAM_MUSIC) {
123236829f97c0c547d9c6c918e248071cc616818616Eric Laurent        selectOutputForMusicEffects();
123336829f97c0c547d9c6c918e248071cc616818616Eric Laurent    }
123436829f97c0c547d9c6c918e248071cc616818616Eric Laurent
1235493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent    if (outputDesc->mRefCount[stream] == 1 || device != AUDIO_DEVICE_NONE) {
1236275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        // starting an output being rerouted?
1237c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if (device == AUDIO_DEVICE_NONE) {
1238c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            device = getNewOutputDevice(outputDesc, false /*fromCache*/);
1239275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
124036829f97c0c547d9c6c918e248071cc616818616Eric Laurent
1241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        routing_strategy strategy = getStrategy(stream);
1242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
1243d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                            (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
1244d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                            (beaconMuteLatency > 0);
1245d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        uint32_t waitMs = beaconMuteLatency;
1246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
12471f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent            sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
1248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (desc != outputDesc) {
1249b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                // An output has a shared device if
1250b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                // - managed by the same hw module
1251b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                // - supports the currently selected device
1252b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                const bool sharedDevice = outputDesc->sharesHwModuleWith(desc)
1253b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                        && (desc->supportedDevices() & device) != AUDIO_DEVICE_NONE;
1254b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi
125577305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // force a device change if any other output is:
125677305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // - managed by the same hw module
12574a5b48197acdeaa397bf63a753af550bdea1b361Jean-Michel Trivi                // - supports currently selected device
1258b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                // - has a current device selection that differs from selected device.
125977305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // - has an active audio patch
1260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // In this case, the audio HAL must receive the new device selection so that it can
1261b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                // change the device currently selected by the other output.
1262b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                if (sharedDevice &&
126377305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                        desc->device() != device &&
126477305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                        desc->getPatchHandle() != AUDIO_PATCH_HANDLE_NONE) {
1265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    force = true;
1266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // wait for audio on other active outputs to be presented when starting
1268d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                // a notification so that audio focus effect can propagate, or that a mute/unmute
1269d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                // event occurred for beacon
1270b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                const uint32_t latencyMs = desc->latency();
1271b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                const bool isActive = desc->isActive(latencyMs * 2);  // account for drain
1272b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi
1273b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                if (shouldWait && isActive && (waitMs < latencyMs)) {
1274b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                    waitMs = latencyMs;
1275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1276b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi
1277b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                // Require mute check if another output is on a shared device
1278b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                // and currently active to have proper drain and avoid pops.
1279b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                // Note restoring AudioTracks onto this output needs to invoke
1280b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                // a volume ramp if there is no mute.
1281b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                requiresMuteCheck |= sharedDevice && isActive;
1282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1284b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi
1285b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        const uint32_t muteWaitMs =
1286b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                setOutputDevice(outputDesc, device, force, 0, NULL, address, requiresMuteCheck);
1287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle special case for sonification while in call
1289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (isInCall()) {
1290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            handleIncallSonification(stream, true, false);
1291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // apply volume rules for current stream and device if necessary
1294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkAndSetVolume(stream,
12956fe70331b17a513765153afd7f895f807518bb91Shuhei Miyazaki                          mVolumeCurves->getVolumeIndex(stream, outputDesc->device()),
1296c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                          outputDesc,
12976fe70331b17a513765153afd7f895f807518bb91Shuhei Miyazaki                          outputDesc->device());
1298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // update the outputs if starting an output with a stream that can affect notification
1300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // routing
1301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        handleNotificationRoutingForStream(stream);
1302c722f30eef03e77054395ae122470cf8dba93937Eric Laurent
13032cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        // force reevaluating accessibility routing when ringtone or alarm starts
13042cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        if (strategy == STRATEGY_SONIFICATION) {
13052cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent            mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
13062cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        }
1307dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
1308dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        if (waitMs > muteWaitMs) {
1309dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            *delayMs = waitMs - muteWaitMs;
1310dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        }
1311b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi
1312b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        // FIXME: A device change (muteWaitMs > 0) likely introduces a volume change.
1313b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        // A volume change enacted by APM with 0 delay is not synchronous, as it goes
1314b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        // via AudioCommandThread to AudioFlinger.  Hence it is possible that the volume
1315b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        // change occurs after the MixerThread starts and causes a stream volume
1316b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        // glitch.
1317b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        //
1318b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        // We do not introduce additional delay here.
1319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1320dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
1321b62d78b72d9e63b93d869c9c8513f46235f83e03Tomoharu Kasahara    if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE &&
1322b62d78b72d9e63b93d869c9c8513f46235f83e03Tomoharu Kasahara            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
1323b62d78b72d9e63b93d869c9c8513f46235f83e03Tomoharu Kasahara        setStrategyMute(STRATEGY_SONIFICATION, true, outputDesc);
1324b62d78b72d9e63b93d869c9c8513f46235f83e03Tomoharu Kasahara    }
1325b62d78b72d9e63b93d869c9c8513f46235f83e03Tomoharu Kasahara
1326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1330e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
13313b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                            audio_stream_type_t stream,
1332e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                            audio_session_t session)
1333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
1335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
1336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopOutput() unknown output %d", output);
1338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1341c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
1342c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1343c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mRefCount[stream] == 1) {
1344c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        // Automatically disable the remote submix input when output is stopped on a
1345c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        // re routing mix of type MIX_TYPE_RECORDERS
1346c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if (audio_is_remote_submix_device(outputDesc->mDevice) &&
1347c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                outputDesc->mPolicyMix != NULL &&
1348c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
1349c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1350c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
13517638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    outputDesc->mPolicyMix->mDeviceAddress,
1352c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    "remote-submix");
1353c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        }
1354c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1355c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1356c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // Routing?
13578c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    bool forceDeviceUpdate = false;
1358c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mRefCount[stream] > 0) {
13598c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        int activityCount = mOutputRoutes.decRouteActivity(session);
13608c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        forceDeviceUpdate = (mOutputRoutes.hasRoute(session) && (activityCount == 0));
13618c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
13628c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (forceDeviceUpdate) {
13638c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            checkStrategyRoute(getStrategy(stream), AUDIO_IO_HANDLE_NONE);
13648c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
1365c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
13673974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent    status_t status = stopSource(outputDesc, stream, forceDeviceUpdate);
13683974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent
1369733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent    if (status == NO_ERROR ) {
1370733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        outputDesc->stop();
13713974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent    }
13723974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent    return status;
1373c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
1374c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1375e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t AudioPolicyManager::stopSource(const sp<AudioOutputDescriptor>& outputDesc,
13768c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                            audio_stream_type_t stream,
13778c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                            bool forceDeviceUpdate)
1378c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
1379d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    // always handle stream stop, check which stream type is stopping
1380d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
1381d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
1382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle special case for sonification while in call
1383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isInCall()) {
1384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        handleIncallSonification(stream, false, false);
1385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1387e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->mRefCount[stream] > 0) {
1388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // decrement usage count of this stream on the output
1389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->changeRefCount(stream, -1);
1390aa9811945f575614b3482d09e4d969792701cebbPaul McLean
1391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // store time at which the stream was stopped - see isStreamActive()
13928c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (outputDesc->mRefCount[stream] == 0 || forceDeviceUpdate) {
1393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStopTime[stream] = systemTime();
1394c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
1395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // delay the device switch by twice the latency because stopOutput() is executed when
1396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // the track stop() command is received and at that time the audio track buffer can
1397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // still contain data that needs to be drained. The latency only covers the audio HAL
1398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // and kernel buffers. Also the latency does not always include additional delay in the
1399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // audio path (audio DSP, CODEC ...)
1400c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setOutputDevice(outputDesc, newDevice, false, outputDesc->latency()*2);
1401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // force restoring the device selection on other active outputs if it differs from the
1403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // one being selected for this output
140457de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent            uint32_t delayMs = outputDesc->latency()*2;
1405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < mOutputs.size(); i++) {
14061f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
1407c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                if (desc != outputDesc &&
1408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        desc->isActive() &&
1409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputDesc->sharesHwModuleWith(desc) &&
1410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (newDevice != desc->device())) {
141111c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                    audio_devices_t newDevice2 = getNewOutputDevice(desc, false /*fromCache*/);
141211c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                    bool force = desc->device() != newDevice2;
1413f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent
1414c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    setOutputDevice(desc,
141511c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                                    newDevice2,
141611c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                                    force,
141757de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                                    delayMs);
141857de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                    // re-apply device specific volume if not done by setOutputDevice()
141957de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                    if (!force) {
142057de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                        applyStreamVolumes(desc, newDevice2, delayMs);
142157de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                    }
1422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // update the outputs if stopping one with a stream that can affect notification routing
1425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            handleNotificationRoutingForStream(stream);
1426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1427b62d78b72d9e63b93d869c9c8513f46235f83e03Tomoharu Kasahara
1428b62d78b72d9e63b93d869c9c8513f46235f83e03Tomoharu Kasahara        if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE &&
1429b62d78b72d9e63b93d869c9c8513f46235f83e03Tomoharu Kasahara                mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
1430b62d78b72d9e63b93d869c9c8513f46235f83e03Tomoharu Kasahara            setStrategyMute(STRATEGY_SONIFICATION, false, outputDesc);
1431b62d78b72d9e63b93d869c9c8513f46235f83e03Tomoharu Kasahara        }
1432b62d78b72d9e63b93d869c9c8513f46235f83e03Tomoharu Kasahara
143336829f97c0c547d9c6c918e248071cc616818616Eric Laurent        if (stream == AUDIO_STREAM_MUSIC) {
143436829f97c0c547d9c6c918e248071cc616818616Eric Laurent            selectOutputForMusicEffects();
143536829f97c0c547d9c6c918e248071cc616818616Eric Laurent        }
1436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
1437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
1438c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        ALOGW("stopOutput() refcount is already 0");
1439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1443e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentvoid AudioPolicyManager::releaseOutput(audio_io_handle_t output,
1444caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                       audio_stream_type_t stream __unused,
1445caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                       audio_session_t session __unused)
1446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseOutput() %d", output);
1448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
1449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("releaseOutput() releasing unknown output %d", output);
1451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
1452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1454aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // Routing
1455aa9811945f575614b3482d09e4d969792701cebbPaul McLean    mOutputRoutes.removeRoute(session);
1456aa9811945f575614b3482d09e4d969792701cebbPaul McLean
1457c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(index);
14583b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
1459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (desc->mDirectOpenCount <= 0) {
1460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("releaseOutput() invalid open count %d for output %d",
1461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                              desc->mDirectOpenCount, output);
1462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
1463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (--desc->mDirectOpenCount == 0) {
1465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            closeOutput(output);
1466b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent            mpClientInterface->onAudioPortListUpdate();
1467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1472caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurentstatus_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
1473caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                             audio_io_handle_t *input,
1474caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                             audio_session_t session,
14758c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                             uid_t uid,
147620b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                             const audio_config_base_t *config,
147797bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                                             audio_input_flags_t flags,
14782ac7694396640821f6723672e25b2372220bf060Eric Laurent                                             audio_port_handle_t *selectedDeviceId,
147920b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                             input_type_t *inputType,
148020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                             audio_port_handle_t *portId)
1481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
148249f36ba3b4624ddd3d7efa34c95128a73bda6208Glenn Kasten    ALOGV("getInputForAttr() source %d, sampling rate %d, format %#x, channel mask %#x,"
1483caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent            "session %d, flags %#x",
148420b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent          attr->source, config->sample_rate, config->format, config->channel_mask, session, flags);
1485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1486ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    status_t status = NO_ERROR;
1487ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    // handle legacy remote submix case where the address was not always specified
1488ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    String8 address = String8("");
1489ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    audio_source_t halInputSource;
1490ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    audio_source_t inputSource = attr->source;
1491ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    AudioMix *policyMix = NULL;
1492ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    DeviceVector inputDevices;
1493ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent
1494fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    if (inputSource == AUDIO_SOURCE_DEFAULT) {
1495fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        inputSource = AUDIO_SOURCE_MIC;
1496fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    }
1497fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent
1498ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    // Explicit routing?
1499ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    sp<DeviceDescriptor> deviceDesc;
1500ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
1501c0c831a8811b438093ca7f1d01b0ccf8c2a345d3jiabin        deviceDesc = mAvailableInputDevices.getDeviceFromId(*selectedDeviceId);
1502ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    }
1503ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    mInputRoutes.addRoute(session, SessionRoute::STREAM_TYPE_NA, inputSource, deviceDesc, uid);
1504ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent
1505cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent    // special case for mmap capture: if an input IO handle is specified, we reuse this input if
1506cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent    // possible
1507cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent    if ((flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) == AUDIO_INPUT_FLAG_MMAP_NOIRQ &&
1508cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent            *input != AUDIO_IO_HANDLE_NONE) {
1509cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        ssize_t index = mInputs.indexOfKey(*input);
1510cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        if (index < 0) {
1511cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent            ALOGW("getInputForAttr() unknown MMAP input %d", *input);
1512ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent            status = BAD_VALUE;
1513ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent            goto error;
1514cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        }
1515cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1516cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
1517cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        if (audioSession == 0) {
1518cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent            ALOGW("getInputForAttr() unknown session %d on input %d", session, *input);
1519ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent            status = BAD_VALUE;
1520ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent            goto error;
1521cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        }
1522cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        // For MMAP mode, the first call to getInputForAttr() is made on behalf of audioflinger.
1523cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        // The second call is for the first active client and sets the UID. Any further call
1524331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent        // corresponds to a new client and is only permitted from the same UID.
1525331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent        // If the first UID is silenced, allow a new UID connection and replace with new UID
1526cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        if (audioSession->openCount() == 1) {
1527cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent            audioSession->setUid(uid);
1528cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        } else if (audioSession->uid() != uid) {
1529331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent            if (!audioSession->isSilenced()) {
1530331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent                ALOGW("getInputForAttr() bad uid %d for session %d uid %d",
1531331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent                      uid, session, audioSession->uid());
1532331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent                status = INVALID_OPERATION;
1533331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent                goto error;
1534331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent            }
1535331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent            audioSession->setUid(uid);
1536331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent            audioSession->setSilenced(false);
1537cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        }
1538cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        audioSession->changeOpenCount(1);
1539cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        *inputType = API_INPUT_LEGACY;
1540cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        if (*portId == AUDIO_PORT_HANDLE_NONE) {
1541cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent            *portId = AudioPort::getNextUniqueId();
1542cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        }
1543ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent        inputDevices = mAvailableInputDevices.getDevicesFromType(inputDesc->mDevice);
1544cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        *selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
1545cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent                : AUDIO_PORT_HANDLE_NONE;
1546cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        ALOGI("%s reusing MMAP input %d for session %d", __FUNCTION__, *input, session);
1547ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent
1548cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent        return NO_ERROR;
1549cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent    }
1550cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent
1551caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent    *input = AUDIO_IO_HANDLE_NONE;
155297bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi    *inputType = API_INPUT_INVALID;
1553fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1554c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    halInputSource = inputSource;
1555c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent
155620b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    // TODO: check for existing client for this port ID
155720b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    if (*portId == AUDIO_PORT_HANDLE_NONE) {
155820b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent        *portId = AudioPort::getNextUniqueId();
155920b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    }
156020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent
1561ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    audio_devices_t device;
1562466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
1563c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
1564275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
1565ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent        status = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
1566ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent        if (status != NO_ERROR) {
1567ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent            goto error;
1568c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        }
156997bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi        *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
1570036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
1571036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        address = String8(attr->tags + strlen("addr="));
1572275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    } else {
1573c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent        device = getDeviceAndMixForInputSource(inputSource, &policyMix);
1574275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        if (device == AUDIO_DEVICE_NONE) {
1575c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent            ALOGW("getInputForAttr() could not find device for source %d", inputSource);
1576ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent            status = BAD_VALUE;
1577ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent            goto error;
1578275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
1579c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        if (policyMix != NULL) {
15807638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            address = policyMix->mDeviceAddress;
158197bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            if (policyMix->mMixType == MIX_TYPE_RECORDERS) {
158297bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // there is an external policy, but this input is attached to a mix of recorders,
158397bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // meaning it receives audio injected into the framework, so the recorder doesn't
158497bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // know about it and is therefore considered "legacy"
158597bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                *inputType = API_INPUT_LEGACY;
158697bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            } else {
158797bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // recording a mix of players defined by an external policy, we're rerouting for
158897bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // an external policy
158997bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
159097bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            }
1591c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        } else if (audio_is_remote_submix_device(device)) {
1592c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            address = String8("0");
159397bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            *inputType = API_INPUT_MIX_CAPTURE;
159482db269d4797cb9909988b723d91fa2094a74b38Eric Laurent        } else if (device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
159582db269d4797cb9909988b723d91fa2094a74b38Eric Laurent            *inputType = API_INPUT_TELEPHONY_RX;
159697bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi        } else {
159797bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            *inputType = API_INPUT_LEGACY;
1598c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        }
1599b367f5b2de343bfd9040028b00acb96567f30beaRavi Kumar Alamanda
1600599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
1601599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1602599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    *input = getInputForDevice(device, address, session, uid, inputSource,
1603fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                               config, flags,
1604599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                               policyMix);
1605599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (*input == AUDIO_IO_HANDLE_NONE) {
1606ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent        status = INVALID_OPERATION;
1607ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent        goto error;
1608599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
160920b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent
1610ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    inputDevices = mAvailableInputDevices.getDevicesFromType(device);
16112ac7694396640821f6723672e25b2372220bf060Eric Laurent    *selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
16122ac7694396640821f6723672e25b2372220bf060Eric Laurent            : AUDIO_PORT_HANDLE_NONE;
16132ac7694396640821f6723672e25b2372220bf060Eric Laurent
16142ac7694396640821f6723672e25b2372220bf060Eric Laurent    ALOGV("getInputForAttr() returns input %d type %d selectedDeviceId %d",
16152ac7694396640821f6723672e25b2372220bf060Eric Laurent            *input, *inputType, *selectedDeviceId);
16162ac7694396640821f6723672e25b2372220bf060Eric Laurent
1617599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return NO_ERROR;
1618ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent
1619ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurenterror:
1620ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    mInputRoutes.removeRoute(session);
1621ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    return status;
1622599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
1623599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1624599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1625599c758b258cc5da0dba9b530425381facc37d77Eric Laurentaudio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device,
1626599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        String8 address,
1627599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_session_t session,
1628599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        uid_t uid,
1629599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_source_t inputSource,
1630fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                        const audio_config_base_t *config,
1631599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_input_flags_t flags,
1632599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        AudioMix *policyMix)
1633599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
1634599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
1635599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    audio_source_t halInputSource = inputSource;
1636599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    bool isSoundTrigger = false;
1637599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1638599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (inputSource == AUDIO_SOURCE_HOTWORD) {
1639599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ssize_t index = mSoundTriggerSessions.indexOfKey(session);
1640599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (index >= 0) {
1641599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            input = mSoundTriggerSessions.valueFor(session);
1642599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            isSoundTrigger = true;
1643599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_HW_HOTWORD);
1644599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            ALOGV("SoundTrigger capture on session %d input %d", session, input);
1645599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        } else {
1646599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
16475dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent        }
1648851d3ff273dcab849a617586c50a2e1392edefedHaynes Mathew George    } else if (inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION &&
1649fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent               audio_is_linear_pcm(config->format)) {
1650851d3ff273dcab849a617586c50a2e1392edefedHaynes Mathew George        flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_VOIP_TX);
16515dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent    }
16525dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent
1653f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    // find a compatible input profile (not necessarily identical in parameters)
1654f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    sp<IOProfile> profile;
1655fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    // sampling rate and flags may be updated by getInputProfile
1656fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    uint32_t profileSamplingRate = (config->sample_rate == 0) ?
1657fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            SAMPLE_RATE_HZ_DEFAULT : config->sample_rate;
1658730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten    audio_format_t profileFormat;
1659fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    audio_channel_mask_t profileChannelMask = config->channel_mask;
1660f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    audio_input_flags_t profileFlags = flags;
1661f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    for (;;) {
1662730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten        profileFormat = config->format; // reset each time through loop, in case it is updated
1663275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        profile = getInputProfile(device, address,
1664f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                  profileSamplingRate, profileFormat, profileChannelMask,
1665f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                  profileFlags);
1666f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        if (profile != 0) {
1667f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung            break; // success
1668050677873c10d4da308ac222f8533c96cca3207eEric Laurent        } else if (profileFlags & AUDIO_INPUT_FLAG_RAW) {
1669050677873c10d4da308ac222f8533c96cca3207eEric Laurent            profileFlags = (audio_input_flags_t) (profileFlags & ~AUDIO_INPUT_FLAG_RAW); // retry
1670f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        } else if (profileFlags != AUDIO_INPUT_FLAG_NONE) {
1671f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung            profileFlags = AUDIO_INPUT_FLAG_NONE; // retry
1672f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        } else { // fail
1673faa10a64016300504691653f4beb451cb66ec197Glenn Kasten            ALOGW("getInputForDevice() could not find profile for device 0x%X, "
1674fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                  "sampling rate %u, format %#x, channel mask 0x%X, flags %#x",
1675fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    device, config->sample_rate, config->format, config->channel_mask, flags);
1676599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            return input;
16775dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent        }
1678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
167905ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten    // Pick input sampling rate if not specified by client
1680fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    uint32_t samplingRate = config->sample_rate;
168105ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten    if (samplingRate == 0) {
168205ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten        samplingRate = profileSamplingRate;
168305ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten    }
1684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1685322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    if (profile->getModuleHandle() == 0) {
1686322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent        ALOGE("getInputForAttr(): HW module %s not opened", profile->getModuleName());
1687599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return input;
1688cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    }
1689cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent
1690599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = new AudioSession(session,
1691fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                     inputSource,
1692fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                     config->format,
1693fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                     samplingRate,
1694fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                     config->channel_mask,
1695fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                     flags,
1696fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                     uid,
1697fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                     isSoundTrigger,
1698fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                     policyMix, mpClientInterface);
1699599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
170074708e7c4622d65a7798d5fa9347c55583d347feEric Laurent// FIXME: disable concurrent capture until UI is ready
170174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent#if 0
1702599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    // reuse an open input if possible
1703555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent    sp<AudioInputDescriptor> reusedInputDesc;
1704599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
1705599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
1706fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        // reuse input if:
1707fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        // - it shares the same profile
1708fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        //      AND
1709fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        // - it is not a reroute submix input
1710fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        //      AND
1711fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        // - it is: not used for sound trigger
1712fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        //                OR
1713fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        //          used for sound trigger and all clients use the same session ID
1714fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        //
1715fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        if ((profile == desc->mProfile) &&
1716fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            (isSoundTrigger == desc->isSoundTrigger()) &&
1717fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            !is_virtual_input_device(device)) {
1718599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1719599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            sp<AudioSession> as = desc->getAudioSession(session);
1720599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            if (as != 0) {
1721599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                // do not allow unmatching properties on same session
1722599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                if (as->matches(audioSession)) {
1723599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                    as->changeOpenCount(1);
1724599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                } else {
1725599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                    ALOGW("getInputForDevice() record with different attributes"
1726599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                          " exists for session %d", session);
1727555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent                    continue;
1728fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                }
1729fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            } else if (isSoundTrigger) {
1730555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent                continue;
1731fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            }
1732bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent
1733555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // Reuse the already opened input stream on this profile if:
1734555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // - the new capture source is background OR
1735555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // - the path requested configurations match OR
1736555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // - the new source priority is less than the highest source priority on this input
1737555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // If the input stream cannot be reused, close it before opening a new stream
1738555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // on the same profile for the new client so that the requested path configuration
1739555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // can be selected.
1740555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            if (!isConcurrentSource(inputSource) &&
1741bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent                    ((desc->mSamplingRate != samplingRate ||
1742fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    desc->mChannelMask != config->channel_mask ||
1743fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    !audio_formats_match(desc->mFormat, config->format)) &&
1744fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                    (source_priority(desc->getHighestPrioritySource(false /*activeOnly*/)) <
1745bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent                     source_priority(inputSource)))) {
1746555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent                reusedInputDesc = desc;
1747555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent                continue;
1748599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            } else {
1749599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                desc->addAudioSession(session, audioSession);
1750fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                ALOGV("%s: reusing input %d", __FUNCTION__, mInputs.keyAt(i));
1751fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                return mInputs.keyAt(i);
1752599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            }
1753599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        }
1754599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
1755599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1756555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent    if (reusedInputDesc != 0) {
1757555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent        AudioSessionCollection sessions = reusedInputDesc->getAudioSessions(false /*activeOnly*/);
1758555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent        for (size_t j = 0; j < sessions.size(); j++) {
1759555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            audio_session_t currentSession = sessions.keyAt(j);
1760555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            stopInput(reusedInputDesc->mIoHandle, currentSession);
1761555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            releaseInput(reusedInputDesc->mIoHandle, currentSession);
1762555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent        }
1763555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent    }
176474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent#endif
1765555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent
17663974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent    if (!profile->canOpenNewIo()) {
17673974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent        return AUDIO_IO_HANDLE_NONE;
17683974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent    }
17693974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent
1770fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile, mpClientInterface);
1771df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
1772fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    audio_config_t lConfig = AUDIO_CONFIG_INITIALIZER;
1773fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    lConfig.sample_rate = profileSamplingRate;
1774fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    lConfig.channel_mask = profileChannelMask;
1775fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    lConfig.format = profileFormat;
1776e301410b8495a3702e21019e92d44ade2a3f81d1Eric Laurent
177753b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent    if (address == "") {
177853b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent        DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(device);
177953b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent        // the inputs vector must be of size >= 1, but we don't want to crash here
178053b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent        address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress : String8("");
178153b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent    }
178253b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent
1783fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    status_t status = inputDesc->open(&lConfig, device, address,
1784fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            halInputSource, profileFlags, &input);
1785cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent
1786cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    // only accept input with the exact requested set of parameters
1787599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE ||
1788fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        (profileSamplingRate != lConfig.sample_rate) ||
1789fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        !audio_formats_match(profileFormat, lConfig.format) ||
1790fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        (profileChannelMask != lConfig.channel_mask)) {
1791fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        ALOGW("getInputForAttr() failed opening input: sampling rate %d"
179249f36ba3b4624ddd3d7efa34c95128a73bda6208Glenn Kasten              ", format %#x, channel mask %#x",
1793fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent              profileSamplingRate, profileFormat, profileChannelMask);
1794599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (input != AUDIO_IO_HANDLE_NONE) {
1795fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            inputDesc->close();
1796cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        }
1797599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return AUDIO_IO_HANDLE_NONE;
1798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1800c722f30eef03e77054395ae122470cf8dba93937Eric Laurent    inputDesc->mPolicyMix = policyMix;
1801599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    inputDesc->addAudioSession(session, audioSession);
1802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1803599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    addInput(input, inputDesc);
1804b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPortListUpdate();
1805466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
1806599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return input;
1807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1809bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent//static
1810bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurentbool AudioPolicyManager::isConcurrentSource(audio_source_t source)
1811bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent{
1812bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent    return (source == AUDIO_SOURCE_HOTWORD) ||
1813bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent            (source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
1814bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent            (source == AUDIO_SOURCE_FM_TUNER);
1815bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent}
1816bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent
1817fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentbool AudioPolicyManager::isConcurentCaptureAllowed(const sp<AudioInputDescriptor>& inputDesc,
1818fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        const sp<AudioSession>& audioSession)
1819fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent{
1820fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // Do not allow capture if an active voice call is using a software patch and
1821fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // the call TX source device is on the same HW module.
1822fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // FIXME: would be better to refine to only inputs whose profile connects to the
1823fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // call TX device but this information is not in the audio patch
1824fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (mCallTxPatch != 0 &&
1825fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
1826fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        return false;
1827fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
1828fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1829fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // starting concurrent capture is enabled if:
1830fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // 1) capturing for re-routing
1831fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // 2) capturing for HOTWORD source
1832fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // 3) capturing for FM TUNER source
1833fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // 3) All other active captures are either for re-routing or HOTWORD
1834fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1835fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (is_virtual_input_device(inputDesc->mDevice) ||
1836bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent            isConcurrentSource(audioSession->inputSource())) {
1837fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        return true;
1838fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
1839fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1840cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    for (const auto& activeInput : mInputs.getActiveInputs()) {
1841bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent        if (!isConcurrentSource(activeInput->inputSource(true)) &&
1842fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                !is_virtual_input_device(activeInput->mDevice)) {
1843fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            return false;
1844fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        }
1845fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
1846fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1847fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    return true;
1848fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent}
1849fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
18502b8646482dc74cf1afef50a812691600aa229090Chris Thornton// FIXME: remove when concurrent capture is ready. This is a hack to work around bug b/63083537.
18512b8646482dc74cf1afef50a812691600aa229090Chris Thorntonbool AudioPolicyManager::soundTriggerSupportsConcurrentCapture() {
18522b8646482dc74cf1afef50a812691600aa229090Chris Thornton    if (!mHasComputedSoundTriggerSupportsConcurrentCapture) {
18532b8646482dc74cf1afef50a812691600aa229090Chris Thornton        bool soundTriggerSupportsConcurrentCapture = false;
18542b8646482dc74cf1afef50a812691600aa229090Chris Thornton        unsigned int numModules = 0;
18552b8646482dc74cf1afef50a812691600aa229090Chris Thornton        struct sound_trigger_module_descriptor* nModules = NULL;
18562b8646482dc74cf1afef50a812691600aa229090Chris Thornton
18572b8646482dc74cf1afef50a812691600aa229090Chris Thornton        status_t status = SoundTrigger::listModules(nModules, &numModules);
18582b8646482dc74cf1afef50a812691600aa229090Chris Thornton        if (status == NO_ERROR && numModules != 0) {
18592b8646482dc74cf1afef50a812691600aa229090Chris Thornton            nModules = (struct sound_trigger_module_descriptor*) calloc(
18602b8646482dc74cf1afef50a812691600aa229090Chris Thornton                    numModules, sizeof(struct sound_trigger_module_descriptor));
18612b8646482dc74cf1afef50a812691600aa229090Chris Thornton            if (nModules == NULL) {
18622b8646482dc74cf1afef50a812691600aa229090Chris Thornton              // We failed to malloc the buffer, so just say no for now, and hope that we have more
18632b8646482dc74cf1afef50a812691600aa229090Chris Thornton              // ram the next time this function is called.
18642b8646482dc74cf1afef50a812691600aa229090Chris Thornton              ALOGE("Failed to allocate buffer for module descriptors");
18652b8646482dc74cf1afef50a812691600aa229090Chris Thornton              return false;
18662b8646482dc74cf1afef50a812691600aa229090Chris Thornton            }
18672b8646482dc74cf1afef50a812691600aa229090Chris Thornton
18682b8646482dc74cf1afef50a812691600aa229090Chris Thornton            status = SoundTrigger::listModules(nModules, &numModules);
18692b8646482dc74cf1afef50a812691600aa229090Chris Thornton            if (status == NO_ERROR) {
18702b8646482dc74cf1afef50a812691600aa229090Chris Thornton                soundTriggerSupportsConcurrentCapture = true;
18712b8646482dc74cf1afef50a812691600aa229090Chris Thornton                for (size_t i = 0; i < numModules; ++i) {
18722b8646482dc74cf1afef50a812691600aa229090Chris Thornton                    soundTriggerSupportsConcurrentCapture &=
18732b8646482dc74cf1afef50a812691600aa229090Chris Thornton                            nModules[i].properties.concurrent_capture;
18742b8646482dc74cf1afef50a812691600aa229090Chris Thornton                }
18752b8646482dc74cf1afef50a812691600aa229090Chris Thornton            }
18762b8646482dc74cf1afef50a812691600aa229090Chris Thornton            free(nModules);
18772b8646482dc74cf1afef50a812691600aa229090Chris Thornton        }
18782b8646482dc74cf1afef50a812691600aa229090Chris Thornton        mSoundTriggerSupportsConcurrentCapture = soundTriggerSupportsConcurrentCapture;
18792b8646482dc74cf1afef50a812691600aa229090Chris Thornton        mHasComputedSoundTriggerSupportsConcurrentCapture = true;
18802b8646482dc74cf1afef50a812691600aa229090Chris Thornton    }
18812b8646482dc74cf1afef50a812691600aa229090Chris Thornton    return mSoundTriggerSupportsConcurrentCapture;
18822b8646482dc74cf1afef50a812691600aa229090Chris Thornton}
18832b8646482dc74cf1afef50a812691600aa229090Chris Thornton
1884fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
18854dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentstatus_t AudioPolicyManager::startInput(audio_io_handle_t input,
1886fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                                        audio_session_t session,
1887f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                                        bool silenced,
1888fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                                        concurrency_type__mask_t *concurrency)
1889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1890f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
1891f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    ALOGV("AudioPolicyManager::startInput(input:%d, session:%d, silenced:%d, concurrency:%d)",
1892f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            input, session, silenced, *concurrency);
1893f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
1894fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    *concurrency = API_INPUT_CONCURRENCY_NONE;
1895f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
1896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("startInput() unknown input %d", input);
1899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
19011f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1903599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
1904599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession == 0) {
19054dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        ALOGW("startInput() unknown session %d on input %d", session, input);
19064dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        return BAD_VALUE;
19074dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    }
19084dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent
190974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent// FIXME: disable concurrent capture until UI is ready
191074708e7c4622d65a7798d5fa9347c55583d347feEric Laurent#if 0
1911fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (!isConcurentCaptureAllowed(inputDesc, audioSession)) {
1912fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        ALOGW("startInput(%d) failed: other input already started", input);
1913fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        return INVALID_OPERATION;
1914fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
1915c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent
1916fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (isInCall()) {
1917fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        *concurrency |= API_INPUT_CONCURRENCY_CALL;
1918fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
1919f7c50104b07091880019f4ecc70d977961148268Eric Laurent    if (mInputs.activeInputsCountOnDevices() != 0) {
1920fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        *concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
1921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
192274708e7c4622d65a7798d5fa9347c55583d347feEric Laurent#else
192374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent    if (!is_virtual_input_device(inputDesc->mDevice)) {
192474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        if (mCallTxPatch != 0 &&
192574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
192674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            ALOGW("startInput(%d) failed: call in progress", input);
192784e84a5dd3b6d9ee4cf032e8d6206c70969b7107Ray Essick            *concurrency |= API_INPUT_CONCURRENCY_CALL;
192874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            return INVALID_OPERATION;
192974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        }
193074708e7c4622d65a7798d5fa9347c55583d347feEric Laurent
1931f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        Vector<sp<AudioInputDescriptor>> activeInputs = mInputs.getActiveInputs();
1932f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
1933f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        // If a UID is idle and records silence and another not silenced recording starts
1934f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        // from another UID (idle or active) we stop the current idle UID recording in
1935f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        // favor of the new one - "There can be only one" TM
1936f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        if (!silenced) {
1937f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            for (const auto& activeDesc : activeInputs) {
1938f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                if ((audioSession->flags() & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0 &&
1939f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                        activeDesc->getId() == inputDesc->getId()) {
1940f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                     continue;
1941f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                }
1942f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
1943f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                AudioSessionCollection activeSessions = activeDesc->getAudioSessions(
1944f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                        true /*activeOnly*/);
1945f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                sp<AudioSession> activeSession = activeSessions.valueAt(0);
1946f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                if (activeSession->isSilenced()) {
1947f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                    audio_io_handle_t activeInput = activeDesc->mIoHandle;
1948f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                    audio_session_t activeSessionId = activeSession->session();
1949f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                    stopInput(activeInput, activeSessionId);
1950f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                    releaseInput(activeInput, activeSessionId);
1951f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                    ALOGV("startInput(%d) stopping silenced input %d", input, activeInput);
1952f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                    activeInputs = mInputs.getActiveInputs();
1953f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                }
195474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            }
1955f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        }
195674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent
1957f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        for (const auto& activeDesc : activeInputs) {
1958cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent            if ((audioSession->flags() & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0 &&
1959cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent                    activeDesc->getId() == inputDesc->getId()) {
1960cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent                continue;
1961cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent            }
1962cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent
196374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            audio_source_t activeSource = activeDesc->inputSource(true);
196474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            if (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) {
196574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                if (activeSource == AUDIO_SOURCE_HOTWORD) {
196674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    if (activeDesc->hasPreemptedSession(session)) {
196774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                        ALOGW("startInput(%d) failed for HOTWORD: "
196874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                                "other input %d already started for HOTWORD",
196974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                              input, activeDesc->mIoHandle);
197084e84a5dd3b6d9ee4cf032e8d6206c70969b7107Ray Essick                        *concurrency |= API_INPUT_CONCURRENCY_HOTWORD;
197174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                        return INVALID_OPERATION;
197274708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    }
197374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                } else {
197474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    ALOGV("startInput(%d) failed for HOTWORD: other input %d already started",
197574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                          input, activeDesc->mIoHandle);
197684e84a5dd3b6d9ee4cf032e8d6206c70969b7107Ray Essick                    *concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
197774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    return INVALID_OPERATION;
197874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                }
197974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            } else {
198074708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                if (activeSource != AUDIO_SOURCE_HOTWORD) {
198174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    ALOGW("startInput(%d) failed: other input %d already started",
198274708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                          input, activeDesc->mIoHandle);
198384e84a5dd3b6d9ee4cf032e8d6206c70969b7107Ray Essick                    *concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
198474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    return INVALID_OPERATION;
198574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                }
198674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            }
198774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        }
198874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent
19892b8646482dc74cf1afef50a812691600aa229090Chris Thornton        // We only need to check if the sound trigger session supports concurrent capture if the
19902b8646482dc74cf1afef50a812691600aa229090Chris Thornton        // input is also a sound trigger input. Otherwise, we should preempt any hotword stream
19912b8646482dc74cf1afef50a812691600aa229090Chris Thornton        // that's running.
19922b8646482dc74cf1afef50a812691600aa229090Chris Thornton        const bool allowConcurrentWithSoundTrigger =
19932b8646482dc74cf1afef50a812691600aa229090Chris Thornton            inputDesc->isSoundTrigger() ? soundTriggerSupportsConcurrentCapture() : false;
19942b8646482dc74cf1afef50a812691600aa229090Chris Thornton
199574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        // if capture is allowed, preempt currently active HOTWORD captures
1996cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        for (const auto& activeDesc : activeInputs) {
19972b8646482dc74cf1afef50a812691600aa229090Chris Thornton            if (allowConcurrentWithSoundTrigger && activeDesc->isSoundTrigger()) {
19982b8646482dc74cf1afef50a812691600aa229090Chris Thornton                continue;
19992b8646482dc74cf1afef50a812691600aa229090Chris Thornton            }
20002b8646482dc74cf1afef50a812691600aa229090Chris Thornton
200174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            audio_source_t activeSource = activeDesc->inputSource(true);
200274708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            if (activeSource == AUDIO_SOURCE_HOTWORD) {
200374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                AudioSessionCollection activeSessions =
200474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                        activeDesc->getAudioSessions(true /*activeOnly*/);
200574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                audio_session_t activeSession = activeSessions.keyAt(0);
200674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                audio_io_handle_t activeHandle = activeDesc->mIoHandle;
200774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                SortedVector<audio_session_t> sessions = activeDesc->getPreemptedSessions();
200884e84a5dd3b6d9ee4cf032e8d6206c70969b7107Ray Essick                *concurrency |= API_INPUT_CONCURRENCY_PREEMPT;
200974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                sessions.add(activeSession);
201074708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                inputDesc->setPreemptedSessions(sessions);
201174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                stopInput(activeHandle, activeSession);
201274708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                releaseInput(activeHandle, activeSession);
201374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                ALOGV("startInput(%d) for HOTWORD preempting HOTWORD input %d",
201474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                      input, activeDesc->mIoHandle);
201574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            }
201674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        }
201774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent    }
201874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent#endif
2019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2020f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    // Make sure we start with the correct silence state
2021f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    audioSession->setSilenced(silenced);
2022f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
2023313d1e7dfb4bf8e0a2f09a9adb287062dd64410cEric Laurent    // increment activity count before calling getNewInputDevice() below as only active sessions
2024313d1e7dfb4bf8e0a2f09a9adb287062dd64410cEric Laurent    // are considered for device selection
2025313d1e7dfb4bf8e0a2f09a9adb287062dd64410cEric Laurent    audioSession->changeActiveCount(1);
2026313d1e7dfb4bf8e0a2f09a9adb287062dd64410cEric Laurent
20278c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // Routing?
20288c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    mInputRoutes.incRouteActivity(session);
20298c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
20302157f5bc0c54a77318e75076365eff739e07056fEric Laurent    if (audioSession->activeCount() == 1 || mInputRoutes.getAndClearRouteChanged(session)) {
2031271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        // indicate active capture to sound trigger service if starting capture from a mic on
2032271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        // primary HW module
2033f7c50104b07091880019f4ecc70d977961148268Eric Laurent        audio_devices_t device = getNewInputDevice(inputDesc);
2034271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        setInputDevice(input, device, true /* force */);
2035eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi
2036733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        status_t status = inputDesc->start();
2037733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        if (status != NO_ERROR) {
2038733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            mInputRoutes.decRouteActivity(session);
2039733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            audioSession->changeActiveCount(-1);
2040733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            return status;
2041733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        }
20423974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent
2043733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        if (inputDesc->getAudioSessionCount(true/*activeOnly*/) == 1) {
2044eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // if input maps to a dynamic policy with an activity listener, notify of state change
2045eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            if ((inputDesc->mPolicyMix != NULL)
2046eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
2047eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
2048eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                        MIX_STATE_MIXING);
2049c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            }
2050eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi
2051f7c50104b07091880019f4ecc70d977961148268Eric Laurent            audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
2052f7c50104b07091880019f4ecc70d977961148268Eric Laurent            if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
205305b345e504a0affd24eefa12686812c554b294ffEric Laurent                    mInputs.activeInputsCountOnDevices(primaryInputDevices) == 1) {
2054eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                SoundTrigger::setCaptureState(true);
2055eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            }
2056eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi
2057eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // automatically enable the remote submix output when input is started if not
2058eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // used by a policy mix of type MIX_TYPE_RECORDERS
2059eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // For remote submix (a virtual device), we open only one input per capture request.
2060eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            if (audio_is_remote_submix_device(inputDesc->mDevice)) {
2061eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                String8 address = String8("");
2062eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                if (inputDesc->mPolicyMix == NULL) {
2063eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    address = String8("0");
2064eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
2065eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    address = inputDesc->mPolicyMix->mDeviceAddress;
2066eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                }
2067eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                if (address != "") {
2068eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2069eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                            AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2070eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                            address, "remote-submix");
2071eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                }
2072c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            }
207374a8e2533561f04029873446206ab407cd2e033bGlenn Kasten        }
2074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2076599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("AudioPolicyManager::startInput() input source = %d", audioSession->inputSource());
2077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
2079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
20814dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentstatus_t AudioPolicyManager::stopInput(audio_io_handle_t input,
20824dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent                                       audio_session_t session)
2083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("stopInput() input %d", input);
2085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
2086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
2087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopInput() unknown input %d", input);
2088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
2089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
20901f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
2091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2092599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
20934dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    if (index < 0) {
20944dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        ALOGW("stopInput() unknown session %d on input %d", session, input);
20954dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        return BAD_VALUE;
20964dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    }
20974dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent
2098599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession->activeCount() == 0) {
2099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopInput() input %d already stopped", input);
2100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
21016a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    }
21026a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten
2103599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    audioSession->changeActiveCount(-1);
2104466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
2105466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    // Routing?
2106466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    mInputRoutes.decRouteActivity(session);
2107466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
2108eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi    if (audioSession->activeCount() == 0) {
2109733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        inputDesc->stop();
2110eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi        if (inputDesc->isActive()) {
2111eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
2112eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi        } else {
2113eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // if input maps to a dynamic policy with an activity listener, notify of state change
2114eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            if ((inputDesc->mPolicyMix != NULL)
2115eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
2116eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
2117eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                        MIX_STATE_IDLE);
2118c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            }
2119eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi
2120eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // automatically disable the remote submix output when input is stopped if not
2121eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // used by a policy mix of type MIX_TYPE_RECORDERS
2122eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            if (audio_is_remote_submix_device(inputDesc->mDevice)) {
2123eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                String8 address = String8("");
2124eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                if (inputDesc->mPolicyMix == NULL) {
2125eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    address = String8("0");
2126eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
2127eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    address = inputDesc->mPolicyMix->mDeviceAddress;
2128eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                }
2129eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                if (address != "") {
2130eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2131eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                                             AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2132eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                                             address, "remote-submix");
2133eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                }
2134c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            }
2135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2136f7c50104b07091880019f4ecc70d977961148268Eric Laurent            audio_devices_t device = inputDesc->mDevice;
2137fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            resetInputDevice(input);
2138df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
2139f7c50104b07091880019f4ecc70d977961148268Eric Laurent            // indicate inactive capture to sound trigger service if stopping capture from a mic on
2140f7c50104b07091880019f4ecc70d977961148268Eric Laurent            // primary HW module
2141f7c50104b07091880019f4ecc70d977961148268Eric Laurent            audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
2142f7c50104b07091880019f4ecc70d977961148268Eric Laurent            if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
2143f7c50104b07091880019f4ecc70d977961148268Eric Laurent                    mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0) {
2144fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                SoundTrigger::setCaptureState(false);
2145fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            }
2146fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            inputDesc->clearPreemptedSessions();
2147df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        }
2148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
21496a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    return NO_ERROR;
2150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
21524dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentvoid AudioPolicyManager::releaseInput(audio_io_handle_t input,
21534dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent                                      audio_session_t session)
2154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseInput() %d", input);
2156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
2157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
2158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("releaseInput() releasing unknown input %d", input);
2159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
2160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2161466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
2162466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    // Routing
2163466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    mInputRoutes.removeRoute(session);
2164466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
21656a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
21666a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    ALOG_ASSERT(inputDesc != 0);
21674dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent
2168599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
2169587b8dfdbc3d3b1dd9ffc1996b9a07cd9b284833vivek mehta    if (audioSession == 0) {
21704dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        ALOGW("releaseInput() unknown session %d on input %d", session, input);
21714dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        return;
21724dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    }
2173599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
2174599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession->openCount() == 0) {
2175599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("releaseInput() invalid open count %d on session %d",
2176599c758b258cc5da0dba9b530425381facc37d77Eric Laurent              audioSession->openCount(), session);
21776a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten        return;
21786a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    }
2179599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
2180599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession->changeOpenCount(-1) == 0) {
2181599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        inputDesc->removeAudioSession(session);
2182599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
2183599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
218465bfe916ca972b95f41d7f6cc2566c2e12a3eadaJean-Michel Trivi    if (inputDesc->getOpenRefCount() > 0) {
21856a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten        ALOGV("releaseInput() exit > 0");
21866a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten        return;
21876a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    }
21886a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten
218905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    closeInput(input);
2190b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPortListUpdate();
2191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseInput() exit");
2192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2194d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::closeAllInputs() {
219505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    bool patchRemoved = false;
219605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
21977e22e94d0654d7ab4c31aee7f7120542e358a5abMikhail Naganov    for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
219805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index);
21998c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
220005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        if (patch_index >= 0) {
220105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent            sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index);
2202fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten            (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
220305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent            mAudioPatches.removeItemsAt(patch_index);
220405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent            patchRemoved = true;
220505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        }
2206fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        inputDesc->close();
2207d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }
2208829a00bd6e54ce78fe1a28d8739988e24ec4ab6djiabin    mInputRoutes.clear();
2209d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    mInputs.clear();
221052785f3df24fe817af4f1c3c2cddfb30ab5450eeChris Thornton    SoundTrigger::setCaptureState(false);
22116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
221205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
221305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (patchRemoved) {
221405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mpClientInterface->onAudioPatchListUpdate();
221505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
2216d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
2217d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2218e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
2219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int indexMin,
2220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int indexMax)
2221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
2223d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves->initStreamVolume(stream, indexMin, indexMax);
222428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent
222528d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    // initialize other private stream volumes which follow this one
2226794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
2227794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
222828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
222928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
223028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        mVolumeCurves->initStreamVolume((audio_stream_type_t)curStream, indexMin, indexMax);
2231223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    }
2232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2234e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
223553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  int index,
223653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  audio_devices_t device)
2237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
22397c605f65099f4db2ece707e07b5e844d5eefc9a6Nadav Bar    // VOICE_CALL stream has minVolumeIndex > 0  but can be muted directly by an
22407c605f65099f4db2ece707e07b5e844d5eefc9a6Nadav Bar    // app that has MODIFY_PHONE_STATE permission.
22417c605f65099f4db2ece707e07b5e844d5eefc9a6Nadav Bar    if (((index < mVolumeCurves->getVolumeIndexMin(stream)) &&
22427c605f65099f4db2ece707e07b5e844d5eefc9a6Nadav Bar            !(stream == AUDIO_STREAM_VOICE_CALL && index == 0)) ||
2243d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            (index > mVolumeCurves->getVolumeIndexMax(stream))) {
2244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
2245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device)) {
2247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
2248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Force max volume if stream cannot be muted
2251d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if (!mVolumeCurves->canBeMuted(stream)) index = mVolumeCurves->getVolumeIndexMax(stream);
2252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
22531fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d",
2254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          stream, device, index);
2255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
225628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    // update other private stream volumes which follow this one
2257794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
2258794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
225928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
226028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
226128d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        mVolumeCurves->addCurrentVolumeIndex((audio_stream_type_t)curStream, device, index);
2262223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    }
2263e04e62bc05316d9682688f87053be5cf47e9c707Eric Laurent
22641fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // update volume on all outputs and streams matching the following:
22651fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // - The requested stream (or a stream matching for volume control) is active on the output
22661fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // - The device (or devices) selected by the strategy corresponding to this stream includes
22671fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // the requested device
22681fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // - For non default requested device, currently selected device on the output is either the
22691fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // requested device or one of the devices selected by the strategy
22705a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
22715a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    // no specific device volume value exists for currently selected device.
2272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    status_t status = NO_ERROR;
2273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
2274c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
2275c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        audio_devices_t curDevice = Volume::getDeviceForVolume(desc->device());
2276794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
2277794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
227828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                continue;
227928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            }
2280d3926fe68ffd8d156e7c019277bbeb32ca786d8eEric Laurent            if (!(desc->isStreamActive((audio_stream_type_t)curStream) ||
2281d3926fe68ffd8d156e7c019277bbeb32ca786d8eEric Laurent                    (isInCall() && (curStream == AUDIO_STREAM_VOICE_CALL)))) {
22821fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent                continue;
22831fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent            }
2284794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
2285b7fdce6e1654e573c25ec19fa6dfeb79dc4e6597Jean-Michel Trivi            audio_devices_t curStreamDevice = Volume::getDeviceForVolume(getDeviceForStrategy(
2286b7fdce6e1654e573c25ec19fa6dfeb79dc4e6597Jean-Michel Trivi                    curStrategy, false /*fromCache*/));
2287e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            if ((device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) &&
2288e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent                    ((curStreamDevice & device) == 0)) {
22891fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent                continue;
22901fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent            }
2291e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            bool applyVolume;
22925a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent            if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
22931fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent                curStreamDevice |= device;
2294e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent                applyVolume = (curDevice & curStreamDevice) != 0;
2295e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            } else {
2296e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent                applyVolume = !mVolumeCurves->hasVolumeIndexForDevice(
2297b7fdce6e1654e573c25ec19fa6dfeb79dc4e6597Jean-Michel Trivi                        stream, curStreamDevice);
22981fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent            }
22991fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent
2300e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            if (applyVolume) {
2301dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                //FIXME: workaround for truncated touch sounds
2302dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // delayed volume change for system stream to be removed when the problem is
2303dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // handled by system UI
230428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                status_t volStatus =
2305dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                        checkAndSetVolume((audio_stream_type_t)curStream, index, desc, curDevice,
2306dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                            (stream == AUDIO_STREAM_SYSTEM) ? TOUCH_SOUND_FIXED_DELAY_MS : 0);
230728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                if (volStatus != NO_ERROR) {
230828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                    status = volStatus;
230928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                }
2310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2311223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent        }
2312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return status;
2314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2316e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
2317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      int *index,
2318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      audio_devices_t device)
2319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index == NULL) {
2321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
2322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device)) {
2324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
2325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
23265a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device corresponding to
2327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // the strategy the stream belongs to.
23285a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
2329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
2330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2331dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    device = Volume::getDeviceForVolume(device);
2332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2333d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    *index =  mVolumeCurves->getVolumeIndex(stream, device);
2334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
2335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
2336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
233836829f97c0c547d9c6c918e248071cc616818616Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutputForMusicEffects()
2339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // select one output among several suitable for global effects.
2341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // The priority is as follows:
2342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: An offloaded output. If the effect ends up not being offloadable,
2343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //    AudioFlinger will invalidate the track and the offloaded output
2344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //    will be closed causing the effect to be moved to a PCM output.
2345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: A deep buffer output
234636829f97c0c547d9c6c918e248071cc616818616Eric Laurent    // 3: The primary output
234736829f97c0c547d9c6c918e248071cc616818616Eric Laurent    // 4: the first output in the list
234836829f97c0c547d9c6c918e248071cc616818616Eric Laurent
234936829f97c0c547d9c6c918e248071cc616818616Eric Laurent    routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
235036829f97c0c547d9c6c918e248071cc616818616Eric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
235136829f97c0c547d9c6c918e248071cc616818616Eric Laurent    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
2352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 0) {
235436829f97c0c547d9c6c918e248071cc616818616Eric Laurent        return AUDIO_IO_HANDLE_NONE;
2355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
235736829f97c0c547d9c6c918e248071cc616818616Eric Laurent    audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
235836829f97c0c547d9c6c918e248071cc616818616Eric Laurent    bool activeOnly = true;
2359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
236036829f97c0c547d9c6c918e248071cc616818616Eric Laurent    while (output == AUDIO_IO_HANDLE_NONE) {
236136829f97c0c547d9c6c918e248071cc616818616Eric Laurent        audio_io_handle_t outputOffloaded = AUDIO_IO_HANDLE_NONE;
236236829f97c0c547d9c6c918e248071cc616818616Eric Laurent        audio_io_handle_t outputDeepBuffer = AUDIO_IO_HANDLE_NONE;
236336829f97c0c547d9c6c918e248071cc616818616Eric Laurent        audio_io_handle_t outputPrimary = AUDIO_IO_HANDLE_NONE;
236436829f97c0c547d9c6c918e248071cc616818616Eric Laurent
2365cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        for (audio_io_handle_t output : outputs) {
2366cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov            sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
236736829f97c0c547d9c6c918e248071cc616818616Eric Laurent            if (activeOnly && !desc->isStreamActive(AUDIO_STREAM_MUSIC)) {
236836829f97c0c547d9c6c918e248071cc616818616Eric Laurent                continue;
236936829f97c0c547d9c6c918e248071cc616818616Eric Laurent            }
2370cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov            ALOGV("selectOutputForMusicEffects activeOnly %d output %d flags 0x%08x",
2371cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                  activeOnly, output, desc->mFlags);
237236829f97c0c547d9c6c918e248071cc616818616Eric Laurent            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
2373cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                outputOffloaded = output;
237436829f97c0c547d9c6c918e248071cc616818616Eric Laurent            }
237536829f97c0c547d9c6c918e248071cc616818616Eric Laurent            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
2376cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                outputDeepBuffer = output;
237736829f97c0c547d9c6c918e248071cc616818616Eric Laurent            }
237836829f97c0c547d9c6c918e248071cc616818616Eric Laurent            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) != 0) {
2379cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                outputPrimary = output;
238036829f97c0c547d9c6c918e248071cc616818616Eric Laurent            }
2381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
238236829f97c0c547d9c6c918e248071cc616818616Eric Laurent        if (outputOffloaded != AUDIO_IO_HANDLE_NONE) {
238336829f97c0c547d9c6c918e248071cc616818616Eric Laurent            output = outputOffloaded;
238436829f97c0c547d9c6c918e248071cc616818616Eric Laurent        } else if (outputDeepBuffer != AUDIO_IO_HANDLE_NONE) {
238536829f97c0c547d9c6c918e248071cc616818616Eric Laurent            output = outputDeepBuffer;
238636829f97c0c547d9c6c918e248071cc616818616Eric Laurent        } else if (outputPrimary != AUDIO_IO_HANDLE_NONE) {
238736829f97c0c547d9c6c918e248071cc616818616Eric Laurent            output = outputPrimary;
238836829f97c0c547d9c6c918e248071cc616818616Eric Laurent        } else {
238936829f97c0c547d9c6c918e248071cc616818616Eric Laurent            output = outputs[0];
2390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
239136829f97c0c547d9c6c918e248071cc616818616Eric Laurent        activeOnly = false;
2392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
239436829f97c0c547d9c6c918e248071cc616818616Eric Laurent    if (output != mMusicEffectOutput) {
239536829f97c0c547d9c6c918e248071cc616818616Eric Laurent        mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mMusicEffectOutput, output);
239636829f97c0c547d9c6c918e248071cc616818616Eric Laurent        mMusicEffectOutput = output;
2397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
239936829f97c0c547d9c6c918e248071cc616818616Eric Laurent    ALOGV("selectOutputForMusicEffects selected output %d", output);
240036829f97c0c547d9c6c918e248071cc616818616Eric Laurent    return output;
2401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
240336829f97c0c547d9c6c918e248071cc616818616Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc __unused)
2404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
240536829f97c0c547d9c6c918e248071cc616818616Eric Laurent    return selectOutputForMusicEffects();
2406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2408e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
2409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                audio_io_handle_t io,
2410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                uint32_t strategy,
2411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                int session,
2412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                int id)
2413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(io);
2415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
2416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        index = mInputs.indexOfKey(io);
2417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (index < 0) {
2418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("registerEffect() unknown io %d", io);
2419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return INVALID_OPERATION;
2420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
242245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return mEffects.registerEffect(desc, io, strategy, session, id);
2423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2425c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
2426c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
242728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    bool active = false;
2428794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT && !active; curStream++) {
2429794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
243028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
243128d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
243228d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        active = mOutputs.isStreamActive((audio_stream_type_t)curStream, inPastMs);
243328d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    }
243428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    return active;
2435c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
2436c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
2437c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
2438c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
2439c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return mOutputs.isStreamActiveRemotely(stream, inPastMs);
2440c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
2441c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
2442e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isSourceActive(audio_source_t source) const
2443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
24451f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent        const sp<AudioInputDescriptor>  inputDescriptor = mInputs.valueAt(i);
2446599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (inputDescriptor->isSourceActive(source)) {
2447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
2448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
2451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2453275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// Register a list of custom mixes with their attributes and format.
2454275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When a mix is registered, corresponding input and output profiles are
2455275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// added to the remote submix hw module. The profile contains only the
2456275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// parameters (sampling rate, format...) specified by the mix.
2457275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// The corresponding input remote submix device is also connected.
2458275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//
2459275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When a remote submix device is connected, the address is checked to select the
2460275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// appropriate profile and the corresponding input or output stream is opened.
2461275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//
2462275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When capture starts, getInputForAttr() will:
2463275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 1 look for a mix matching the address passed in attribtutes tags if any
2464275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 2 if none found, getDeviceForInputSource() will:
2465275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//     - 2.1 look for a mix matching the attributes source
2466275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//     - 2.2 if none found, default to device selection by policy rules
2467275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// At this time, the corresponding output remote submix device is also connected
2468275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// and active playback use cases can be transferred to this mix if needed when reconnecting
2469275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// after AudioTracks are invalidated
2470275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//
2471275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When playback starts, getOutputForAttr() will:
2472275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 1 look for a mix matching the address passed in attribtutes tags if any
2473275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 2 if none found, look for a mix matching the attributes usage
2474275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 3 if none found, default to device and output selection by policy rules.
2475275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
2476e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t AudioPolicyManager::registerPolicyMixes(const Vector<AudioMix>& mixes)
2477275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{
24787638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    ALOGV("registerPolicyMixes() %zu mix(es)", mixes.size());
24797638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    status_t res = NO_ERROR;
24807638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
24817638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    sp<HwModule> rSubmixModule;
24827638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    // examine each mix's route type
24837638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    for (size_t i = 0; i < mixes.size(); i++) {
24847638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        // we only support MIX_ROUTE_FLAG_LOOP_BACK or MIX_ROUTE_FLAG_RENDER, not the combination
24857638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_ALL) == MIX_ROUTE_FLAG_ALL) {
24867638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            res = INVALID_OPERATION;
2487275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            break;
2488275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
24897638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
24907638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            ALOGV("registerPolicyMixes() mix %zu of %zu is LOOP_BACK", i, mixes.size());
24917638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (rSubmixModule == 0) {
2492d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                rSubmixModule = mHwModules.getModuleFromName(
2493d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                        AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX);
2494d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                if (rSubmixModule == 0) {
2495d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                    ALOGE(" Unable to find audio module for submix, aborting mix %zu registration",
2496d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                            i);
2497d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                    res = INVALID_OPERATION;
2498d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                    break;
2499d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                }
25007638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2501275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
25027638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            String8 address = mixes[i].mDeviceAddress;
2503036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie
25047638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (mPolicyMixes.registerMix(address, mixes[i], 0 /*output desc*/) != NO_ERROR) {
25055ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                ALOGE(" Error registering mix %zu for address %s", i, address.string());
25067638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
25077638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                break;
25087638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
25097638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            audio_config_t outputConfig = mixes[i].mFormat;
25107638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            audio_config_t inputConfig = mixes[i].mFormat;
25117638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            // NOTE: audio flinger mixer does not support mono output: configure remote submix HAL in
25127638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            // stereo and let audio flinger do the channel conversion if needed.
25137638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            outputConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
25147638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            inputConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO;
25157638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->addOutputProfile(address, &outputConfig,
25167638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address);
25177638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->addInputProfile(address, &inputConfig,
25187638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_DEVICE_IN_REMOTE_SUBMIX, address);
25197638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
25207638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (mixes[i].mMixType == MIX_TYPE_PLAYERS) {
25217638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
25227638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
25237638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
25247638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            } else {
25257638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
25267638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
25277638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
25287638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
25297638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        } else if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
25307638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            String8 address = mixes[i].mDeviceAddress;
25317638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            audio_devices_t device = mixes[i].mDeviceType;
25325ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi            ALOGV(" registerPolicyMixes() mix %zu of %zu is RENDER, dev=0x%X addr=%s",
25335ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                    i, mixes.size(), device, address.string());
25347638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
25355ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi            bool foundOutput = false;
25367638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            for (size_t j = 0 ; j < mOutputs.size() ; j++) {
25377638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(j);
25387638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                sp<AudioPatch> patch = mAudioPatches.valueFor(desc->getPatchHandle());
25397638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                if ((patch != 0) && (patch->mPatch.num_sinks != 0)
25407638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        && (patch->mPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE)
25417638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        && (patch->mPatch.sinks[0].ext.device.type == device)
25425ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        && (strncmp(patch->mPatch.sinks[0].ext.device.address, address.string(),
25435ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                                AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
25447638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    if (mPolicyMixes.registerMix(address, mixes[i], desc) != NO_ERROR) {
25457638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        res = INVALID_OPERATION;
25465ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                    } else {
25475ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        foundOutput = true;
25487638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    }
25497638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    break;
25507638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                }
25517638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
25527638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
25537638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (res != NO_ERROR) {
25547638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                ALOGE(" Error registering mix %zu for device 0x%X addr %s",
25555ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        i, device, address.string());
25565ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                res = INVALID_OPERATION;
25575ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                break;
25585ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi            } else if (!foundOutput) {
25595ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                ALOGE(" Output not found for mix %zu for device 0x%X addr %s",
25605ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        i, device, address.string());
25617638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
25627638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                break;
25637638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2564c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        }
2565275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
25667638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    if (res != NO_ERROR) {
25677638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        unregisterPolicyMixes(mixes);
25687638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    }
25697638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    return res;
2570275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent}
2571275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
2572275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentstatus_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes)
2573275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{
25747b279bbc24139ee1e01b58055ca94926ec18e2e9Eric Laurent    ALOGV("unregisterPolicyMixes() num mixes %zu", mixes.size());
25757638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    status_t res = NO_ERROR;
25767638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    sp<HwModule> rSubmixModule;
25777638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    // examine each mix's route type
2578cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    for (const auto& mix : mixes) {
2579cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        if ((mix.mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
25807638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
25817638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (rSubmixModule == 0) {
2582d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                rSubmixModule = mHwModules.getModuleFromName(
2583d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                        AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX);
2584d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                if (rSubmixModule == 0) {
2585d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                    res = INVALID_OPERATION;
2586d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                    continue;
25877638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                }
25887638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2589036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie
2590cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov            String8 address = mix.mDeviceAddress;
2591275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
25927638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (mPolicyMixes.unregisterMix(address) != NO_ERROR) {
25937638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
25947638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                continue;
25957638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2596275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
25977638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (getDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, address.string()) ==
25987638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE)  {
25997638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
26007638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
26017638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
26027638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
26037638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) ==
26047638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE)  {
26057638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
26067638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
26077638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
26087638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
26097638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->removeOutputProfile(address);
26107638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->removeInputProfile(address);
26117638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
2612cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        } if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
2613cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov            if (mPolicyMixes.unregisterMix(mix.mDeviceAddress) != NO_ERROR) {
26147638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
26157638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                continue;
26167638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2617275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
2618275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
26197638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    return res;
2620275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent}
2621275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
2622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2623e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::dump(int fd)
2624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
2626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
2627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
2628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
2630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
2631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
263287ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    snprintf(buffer, SIZE, " Primary Output: %d\n",
263387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent             hasPrimaryOutput() ? mPrimaryOutput->mIoHandle : AUDIO_IO_HANDLE_NONE);
2634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
26350d6a03301d77724c00c7a9ce7b8c123092d07a19Mikhail Naganov    std::string stateLiteral;
26360d6a03301d77724c00c7a9ce7b8c123092d07a19Mikhail Naganov    AudioModeConverter::toString(mEngine->getPhoneState(), stateLiteral);
26370d6a03301d77724c00c7a9ce7b8c123092d07a19Mikhail Naganov    snprintf(buffer, SIZE, " Phone state: %s\n", stateLiteral.c_str());
2638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
26393b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for communications %d\n",
26402110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie             mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION));
2641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
26422110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for media %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA));
2643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
26442110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for record %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD));
2645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
26462110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for dock %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK));
2647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
26482110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for system %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM));
2649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
26507b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang    snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n",
26512110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO));
26527b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang    result.append(buffer);
265309bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    snprintf(buffer, SIZE, " Force use for encoded surround output %d\n",
265409bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND));
265509bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    result.append(buffer);
26569459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    snprintf(buffer, SIZE, " TTS output %s\n", mTtsOutputAvailable ? "available" : "not available");
26579459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    result.append(buffer);
26582ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    snprintf(buffer, SIZE, " Master mono: %s\n", mMasterMono ? "on" : "off");
26592ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    result.append(buffer);
26609459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent
26612110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    write(fd, result.string(), result.size());
2662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2663112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    mAvailableOutputDevices.dump(fd, String8("Available output"));
2664112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    mAvailableInputDevices.dump(fd, String8("Available input"));
2665d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov    mHwModulesAll.dump(fd);
266653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mOutputs.dump(fd);
266753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mInputs.dump(fd);
2668d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves->dump(fd);
266945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    mEffects.dump(fd);
267053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mAudioPatches.dump(fd);
267144344b05261cb9ad46a43e635f637b89aecc7afeMikhail Naganov    mPolicyMixes.dump(fd);
2672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
2674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This function checks for the parameters which can be offloaded.
2677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This can be enhanced depending on the capability of the DSP and policy
2678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// of the system.
2679e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
2680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
2682d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent     " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
2683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.sample_rate, offloadInfo.channel_mask,
2684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.format,
2685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
2686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.has_video);
2687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
26882ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    if (mMasterMono) {
26892ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        return false; // no offloading if mono is set.
26902ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
26912ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung
2692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check if offload has been disabled
2693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char propValue[PROPERTY_VALUE_MAX];
2694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (property_get("audio.offload.disable", propValue, "0")) {
2695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (atoi(propValue) != 0) {
2696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("offload disabled by audio.offload.disable=%s", propValue );
2697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
2698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check if stream type is music, then only allow offload as of now.
2702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
2703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
2704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
2705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //TODO: enable audio offloading with video when ready
270908945c44a97d3749cc48f860eb4e01e57183ad90Andy Hung    const bool allowOffloadWithVideo =
271008945c44a97d3749cc48f860eb4e01e57183ad90Andy Hung            property_get_bool("audio.offload.video", false /* default_value */);
271108945c44a97d3749cc48f860eb4e01e57183ad90Andy Hung    if (offloadInfo.has_video && !allowOffloadWithVideo) {
2712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("isOffloadSupported: has_video == true, returning false");
2713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //If duration is less than minimum value defined in property, return false
2717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
2718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
2719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
2720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
2721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
2723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
2724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not allow offloading if one non offloadable effect is enabled. This prevents from
2728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // creating an offloaded track and tearing it down immediately after start when audioflinger
2729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // detects there is an active non offloadable effect.
2730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // FIXME: We should check the audio session here but we do not have it in this context.
2731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // This may prevent offloading in rare situations where effects are left active by apps
2732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the background.
273345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    if (mEffects.isNonOffloadableEffectEnabled()) {
2734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // See if there is a profile to support this.
2738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // AUDIO_DEVICE_NONE
27391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
2740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.sample_rate,
2741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.format,
2742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.channel_mask,
2743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
27441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
27451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return (profile != 0);
2746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
27486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
27496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            audio_port_type_t type,
27506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            unsigned int *num_ports,
27516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            struct audio_port *ports,
27526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            unsigned int *generation)
27536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
27546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (num_ports == NULL || (*num_ports != 0 && ports == NULL) ||
27556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            generation == NULL) {
27566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
27576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
27586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports);
27596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (ports == NULL) {
27606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        *num_ports = 0;
27616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
27626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
27636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    size_t portsWritten = 0;
27646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    size_t portsMax = *num_ports;
27656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    *num_ports = 0;
27666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) {
27675a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent        // do not report devices with type AUDIO_DEVICE_IN_STUB or AUDIO_DEVICE_OUT_STUB
27685a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent        // as they are used by stub HALs by convention
27696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
2770cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov            for (const auto& dev : mAvailableOutputDevices) {
2771cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                if (dev->type() == AUDIO_DEVICE_OUT_STUB) {
27725a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                    continue;
27735a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
27745a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                if (portsWritten < portsMax) {
2775cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                    dev->toAudioPort(&ports[portsWritten++]);
27765a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
27775a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                (*num_ports)++;
27786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
27796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
27806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
2781cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov            for (const auto& dev : mAvailableInputDevices) {
2782cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                if (dev->type() == AUDIO_DEVICE_IN_STUB) {
27835a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                    continue;
27845a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
27855a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                if (portsWritten < portsMax) {
2786cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                    dev->toAudioPort(&ports[portsWritten++]);
27875a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
27885a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                (*num_ports)++;
27896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
27906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
27916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
27926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) {
27936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
27946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++) {
27956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                mInputs[i]->toAudioPort(&ports[portsWritten++]);
27966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
27976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            *num_ports += mInputs.size();
27986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
27996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
280084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            size_t numOutputs = 0;
280184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            for (size_t i = 0; i < mOutputs.size(); i++) {
280284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                if (!mOutputs[i]->isDuplicated()) {
280384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                    numOutputs++;
280484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                    if (portsWritten < portsMax) {
280584c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                        mOutputs[i]->toAudioPort(&ports[portsWritten++]);
280684c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                    }
280784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                }
28086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
280984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            *num_ports += numOutputs;
28106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
28116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
28126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    *generation = curAudioPortGeneration();
2813beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn    ALOGV("listAudioPorts() got %zu ports needed %d", portsWritten, *num_ports);
28146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return NO_ERROR;
28156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
28166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
281799fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurentstatus_t AudioPolicyManager::getAudioPort(struct audio_port *port)
28186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
281999fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    if (port == nullptr || port->id == AUDIO_PORT_HANDLE_NONE) {
282099fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent        return BAD_VALUE;
282199fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    }
282299fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    sp<DeviceDescriptor> dev = mAvailableOutputDevices.getDeviceFromId(port->id);
282399fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    if (dev != 0) {
282499fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent        dev->toAudioPort(port);
282599fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent        return NO_ERROR;
282699fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    }
282799fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    dev = mAvailableInputDevices.getDeviceFromId(port->id);
282899fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    if (dev != 0) {
282999fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent        dev->toAudioPort(port);
283099fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent        return NO_ERROR;
283199fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    }
283299fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    sp<SwAudioOutputDescriptor> out = mOutputs.getOutputFromId(port->id);
283399fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    if (out != 0) {
283499fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent        out->toAudioPort(port);
283599fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent        return NO_ERROR;
283699fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    }
283799fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    sp<AudioInputDescriptor> in = mInputs.getInputFromId(port->id);
283899fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    if (in != 0) {
283999fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent        in->toAudioPort(port);
284099fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent        return NO_ERROR;
284199fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    }
284299fcae46d54639e7841d87b1dcacbc229bbf8dc4Eric Laurent    return BAD_VALUE;
28436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
28446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
28456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,
28466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               audio_patch_handle_t *handle,
28476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               uid_t uid)
28486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
28496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("createAudioPatch()");
28506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
28516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (handle == NULL || patch == NULL) {
28526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
28536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
28546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks);
28556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
2856874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
2857874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
2858874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        return BAD_VALUE;
2859874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    }
2860874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    // only one source per audio patch supported for now
2861874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    if (patch->num_sources > 1) {
28626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return INVALID_OPERATION;
28636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
2864874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
2865874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    if (patch->sources[0].role != AUDIO_PORT_ROLE_SOURCE) {
28666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return INVALID_OPERATION;
28676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
2868874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    for (size_t i = 0; i < patch->num_sinks; i++) {
2869874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        if (patch->sinks[i].role != AUDIO_PORT_ROLE_SINK) {
2870874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            return INVALID_OPERATION;
2871874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        }
2872874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    }
28736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
28746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp<AudioPatch> patchDesc;
28756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index = mAudioPatches.indexOfKey(*handle);
28766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
28776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("createAudioPatch source id %d role %d type %d", patch->sources[0].id,
28786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                           patch->sources[0].role,
28796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                           patch->sources[0].type);
2880874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent#if LOG_NDEBUG == 0
2881874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    for (size_t i = 0; i < patch->num_sinks; i++) {
28827b279bbc24139ee1e01b58055ca94926ec18e2e9Eric Laurent        ALOGV("createAudioPatch sink %zu: id %d role %d type %d", i, patch->sinks[i].id,
2883874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                                                             patch->sinks[i].role,
2884874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                                                             patch->sinks[i].type);
2885874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    }
2886874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent#endif
28876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
28886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index >= 0) {
28896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        patchDesc = mAudioPatches.valueAt(index);
28906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        ALOGV("createAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
28916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  mUidCached, patchDesc->mUid, uid);
28926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
28936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return INVALID_OPERATION;
28946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
28956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
2896a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten        *handle = AUDIO_PATCH_HANDLE_NONE;
28976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
28986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
28996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
2900c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
29016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (outputDesc == NULL) {
29026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id);
29036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
29046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
290584c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent        ALOG_ASSERT(!outputDesc->isDuplicated(),"duplicated output %d in source in ports",
290684c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                                                outputDesc->mIoHandle);
29076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc != 0) {
29086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
29096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGV("createAudioPatch() source id differs for patch current id %d new id %d",
29106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                          patchDesc->mPatch.sources[0].id, patch->sources[0].id);
29116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
29126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
29136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
2914874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        DeviceVector devices;
2915874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        for (size_t i = 0; i < patch->num_sinks; i++) {
2916874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            // Only support mix to devices connection
2917874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            // TODO add support for mix to mix connection
2918874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2919874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                ALOGV("createAudioPatch() source mix but sink is not a device");
2920874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return INVALID_OPERATION;
2921874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
2922874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            sp<DeviceDescriptor> devDesc =
2923874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2924874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            if (devDesc == 0) {
2925874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                ALOGV("createAudioPatch() out device not found for id %d", patch->sinks[i].id);
2926874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return BAD_VALUE;
2927874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
29286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
292953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if (!outputDesc->mProfile->isCompatibleProfile(devDesc->type(),
2930275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                           devDesc->mAddress,
2931874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                                                           patch->sources[0].sample_rate,
293253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           NULL,  // updatedSamplingRate
293353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           patch->sources[0].format,
2934f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                           NULL,  // updatedFormat
293553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           patch->sources[0].channel_mask,
2936f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                           NULL,  // updatedChannelMask
293753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) {
2938f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                ALOGV("createAudioPatch() profile not supported for device %08x",
2939f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                        devDesc->type());
2940874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return INVALID_OPERATION;
2941874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
2942874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            devices.add(devDesc);
2943874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        }
2944874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        if (devices.size() == 0) {
29456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return INVALID_OPERATION;
29466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
2947874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
29486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        // TODO: reconfigure output format and channels here
29496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        ALOGV("createAudioPatch() setting device %08x on output %d",
2950874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent              devices.types(), outputDesc->mIoHandle);
2951c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        setOutputDevice(outputDesc, devices.types(), true, 0, handle);
29526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        index = mAudioPatches.indexOfKey(*handle);
29536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (index >= 0) {
29546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
29556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("createAudioPatch() setOutputDevice() did not reuse the patch provided");
29566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
29576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            patchDesc = mAudioPatches.valueAt(index);
29586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            patchDesc->mUid = uid;
29596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() success");
29606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else {
29616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGW("createAudioPatch() setOutputDevice() failed to create a patch");
29626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return INVALID_OPERATION;
29636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
29646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
29656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
29666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // input device to input mix connection
2967874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            // only one sink supported when connecting an input device to a mix
2968874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            if (patch->num_sinks > 1) {
2969874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return INVALID_OPERATION;
2970874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
297153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
29726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (inputDesc == NULL) {
29736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
29746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
29756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc != 0) {
29766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) {
29776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    return BAD_VALUE;
29786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
29796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
29806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp<DeviceDescriptor> devDesc =
29816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
29826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (devDesc == 0) {
29836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
29846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
29856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
298653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if (!inputDesc->mProfile->isCompatibleProfile(devDesc->type(),
2987275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          devDesc->mAddress,
2988275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          patch->sinks[0].sample_rate,
2989275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          NULL, /*updatedSampleRate*/
2990275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          patch->sinks[0].format,
2991f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                          NULL, /*updatedFormat*/
2992275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          patch->sinks[0].channel_mask,
2993f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                          NULL, /*updatedChannelMask*/
2994275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          // FIXME for the parameter type,
2995275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          // and the NONE
2996275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          (audio_output_flags_t)
29976a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten                                                            AUDIO_INPUT_FLAG_NONE)) {
29986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
29996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
30006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // TODO: reconfigure output format and channels here
30016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() setting device %08x on output %d",
300253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  devDesc->type(), inputDesc->mIoHandle);
300353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            setInputDevice(inputDesc->mIoHandle, devDesc->type(), true, handle);
30046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            index = mAudioPatches.indexOfKey(*handle);
30056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
30066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
30076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    ALOGW("createAudioPatch() setInputDevice() did not reuse the patch provided");
30086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
30096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc = mAudioPatches.valueAt(index);
30106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mUid = uid;
30116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGV("createAudioPatch() success");
30126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
30136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("createAudioPatch() setInputDevice() failed to create a patch");
30146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
30156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
30166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
30176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // device to device connection
30186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc != 0) {
3019874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
30206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    return BAD_VALUE;
30216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
30226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
30236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp<DeviceDescriptor> srcDeviceDesc =
30246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
302558f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent            if (srcDeviceDesc == 0) {
302658f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent                return BAD_VALUE;
302758f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent            }
3028874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
30296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            //update source and sink with our own data as the data passed in the patch may
30306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // be incomplete.
30316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            struct audio_patch newPatch = *patch;
30326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]);
3033874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
3034874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            for (size_t i = 0; i < patch->num_sinks; i++) {
3035874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
3036874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    ALOGV("createAudioPatch() source device but one sink is not a device");
3037874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    return INVALID_OPERATION;
3038874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                }
3039874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
3040874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                sp<DeviceDescriptor> sinkDeviceDesc =
3041874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
3042874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                if (sinkDeviceDesc == 0) {
3043874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    return BAD_VALUE;
3044874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                }
3045874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]);
3046874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
30473bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                // create a software bridge in PatchPanel if:
3048f317240cde612c3509c7d0950484516ed33fd664Scott Randolph                // - source and sink devices are on different HW modules OR
30493bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                // - audio HAL version is < 3.0
3050fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                if (!srcDeviceDesc->hasSameHwModuleAs(sinkDeviceDesc) ||
30519ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov                        (srcDeviceDesc->mModule->getHalVersionMajor() < 3)) {
30523bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                    // support only one sink device for now to simplify output selection logic
3053874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    if (patch->num_sinks > 1) {
305483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                        return INVALID_OPERATION;
305583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                    }
3056874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    SortedVector<audio_io_handle_t> outputs =
305753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                            getOutputsForDevice(sinkDeviceDesc->type(), mOutputs);
3058874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    // if the sink device is reachable via an opened output stream, request to go via
3059874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    // this output stream by adding a second source to the patch description
30608838a3895c365d443ee22e169ccf45956780c081Eric Laurent                    audio_io_handle_t output = selectOutput(outputs,
30618838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                            AUDIO_OUTPUT_FLAG_NONE,
30628838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                            AUDIO_FORMAT_INVALID);
3063874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    if (output != AUDIO_IO_HANDLE_NONE) {
3064874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
3065874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        if (outputDesc->isDuplicated()) {
3066874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                            return INVALID_OPERATION;
3067874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        }
3068874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        outputDesc->toAudioPortConfig(&newPatch.sources[1], &patch->sources[0]);
30693bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                        newPatch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
3070874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        newPatch.num_sources = 2;
3071874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    }
307283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                }
30736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
30746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // TODO: check from routing capabilities in config file and other conflicting patches
30756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
30766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
30776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
30786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                afPatchHandle = patchDesc->mAfPatchHandle;
30796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
30806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
30816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            status_t status = mpClientInterface->createAudioPatch(&newPatch,
30826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  &afPatchHandle,
30836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  0);
30846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() patch panel returned %d patchHandle %d",
30856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  status, afPatchHandle);
30866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (status == NO_ERROR) {
30876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (index < 0) {
308898cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie                    patchDesc = new AudioPatch(&newPatch, uid);
30896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    addAudioPatch(patchDesc->mHandle, patchDesc);
30906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                } else {
30916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    patchDesc->mPatch = newPatch;
30926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
30936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mAfPatchHandle = afPatchHandle;
30946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                *handle = patchDesc->mHandle;
30956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                nextAudioPortGeneration();
3096b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                mpClientInterface->onAudioPatchListUpdate();
30976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
30986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("createAudioPatch() patch panel could not connect device patch, error %d",
30996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                status);
31006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
31016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
31026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else {
31036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
31046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
31056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
31066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
31076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
31086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return NO_ERROR;
31096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
31106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
31116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle,
31126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                  uid_t uid)
31136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
31146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("releaseAudioPatch() patch %d", handle);
31156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
31166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index = mAudioPatches.indexOfKey(handle);
31176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
31186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index < 0) {
31196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
31206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
31216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
31226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("releaseAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
31236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent          mUidCached, patchDesc->mUid, uid);
31246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
31256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return INVALID_OPERATION;
31266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
31276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
31286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    struct audio_patch *patch = &patchDesc->mPatch;
31296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    patchDesc->mUid = mUidCached;
31306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
3131c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
31326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (outputDesc == NULL) {
31336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id);
31346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
31356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
31366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
3137c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        setOutputDevice(outputDesc,
3138c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                        getNewOutputDevice(outputDesc, true /*fromCache*/),
31396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                       true,
31406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                       0,
31416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                       NULL);
31426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
31436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
314453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
31456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (inputDesc == NULL) {
31466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id);
31476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
31486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
31496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            setInputDevice(inputDesc->mIoHandle,
3150fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                           getNewInputDevice(inputDesc),
31516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                           true,
31526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                           NULL);
31536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
31546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
31556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("releaseAudioPatch() patch panel returned %d patchHandle %d",
31566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                              status, patchDesc->mAfPatchHandle);
31576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            removeAudioPatch(patchDesc->mHandle);
31586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            nextAudioPortGeneration();
3159b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent            mpClientInterface->onAudioPatchListUpdate();
31606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else {
31616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
31626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
31636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
31646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
31656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
31666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return NO_ERROR;
31676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
31686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
31696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches,
31706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                              struct audio_patch *patches,
31716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                              unsigned int *generation)
31726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
317353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    if (generation == NULL) {
31746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
31756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
31766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    *generation = curAudioPortGeneration();
317753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return mAudioPatches.listAudioPatches(num_patches, patches);
31786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
31796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
3180e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config)
31816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
3182e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    ALOGV("setAudioPortConfig()");
3183e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
3184e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    if (config == NULL) {
3185e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        return BAD_VALUE;
3186e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
3187e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    ALOGV("setAudioPortConfig() on port handle %d", config->id);
3188e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    // Only support gain configuration for now
3189a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    if (config->config_mask != AUDIO_PORT_CONFIG_GAIN) {
3190a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        return INVALID_OPERATION;
3191e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
3192e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
3193a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    sp<AudioPortConfig> audioPortConfig;
3194e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    if (config->type == AUDIO_PORT_TYPE_MIX) {
3195e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        if (config->role == AUDIO_PORT_ROLE_SOURCE) {
3196c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(config->id);
3197e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            if (outputDesc == NULL) {
3198e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                return BAD_VALUE;
3199e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            }
320084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            ALOG_ASSERT(!outputDesc->isDuplicated(),
320184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                        "setAudioPortConfig() called on duplicated output %d",
320284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                        outputDesc->mIoHandle);
3203a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent            audioPortConfig = outputDesc;
3204e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else if (config->role == AUDIO_PORT_ROLE_SINK) {
320553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(config->id);
3206e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            if (inputDesc == NULL) {
3207e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                return BAD_VALUE;
3208e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            }
3209a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent            audioPortConfig = inputDesc;
3210e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else {
3211e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            return BAD_VALUE;
3212e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        }
3213e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    } else if (config->type == AUDIO_PORT_TYPE_DEVICE) {
3214e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        sp<DeviceDescriptor> deviceDesc;
3215e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        if (config->role == AUDIO_PORT_ROLE_SOURCE) {
3216e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id);
3217e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else if (config->role == AUDIO_PORT_ROLE_SINK) {
3218e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id);
3219e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else {
3220e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            return BAD_VALUE;
3221e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        }
3222e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        if (deviceDesc == NULL) {
3223e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            return BAD_VALUE;
3224e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        }
3225a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        audioPortConfig = deviceDesc;
3226e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    } else {
3227e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        return BAD_VALUE;
3228e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
3229e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
3230a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    struct audio_port_config backupConfig;
3231a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig);
3232a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    if (status == NO_ERROR) {
3233a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        struct audio_port_config newConfig;
3234a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        audioPortConfig->toAudioPortConfig(&newConfig, config);
3235a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        status = mpClientInterface->setAudioPortConfig(&newConfig, 0);
3236e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
3237a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    if (status != NO_ERROR) {
3238a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        audioPortConfig->applyAudioPortConfig(&backupConfig);
3239e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
3240e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
3241e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    return status;
32426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
32436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
32448c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurentvoid AudioPolicyManager::releaseResourcesForUid(uid_t uid)
32458c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent{
3246d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    clearAudioSources(uid);
32478c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    clearAudioPatches(uid);
32488c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    clearSessionRoutes(uid);
32498c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent}
32508c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
32516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentvoid AudioPolicyManager::clearAudioPatches(uid_t uid)
32526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
32530add0fd07401c507a77b37868f46a2ae587c30dfEric Laurent    for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--)  {
32546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
32556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid == uid) {
32560add0fd07401c507a77b37868f46a2ae587c30dfEric Laurent            releaseAudioPatch(mAudioPatches.keyAt(i), uid);
32576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
32586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
32596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
32606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
32618c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurentvoid AudioPolicyManager::checkStrategyRoute(routing_strategy strategy,
32628c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                            audio_io_handle_t ouptutToSkip)
32638c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent{
32648c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
32658c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
32668c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t j = 0; j < mOutputs.size(); j++) {
32678c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (mOutputs.keyAt(j) == ouptutToSkip) {
32688c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            continue;
32698c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
32708c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(j);
32718c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (!isStrategyActive(outputDesc, (routing_strategy)strategy)) {
32728c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            continue;
32738c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
32748c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        // If the default device for this strategy is on another output mix,
32758c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        // invalidate all tracks in this strategy to force re connection.
32768c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        // Otherwise select new device on the output mix.
32778c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (outputs.indexOf(mOutputs.keyAt(j)) < 0) {
3278794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
32798c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                if (getStrategy((audio_stream_type_t)stream) == strategy) {
32808c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                    mpClientInterface->invalidateStream((audio_stream_type_t)stream);
32818c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                }
32828c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            }
32838c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        } else {
32848c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
32858c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            setOutputDevice(outputDesc, newDevice, false);
32868c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
32878c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
32888c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent}
32898c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
32908c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurentvoid AudioPolicyManager::clearSessionRoutes(uid_t uid)
32918c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent{
32928c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // remove output routes associated with this uid
32938c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<routing_strategy> affectedStrategies;
32948c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (ssize_t i = (ssize_t)mOutputRoutes.size() - 1; i >= 0; i--)  {
32958c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<SessionRoute> route = mOutputRoutes.valueAt(i);
32968c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (route->mUid == uid) {
32978c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            mOutputRoutes.removeItemsAt(i);
32988c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            if (route->mDeviceDescriptor != 0) {
32998c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                affectedStrategies.add(getStrategy(route->mStreamType));
33008c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            }
33018c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
33028c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
33038c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // reroute outputs if necessary
3304cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    for (const auto& strategy : affectedStrategies) {
3305cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        checkStrategyRoute(strategy, AUDIO_IO_HANDLE_NONE);
33068c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
33078c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
33088c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // remove input routes associated with this uid
33098c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<audio_source_t> affectedSources;
33108c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (ssize_t i = (ssize_t)mInputRoutes.size() - 1; i >= 0; i--)  {
33118c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<SessionRoute> route = mInputRoutes.valueAt(i);
33128c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (route->mUid == uid) {
33138c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            mInputRoutes.removeItemsAt(i);
33148c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            if (route->mDeviceDescriptor != 0) {
33158c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                affectedSources.add(route->mSource);
33168c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            }
33178c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
33188c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
33198c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // reroute inputs if necessary
33208c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<audio_io_handle_t> inputsToClose;
33218c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
33228c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(i);
3323599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (affectedSources.indexOf(inputDesc->inputSource()) >= 0) {
33248c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            inputsToClose.add(inputDesc->mIoHandle);
33258c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
33268c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
3327cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    for (const auto& input : inputsToClose) {
3328cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        closeInput(input);
33298c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
33308c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent}
33318c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
3332d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentvoid AudioPolicyManager::clearAudioSources(uid_t uid)
3333d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
3334d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--)  {
3335d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
3336d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (sourceDesc->mUid == uid) {
3337d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            stopAudioSource(mAudioSources.keyAt(i));
3338d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3339d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3340d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
33418c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
3342df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentstatus_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session,
3343df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent                                       audio_io_handle_t *ioHandle,
3344df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent                                       audio_devices_t *device)
3345df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{
3346f0c6d7d940314dbec47c9b53cb99da79eb022787Glenn Kasten    *session = (audio_session_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
3347f0c6d7d940314dbec47c9b53cb99da79eb022787Glenn Kasten    *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_INPUT);
3348c73ca6ef04136f28306784ad35f444538f081957Eric Laurent    *device = getDeviceAndMixForInputSource(AUDIO_SOURCE_HOTWORD);
3349df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
3350df37269852ea92bafd939fe793209d0581c4a574François Gaffie    return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
3351df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent}
3352df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
3353d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source,
3354d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                  const audio_attributes_t *attributes,
3355559d439c6fe8679e3c52f1cf265d46d7d2e65b68Glenn Kasten                                  audio_patch_handle_t *handle,
3356d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                  uid_t uid)
3357554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent{
3358d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s source %p attributes %p handle %p", __FUNCTION__, source, attributes, handle);
3359d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (source == NULL || attributes == NULL || handle == NULL) {
3360d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
3361d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3362d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3363559d439c6fe8679e3c52f1cf265d46d7d2e65b68Glenn Kasten    *handle = AUDIO_PATCH_HANDLE_NONE;
3364d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3365d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (source->role != AUDIO_PORT_ROLE_SOURCE ||
3366d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            source->type != AUDIO_PORT_TYPE_DEVICE) {
3367d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s INVALID_OPERATION source->role %d source->type %d", __FUNCTION__, source->role, source->type);
3368d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return INVALID_OPERATION;
3369d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3370d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3371d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<DeviceDescriptor> srcDeviceDesc =
3372d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            mAvailableInputDevices.getDevice(source->ext.device.type,
3373d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                              String8(source->ext.device.address));
3374d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (srcDeviceDesc == 0) {
3375d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s source->ext.device.type %08x not found", __FUNCTION__, source->ext.device.type);
3376d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
3377d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3378d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioSourceDescriptor> sourceDesc =
3379d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            new AudioSourceDescriptor(srcDeviceDesc, attributes, uid);
3380d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3381d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    struct audio_patch dummyPatch;
3382d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioPatch> patchDesc = new AudioPatch(&dummyPatch, uid);
3383d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sourceDesc->mPatchDesc = patchDesc;
3384d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3385d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    status_t status = connectAudioSource(sourceDesc);
3386d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (status == NO_ERROR) {
3387d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        mAudioSources.add(sourceDesc->getHandle(), sourceDesc);
3388d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        *handle = sourceDesc->getHandle();
3389d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3390d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return status;
3391d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
3392d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3393d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t AudioPolicyManager::connectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
3394d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
3395d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
3396d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3397d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    // make sure we only have one patch per source.
3398d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    disconnectAudioSource(sourceDesc);
3399d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3400d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    routing_strategy strategy = (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
340128d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
3402d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<DeviceDescriptor> srcDeviceDesc = sourceDesc->mDevice;
3403d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3404d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    audio_devices_t sinkDevice = getDeviceForStrategy(strategy, true);
3405d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<DeviceDescriptor> sinkDeviceDesc =
3406d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            mAvailableOutputDevices.getDevice(sinkDevice, String8(""));
3407d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3408d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
3409d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    struct audio_patch *patch = &sourceDesc->mPatchDesc->mPatch;
3410d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3411d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (srcDeviceDesc->getAudioPort()->mModule->getHandle() ==
3412d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            sinkDeviceDesc->getAudioPort()->mModule->getHandle() &&
34139ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov            srcDeviceDesc->getAudioPort()->mModule->getHalVersionMajor() >= 3 &&
3414d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            srcDeviceDesc->getAudioPort()->mGains.size() > 0) {
3415d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s AUDIO_DEVICE_API_VERSION_3_0", __FUNCTION__);
3416d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        //   create patch between src device and output device
3417d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        //   create Hwoutput and add to mHwOutputs
3418d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    } else {
3419d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(sinkDevice, mOutputs);
3420d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        audio_io_handle_t output =
3421d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
3422d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (output == AUDIO_IO_HANDLE_NONE) {
3423d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s no output for device %08x", __FUNCTION__, sinkDevice);
3424d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return INVALID_OPERATION;
3425d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3426d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
3427d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (outputDesc->isDuplicated()) {
3428d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s output for device %08x is duplicated", __FUNCTION__, sinkDevice);
3429d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return INVALID_OPERATION;
3430d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3431733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        status_t status = outputDesc->start();
3432733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        if (status != NO_ERROR) {
3433733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            return status;
3434733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        }
3435733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent
3436d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // create a special patch with no sink and two sources:
3437d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // - the second source indicates to PatchPanel through which output mix this patch should
3438d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // be connected as well as the stream type for volume control
3439d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // - the sink is defined by whatever output device is currently selected for the output
3440d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // though which this patch is routed.
3441d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        patch->num_sinks = 0;
3442d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        patch->num_sources = 2;
3443d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        srcDeviceDesc->toAudioPortConfig(&patch->sources[0], NULL);
3444d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        outputDesc->toAudioPortConfig(&patch->sources[1], NULL);
3445d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        patch->sources[1].ext.mix.usecase.stream = stream;
3446733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        status = mpClientInterface->createAudioPatch(patch,
3447d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                              &afPatchHandle,
3448d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                              0);
3449d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s patch panel returned %d patchHandle %d", __FUNCTION__,
3450d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                              status, afPatchHandle);
3451d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (status != NO_ERROR) {
3452d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGW("%s patch panel could not connect device patch, error %d",
3453d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                  __FUNCTION__, status);
3454d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return INVALID_OPERATION;
3455d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3456d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        uint32_t delayMs = 0;
3457c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        status = startSource(outputDesc, stream, sinkDevice, NULL, &delayMs);
3458d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3459d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (status != NO_ERROR) {
3460d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            mpClientInterface->releaseAudioPatch(sourceDesc->mPatchDesc->mAfPatchHandle, 0);
3461d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return status;
3462d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3463d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sourceDesc->mSwOutput = outputDesc;
3464d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (delayMs != 0) {
3465d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            usleep(delayMs * 1000);
3466d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3467d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3468d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3469d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sourceDesc->mPatchDesc->mAfPatchHandle = afPatchHandle;
3470d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    addAudioPatch(sourceDesc->mPatchDesc->mHandle, sourceDesc->mPatchDesc);
3471d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3472d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return NO_ERROR;
3473554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent}
3474554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent
3475559d439c6fe8679e3c52f1cf265d46d7d2e65b68Glenn Kastenstatus_t AudioPolicyManager::stopAudioSource(audio_patch_handle_t handle __unused)
3476554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent{
3477d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueFor(handle);
3478d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s handle %d", __FUNCTION__, handle);
3479d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (sourceDesc == 0) {
3480d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGW("%s unknown source for handle %d", __FUNCTION__, handle);
3481d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
3482d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3483d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    status_t status = disconnectAudioSource(sourceDesc);
3484d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3485d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    mAudioSources.removeItem(handle);
3486d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return status;
3487d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
3488d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
34892ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hungstatus_t AudioPolicyManager::setMasterMono(bool mono)
34902ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung{
34912ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    if (mMasterMono == mono) {
34922ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        return NO_ERROR;
34932ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
34942ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    mMasterMono = mono;
34952ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // if enabling mono we close all offloaded devices, which will invalidate the
34962ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // corresponding AudioTrack. The AudioTrack client/MediaPlayer is responsible
34972ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // for recreating the new AudioTrack as non-offloaded PCM.
34982ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    //
34992ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // If disabling mono, we leave all tracks as is: we don't know which clients
35002ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // and tracks are able to be recreated as offloaded. The next "song" should
35012ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // play back offloaded.
35022ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    if (mMasterMono) {
35032ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        Vector<audio_io_handle_t> offloaded;
35042ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        for (size_t i = 0; i < mOutputs.size(); ++i) {
35052ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
35062ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            if (desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
35072ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung                offloaded.push(desc->mIoHandle);
35082ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            }
35092ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        }
3510cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        for (const auto& handle : offloaded) {
3511cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov            closeOutput(handle);
35122ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        }
35132ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
35142ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // update master mono for all remaining outputs
35152ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    for (size_t i = 0; i < mOutputs.size(); ++i) {
35162ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        updateMono(mOutputs.keyAt(i));
35172ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
35182ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    return NO_ERROR;
35192ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung}
35202ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung
35212ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hungstatus_t AudioPolicyManager::getMasterMono(bool *mono)
35222ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung{
35232ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    *mono = mMasterMono;
35242ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    return NO_ERROR;
35252ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung}
35262ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung
3527ac9cef5f3288df6e65cb4488e2615cc3c07b70d0Eric Laurentfloat AudioPolicyManager::getStreamVolumeDB(
3528ac9cef5f3288df6e65cb4488e2615cc3c07b70d0Eric Laurent        audio_stream_type_t stream, int index, audio_devices_t device)
3529ac9cef5f3288df6e65cb4488e2615cc3c07b70d0Eric Laurent{
3530ac9cef5f3288df6e65cb4488e2615cc3c07b70d0Eric Laurent    return computeVolume(stream, index, device);
3531ac9cef5f3288df6e65cb4488e2615cc3c07b70d0Eric Laurent}
3532ac9cef5f3288df6e65cb4488e2615cc3c07b70d0Eric Laurent
3533817729095966c338615a8a791d2dbf774fc034efjiabinstatus_t AudioPolicyManager::getSupportedFormats(audio_io_handle_t ioHandle,
3534817729095966c338615a8a791d2dbf774fc034efjiabin                                                 FormatVector& formats) {
3535817729095966c338615a8a791d2dbf774fc034efjiabin    if (ioHandle == AUDIO_IO_HANDLE_NONE) {
3536817729095966c338615a8a791d2dbf774fc034efjiabin        return BAD_VALUE;
3537817729095966c338615a8a791d2dbf774fc034efjiabin    }
3538817729095966c338615a8a791d2dbf774fc034efjiabin    String8 reply;
3539817729095966c338615a8a791d2dbf774fc034efjiabin    reply = mpClientInterface->getParameters(
3540817729095966c338615a8a791d2dbf774fc034efjiabin            ioHandle, String8(AudioParameter::keyStreamSupportedFormats));
3541817729095966c338615a8a791d2dbf774fc034efjiabin    ALOGV("%s: supported formats %s", __FUNCTION__, reply.string());
3542817729095966c338615a8a791d2dbf774fc034efjiabin    AudioParameter repliedParameters(reply);
3543817729095966c338615a8a791d2dbf774fc034efjiabin    if (repliedParameters.get(
3544817729095966c338615a8a791d2dbf774fc034efjiabin            String8(AudioParameter::keyStreamSupportedFormats), reply) != NO_ERROR) {
3545817729095966c338615a8a791d2dbf774fc034efjiabin        ALOGE("%s: failed to retrieve format, bailing out", __FUNCTION__);
3546817729095966c338615a8a791d2dbf774fc034efjiabin        return BAD_VALUE;
3547817729095966c338615a8a791d2dbf774fc034efjiabin    }
3548817729095966c338615a8a791d2dbf774fc034efjiabin    for (auto format : formatsFromString(reply.string())) {
3549817729095966c338615a8a791d2dbf774fc034efjiabin        // Only AUDIO_FORMAT_AAC_LC will be used in Settings UI for all AAC formats.
3550817729095966c338615a8a791d2dbf774fc034efjiabin        for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
3551817729095966c338615a8a791d2dbf774fc034efjiabin            if (format == AAC_FORMATS[i]) {
3552817729095966c338615a8a791d2dbf774fc034efjiabin                format = AUDIO_FORMAT_AAC_LC;
3553817729095966c338615a8a791d2dbf774fc034efjiabin                break;
3554817729095966c338615a8a791d2dbf774fc034efjiabin            }
3555817729095966c338615a8a791d2dbf774fc034efjiabin        }
3556817729095966c338615a8a791d2dbf774fc034efjiabin        bool exist = false;
3557817729095966c338615a8a791d2dbf774fc034efjiabin        for (size_t i = 0; i < formats.size(); i++) {
3558817729095966c338615a8a791d2dbf774fc034efjiabin            if (format == formats[i]) {
3559817729095966c338615a8a791d2dbf774fc034efjiabin                exist = true;
3560817729095966c338615a8a791d2dbf774fc034efjiabin                break;
3561817729095966c338615a8a791d2dbf774fc034efjiabin            }
3562817729095966c338615a8a791d2dbf774fc034efjiabin        }
3563817729095966c338615a8a791d2dbf774fc034efjiabin        bool isSurroundFormat = false;
3564817729095966c338615a8a791d2dbf774fc034efjiabin        for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
3565817729095966c338615a8a791d2dbf774fc034efjiabin            if (SURROUND_FORMATS[i] == format) {
3566817729095966c338615a8a791d2dbf774fc034efjiabin                isSurroundFormat = true;
3567817729095966c338615a8a791d2dbf774fc034efjiabin                break;
3568817729095966c338615a8a791d2dbf774fc034efjiabin            }
3569817729095966c338615a8a791d2dbf774fc034efjiabin        }
3570817729095966c338615a8a791d2dbf774fc034efjiabin        if (!exist && isSurroundFormat) {
3571817729095966c338615a8a791d2dbf774fc034efjiabin            formats.add(format);
3572817729095966c338615a8a791d2dbf774fc034efjiabin        }
3573817729095966c338615a8a791d2dbf774fc034efjiabin    }
3574817729095966c338615a8a791d2dbf774fc034efjiabin    return NO_ERROR;
3575817729095966c338615a8a791d2dbf774fc034efjiabin}
3576817729095966c338615a8a791d2dbf774fc034efjiabin
3577817729095966c338615a8a791d2dbf774fc034efjiabinstatus_t AudioPolicyManager::getSurroundFormats(unsigned int *numSurroundFormats,
3578817729095966c338615a8a791d2dbf774fc034efjiabin                                                audio_format_t *surroundFormats,
3579817729095966c338615a8a791d2dbf774fc034efjiabin                                                bool *surroundFormatsEnabled,
3580817729095966c338615a8a791d2dbf774fc034efjiabin                                                bool reported)
3581817729095966c338615a8a791d2dbf774fc034efjiabin{
3582817729095966c338615a8a791d2dbf774fc034efjiabin    if (numSurroundFormats == NULL || (*numSurroundFormats != 0 &&
3583817729095966c338615a8a791d2dbf774fc034efjiabin            (surroundFormats == NULL || surroundFormatsEnabled == NULL))) {
3584817729095966c338615a8a791d2dbf774fc034efjiabin        return BAD_VALUE;
3585817729095966c338615a8a791d2dbf774fc034efjiabin    }
3586817729095966c338615a8a791d2dbf774fc034efjiabin    ALOGV("getSurroundFormats() numSurroundFormats %d surroundFormats %p surroundFormatsEnabled %p",
3587817729095966c338615a8a791d2dbf774fc034efjiabin            *numSurroundFormats, surroundFormats, surroundFormatsEnabled);
3588817729095966c338615a8a791d2dbf774fc034efjiabin
3589817729095966c338615a8a791d2dbf774fc034efjiabin    // Only return value if there is HDMI output.
3590817729095966c338615a8a791d2dbf774fc034efjiabin    if ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_HDMI) == 0) {
3591817729095966c338615a8a791d2dbf774fc034efjiabin        return INVALID_OPERATION;
3592817729095966c338615a8a791d2dbf774fc034efjiabin    }
3593817729095966c338615a8a791d2dbf774fc034efjiabin
3594817729095966c338615a8a791d2dbf774fc034efjiabin    size_t formatsWritten = 0;
3595817729095966c338615a8a791d2dbf774fc034efjiabin    size_t formatsMax = *numSurroundFormats;
3596817729095966c338615a8a791d2dbf774fc034efjiabin    *numSurroundFormats = 0;
3597817729095966c338615a8a791d2dbf774fc034efjiabin    FormatVector formats;
3598817729095966c338615a8a791d2dbf774fc034efjiabin    if (reported) {
3599817729095966c338615a8a791d2dbf774fc034efjiabin        // Only get surround formats which are reported by device.
3600817729095966c338615a8a791d2dbf774fc034efjiabin        // First list already open outputs that can be routed to this device
3601817729095966c338615a8a791d2dbf774fc034efjiabin        audio_devices_t device = AUDIO_DEVICE_OUT_HDMI;
3602817729095966c338615a8a791d2dbf774fc034efjiabin        SortedVector<audio_io_handle_t> outputs;
3603817729095966c338615a8a791d2dbf774fc034efjiabin        bool reportedFormatFound = false;
3604817729095966c338615a8a791d2dbf774fc034efjiabin        status_t status;
3605817729095966c338615a8a791d2dbf774fc034efjiabin        sp<SwAudioOutputDescriptor> desc;
3606817729095966c338615a8a791d2dbf774fc034efjiabin        for (size_t i = 0; i < mOutputs.size(); i++) {
3607817729095966c338615a8a791d2dbf774fc034efjiabin            desc = mOutputs.valueAt(i);
3608817729095966c338615a8a791d2dbf774fc034efjiabin            if (!desc->isDuplicated() && (desc->supportedDevices() & device)) {
3609817729095966c338615a8a791d2dbf774fc034efjiabin                outputs.add(mOutputs.keyAt(i));
3610817729095966c338615a8a791d2dbf774fc034efjiabin            }
3611817729095966c338615a8a791d2dbf774fc034efjiabin        }
3612817729095966c338615a8a791d2dbf774fc034efjiabin        // Open an output to query dynamic parameters.
3613817729095966c338615a8a791d2dbf774fc034efjiabin        DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromType(
3614817729095966c338615a8a791d2dbf774fc034efjiabin                AUDIO_DEVICE_OUT_HDMI);
3615817729095966c338615a8a791d2dbf774fc034efjiabin        for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
3616817729095966c338615a8a791d2dbf774fc034efjiabin            String8 address = hdmiOutputDevices[i]->mAddress;
3617817729095966c338615a8a791d2dbf774fc034efjiabin            for (const auto& hwModule : mHwModules) {
3618817729095966c338615a8a791d2dbf774fc034efjiabin                for (size_t i = 0; i < hwModule->getOutputProfiles().size(); i++) {
3619817729095966c338615a8a791d2dbf774fc034efjiabin                    sp<IOProfile> profile = hwModule->getOutputProfiles()[i];
3620817729095966c338615a8a791d2dbf774fc034efjiabin                    if (profile->supportDevice(AUDIO_DEVICE_OUT_HDMI) &&
3621817729095966c338615a8a791d2dbf774fc034efjiabin                            profile->supportDeviceAddress(address)) {
3622817729095966c338615a8a791d2dbf774fc034efjiabin                        size_t j;
3623817729095966c338615a8a791d2dbf774fc034efjiabin                        for (j = 0; j < outputs.size(); j++) {
3624817729095966c338615a8a791d2dbf774fc034efjiabin                            desc = mOutputs.valueFor(outputs.itemAt(j));
3625817729095966c338615a8a791d2dbf774fc034efjiabin                            if (!desc->isDuplicated() && desc->mProfile == profile) {
3626817729095966c338615a8a791d2dbf774fc034efjiabin                                break;
3627817729095966c338615a8a791d2dbf774fc034efjiabin                            }
3628817729095966c338615a8a791d2dbf774fc034efjiabin                        }
3629817729095966c338615a8a791d2dbf774fc034efjiabin                        if (j != outputs.size()) {
3630817729095966c338615a8a791d2dbf774fc034efjiabin                            status = getSupportedFormats(outputs.itemAt(j), formats);
3631817729095966c338615a8a791d2dbf774fc034efjiabin                            reportedFormatFound |= (status == NO_ERROR);
3632817729095966c338615a8a791d2dbf774fc034efjiabin                            continue;
3633817729095966c338615a8a791d2dbf774fc034efjiabin                        }
3634817729095966c338615a8a791d2dbf774fc034efjiabin
3635817729095966c338615a8a791d2dbf774fc034efjiabin                        if (!profile->canOpenNewIo()) {
3636817729095966c338615a8a791d2dbf774fc034efjiabin                            ALOGW("Max Output number %u already opened for this profile %s",
3637817729095966c338615a8a791d2dbf774fc034efjiabin                                  profile->maxOpenCount, profile->getTagName().c_str());
3638817729095966c338615a8a791d2dbf774fc034efjiabin                            continue;
3639817729095966c338615a8a791d2dbf774fc034efjiabin                        }
3640817729095966c338615a8a791d2dbf774fc034efjiabin
3641817729095966c338615a8a791d2dbf774fc034efjiabin                        ALOGV("opening output for device %08x with params %s profile %p name %s",
3642817729095966c338615a8a791d2dbf774fc034efjiabin                              device, address.string(), profile.get(), profile->getName().string());
3643817729095966c338615a8a791d2dbf774fc034efjiabin                        desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
3644817729095966c338615a8a791d2dbf774fc034efjiabin                        audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
3645817729095966c338615a8a791d2dbf774fc034efjiabin                        status_t status = desc->open(nullptr, device, address,
3646817729095966c338615a8a791d2dbf774fc034efjiabin                                                     AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE,
3647817729095966c338615a8a791d2dbf774fc034efjiabin                                                     &output);
3648817729095966c338615a8a791d2dbf774fc034efjiabin
3649817729095966c338615a8a791d2dbf774fc034efjiabin                        if (status == NO_ERROR) {
3650817729095966c338615a8a791d2dbf774fc034efjiabin                            status = getSupportedFormats(output, formats);
3651817729095966c338615a8a791d2dbf774fc034efjiabin                            reportedFormatFound |= (status == NO_ERROR);
3652817729095966c338615a8a791d2dbf774fc034efjiabin                            desc->close();
3653817729095966c338615a8a791d2dbf774fc034efjiabin                            output = AUDIO_IO_HANDLE_NONE;
3654817729095966c338615a8a791d2dbf774fc034efjiabin                        }
3655817729095966c338615a8a791d2dbf774fc034efjiabin                    }
3656817729095966c338615a8a791d2dbf774fc034efjiabin                }
3657817729095966c338615a8a791d2dbf774fc034efjiabin            }
3658817729095966c338615a8a791d2dbf774fc034efjiabin        }
3659817729095966c338615a8a791d2dbf774fc034efjiabin
3660817729095966c338615a8a791d2dbf774fc034efjiabin        if (!reportedFormatFound) {
3661817729095966c338615a8a791d2dbf774fc034efjiabin            return UNKNOWN_ERROR;
3662817729095966c338615a8a791d2dbf774fc034efjiabin        }
3663817729095966c338615a8a791d2dbf774fc034efjiabin    } else {
3664817729095966c338615a8a791d2dbf774fc034efjiabin        for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
3665817729095966c338615a8a791d2dbf774fc034efjiabin            formats.add(SURROUND_FORMATS[i]);
3666817729095966c338615a8a791d2dbf774fc034efjiabin        }
3667817729095966c338615a8a791d2dbf774fc034efjiabin    }
3668817729095966c338615a8a791d2dbf774fc034efjiabin    for (size_t i = 0; i < formats.size(); i++) {
3669817729095966c338615a8a791d2dbf774fc034efjiabin        if (formatsWritten < formatsMax) {
3670817729095966c338615a8a791d2dbf774fc034efjiabin            surroundFormats[formatsWritten] = formats[i];
3671817729095966c338615a8a791d2dbf774fc034efjiabin            bool formatEnabled = false;
3672817729095966c338615a8a791d2dbf774fc034efjiabin            if (formats[i] == AUDIO_FORMAT_AAC_LC) {
3673817729095966c338615a8a791d2dbf774fc034efjiabin                for (size_t j = 0; j < ARRAY_SIZE(AAC_FORMATS); j++) {
3674817729095966c338615a8a791d2dbf774fc034efjiabin                    formatEnabled =
3675817729095966c338615a8a791d2dbf774fc034efjiabin                            mSurroundFormats.find(AAC_FORMATS[i]) != mSurroundFormats.end();
3676817729095966c338615a8a791d2dbf774fc034efjiabin                    break;
3677817729095966c338615a8a791d2dbf774fc034efjiabin                }
3678817729095966c338615a8a791d2dbf774fc034efjiabin            } else {
3679817729095966c338615a8a791d2dbf774fc034efjiabin                formatEnabled = mSurroundFormats.find(formats[i]) != mSurroundFormats.end();
3680817729095966c338615a8a791d2dbf774fc034efjiabin            }
3681817729095966c338615a8a791d2dbf774fc034efjiabin            surroundFormatsEnabled[formatsWritten++] = formatEnabled;
3682817729095966c338615a8a791d2dbf774fc034efjiabin        }
3683817729095966c338615a8a791d2dbf774fc034efjiabin        (*numSurroundFormats)++;
3684817729095966c338615a8a791d2dbf774fc034efjiabin    }
3685817729095966c338615a8a791d2dbf774fc034efjiabin    return NO_ERROR;
3686817729095966c338615a8a791d2dbf774fc034efjiabin}
3687817729095966c338615a8a791d2dbf774fc034efjiabin
3688817729095966c338615a8a791d2dbf774fc034efjiabinstatus_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
3689817729095966c338615a8a791d2dbf774fc034efjiabin{
3690817729095966c338615a8a791d2dbf774fc034efjiabin    // Check if audio format is a surround formats.
3691817729095966c338615a8a791d2dbf774fc034efjiabin    bool isSurroundFormat = false;
3692817729095966c338615a8a791d2dbf774fc034efjiabin    for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
3693817729095966c338615a8a791d2dbf774fc034efjiabin        if (audioFormat == SURROUND_FORMATS[i]) {
3694817729095966c338615a8a791d2dbf774fc034efjiabin            isSurroundFormat = true;
3695817729095966c338615a8a791d2dbf774fc034efjiabin            break;
3696817729095966c338615a8a791d2dbf774fc034efjiabin        }
3697817729095966c338615a8a791d2dbf774fc034efjiabin    }
3698817729095966c338615a8a791d2dbf774fc034efjiabin    if (!isSurroundFormat) {
3699817729095966c338615a8a791d2dbf774fc034efjiabin        return BAD_VALUE;
3700817729095966c338615a8a791d2dbf774fc034efjiabin    }
3701817729095966c338615a8a791d2dbf774fc034efjiabin
3702817729095966c338615a8a791d2dbf774fc034efjiabin    // Should only be called when MANUAL.
3703817729095966c338615a8a791d2dbf774fc034efjiabin    audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
3704817729095966c338615a8a791d2dbf774fc034efjiabin                AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
3705817729095966c338615a8a791d2dbf774fc034efjiabin    if (forceUse != AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
3706817729095966c338615a8a791d2dbf774fc034efjiabin        return INVALID_OPERATION;
3707817729095966c338615a8a791d2dbf774fc034efjiabin    }
3708817729095966c338615a8a791d2dbf774fc034efjiabin
3709817729095966c338615a8a791d2dbf774fc034efjiabin    if ((mSurroundFormats.find(audioFormat) != mSurroundFormats.end() && enabled)
3710817729095966c338615a8a791d2dbf774fc034efjiabin            || (mSurroundFormats.find(audioFormat) == mSurroundFormats.end() && !enabled)) {
3711817729095966c338615a8a791d2dbf774fc034efjiabin        return NO_ERROR;
3712817729095966c338615a8a791d2dbf774fc034efjiabin    }
3713817729095966c338615a8a791d2dbf774fc034efjiabin
3714817729095966c338615a8a791d2dbf774fc034efjiabin    // The operation is valid only when there is HDMI output available.
3715817729095966c338615a8a791d2dbf774fc034efjiabin    if ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_HDMI) == 0) {
3716817729095966c338615a8a791d2dbf774fc034efjiabin        return INVALID_OPERATION;
3717817729095966c338615a8a791d2dbf774fc034efjiabin    }
3718817729095966c338615a8a791d2dbf774fc034efjiabin
3719817729095966c338615a8a791d2dbf774fc034efjiabin    if (enabled) {
3720817729095966c338615a8a791d2dbf774fc034efjiabin        if (audioFormat == AUDIO_FORMAT_AAC_LC) {
3721817729095966c338615a8a791d2dbf774fc034efjiabin            for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
3722817729095966c338615a8a791d2dbf774fc034efjiabin                mSurroundFormats.insert(AAC_FORMATS[i]);
3723817729095966c338615a8a791d2dbf774fc034efjiabin            }
3724817729095966c338615a8a791d2dbf774fc034efjiabin        } else {
3725817729095966c338615a8a791d2dbf774fc034efjiabin            mSurroundFormats.insert(audioFormat);
3726817729095966c338615a8a791d2dbf774fc034efjiabin        }
3727817729095966c338615a8a791d2dbf774fc034efjiabin    } else {
3728817729095966c338615a8a791d2dbf774fc034efjiabin        if (audioFormat == AUDIO_FORMAT_AAC_LC) {
3729817729095966c338615a8a791d2dbf774fc034efjiabin            for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
3730817729095966c338615a8a791d2dbf774fc034efjiabin                mSurroundFormats.erase(AAC_FORMATS[i]);
3731817729095966c338615a8a791d2dbf774fc034efjiabin            }
3732817729095966c338615a8a791d2dbf774fc034efjiabin        } else {
3733817729095966c338615a8a791d2dbf774fc034efjiabin            mSurroundFormats.erase(audioFormat);
3734817729095966c338615a8a791d2dbf774fc034efjiabin        }
3735817729095966c338615a8a791d2dbf774fc034efjiabin    }
3736817729095966c338615a8a791d2dbf774fc034efjiabin
3737817729095966c338615a8a791d2dbf774fc034efjiabin    sp<SwAudioOutputDescriptor> outputDesc;
3738817729095966c338615a8a791d2dbf774fc034efjiabin    bool profileUpdated = false;
3739817729095966c338615a8a791d2dbf774fc034efjiabin    DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromType(
3740817729095966c338615a8a791d2dbf774fc034efjiabin            AUDIO_DEVICE_OUT_HDMI);
3741817729095966c338615a8a791d2dbf774fc034efjiabin    for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
3742817729095966c338615a8a791d2dbf774fc034efjiabin        // Simulate reconnection to update enabled surround sound formats.
3743817729095966c338615a8a791d2dbf774fc034efjiabin        String8 address = hdmiOutputDevices[i]->mAddress;
3744817729095966c338615a8a791d2dbf774fc034efjiabin        String8 name = hdmiOutputDevices[i]->getName();
3745817729095966c338615a8a791d2dbf774fc034efjiabin        status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
3746817729095966c338615a8a791d2dbf774fc034efjiabin                                                      AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3747817729095966c338615a8a791d2dbf774fc034efjiabin                                                      address.c_str(),
3748817729095966c338615a8a791d2dbf774fc034efjiabin                                                      name.c_str());
3749817729095966c338615a8a791d2dbf774fc034efjiabin        if (status != NO_ERROR) {
3750817729095966c338615a8a791d2dbf774fc034efjiabin            continue;
3751817729095966c338615a8a791d2dbf774fc034efjiabin        }
3752817729095966c338615a8a791d2dbf774fc034efjiabin        status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
3753817729095966c338615a8a791d2dbf774fc034efjiabin                                             AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3754817729095966c338615a8a791d2dbf774fc034efjiabin                                             address.c_str(),
3755817729095966c338615a8a791d2dbf774fc034efjiabin                                             name.c_str());
3756817729095966c338615a8a791d2dbf774fc034efjiabin        profileUpdated |= (status == NO_ERROR);
3757817729095966c338615a8a791d2dbf774fc034efjiabin    }
3758817729095966c338615a8a791d2dbf774fc034efjiabin    DeviceVector hdmiInputDevices = mAvailableInputDevices.getDevicesFromType(
3759817729095966c338615a8a791d2dbf774fc034efjiabin                AUDIO_DEVICE_IN_HDMI);
3760817729095966c338615a8a791d2dbf774fc034efjiabin    for (size_t i = 0; i < hdmiInputDevices.size(); i++) {
3761817729095966c338615a8a791d2dbf774fc034efjiabin        // Simulate reconnection to update enabled surround sound formats.
3762817729095966c338615a8a791d2dbf774fc034efjiabin        String8 address = hdmiInputDevices[i]->mAddress;
3763817729095966c338615a8a791d2dbf774fc034efjiabin        String8 name = hdmiInputDevices[i]->getName();
3764817729095966c338615a8a791d2dbf774fc034efjiabin        status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
3765817729095966c338615a8a791d2dbf774fc034efjiabin                                                      AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3766817729095966c338615a8a791d2dbf774fc034efjiabin                                                      address.c_str(),
3767817729095966c338615a8a791d2dbf774fc034efjiabin                                                      name.c_str());
3768817729095966c338615a8a791d2dbf774fc034efjiabin        if (status != NO_ERROR) {
3769817729095966c338615a8a791d2dbf774fc034efjiabin            continue;
3770817729095966c338615a8a791d2dbf774fc034efjiabin        }
3771817729095966c338615a8a791d2dbf774fc034efjiabin        status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
3772817729095966c338615a8a791d2dbf774fc034efjiabin                                             AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3773817729095966c338615a8a791d2dbf774fc034efjiabin                                             address.c_str(),
3774817729095966c338615a8a791d2dbf774fc034efjiabin                                             name.c_str());
3775817729095966c338615a8a791d2dbf774fc034efjiabin        profileUpdated |= (status == NO_ERROR);
3776817729095966c338615a8a791d2dbf774fc034efjiabin    }
3777817729095966c338615a8a791d2dbf774fc034efjiabin
3778817729095966c338615a8a791d2dbf774fc034efjiabin    // Undo the surround formats change due to no audio profiles updated.
3779817729095966c338615a8a791d2dbf774fc034efjiabin    if (!profileUpdated) {
3780817729095966c338615a8a791d2dbf774fc034efjiabin        if (enabled) {
3781817729095966c338615a8a791d2dbf774fc034efjiabin            if (audioFormat == AUDIO_FORMAT_AAC_LC) {
3782817729095966c338615a8a791d2dbf774fc034efjiabin                for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
3783817729095966c338615a8a791d2dbf774fc034efjiabin                    mSurroundFormats.erase(AAC_FORMATS[i]);
3784817729095966c338615a8a791d2dbf774fc034efjiabin                }
3785817729095966c338615a8a791d2dbf774fc034efjiabin            } else {
3786817729095966c338615a8a791d2dbf774fc034efjiabin                mSurroundFormats.erase(audioFormat);
3787817729095966c338615a8a791d2dbf774fc034efjiabin            }
3788817729095966c338615a8a791d2dbf774fc034efjiabin        } else {
3789817729095966c338615a8a791d2dbf774fc034efjiabin            if (audioFormat == AUDIO_FORMAT_AAC_LC) {
3790817729095966c338615a8a791d2dbf774fc034efjiabin                for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
3791817729095966c338615a8a791d2dbf774fc034efjiabin                    mSurroundFormats.insert(AAC_FORMATS[i]);
3792817729095966c338615a8a791d2dbf774fc034efjiabin                }
3793817729095966c338615a8a791d2dbf774fc034efjiabin            } else {
3794817729095966c338615a8a791d2dbf774fc034efjiabin                mSurroundFormats.insert(audioFormat);
3795817729095966c338615a8a791d2dbf774fc034efjiabin            }
3796817729095966c338615a8a791d2dbf774fc034efjiabin        }
3797817729095966c338615a8a791d2dbf774fc034efjiabin    }
3798817729095966c338615a8a791d2dbf774fc034efjiabin
3799817729095966c338615a8a791d2dbf774fc034efjiabin    return profileUpdated ? NO_ERROR : INVALID_OPERATION;
3800817729095966c338615a8a791d2dbf774fc034efjiabin}
3801817729095966c338615a8a791d2dbf774fc034efjiabin
3802f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyManager::setRecordSilenced(uid_t uid, bool silenced)
3803f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov{
3804f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    ALOGV("AudioPolicyManager:setRecordSilenced(uid:%d, silenced:%d)", uid, silenced);
3805f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
3806f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    Vector<sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
3807f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    for (size_t i = 0; i < activeInputs.size(); i++) {
3808f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        sp<AudioInputDescriptor> activeDesc = activeInputs[i];
3809f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        AudioSessionCollection activeSessions = activeDesc->getAudioSessions(true);
3810f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        for (size_t j = 0; j < activeSessions.size(); j++) {
3811f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            sp<AudioSession> activeSession = activeSessions.valueAt(j);
3812f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            if (activeSession->uid() == uid) {
3813f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                activeSession->setSilenced(silenced);
3814f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            }
3815f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        }
3816f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
3817f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
3818f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
3819d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
3820d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
3821d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
3822d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3823d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioPatch> patchDesc = mAudioPatches.valueFor(sourceDesc->mPatchDesc->mHandle);
3824d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (patchDesc == 0) {
3825d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGW("%s source has no patch with handle %d", __FUNCTION__,
3826d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent              sourceDesc->mPatchDesc->mHandle);
3827d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
3828d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3829d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    removeAudioPatch(sourceDesc->mPatchDesc->mHandle);
3830d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
383128d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
3832d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<SwAudioOutputDescriptor> swOutputDesc = sourceDesc->mSwOutput.promote();
3833d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (swOutputDesc != 0) {
3834733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        status_t status = stopSource(swOutputDesc, stream, false);
3835733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        if (status == NO_ERROR) {
3836733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            swOutputDesc->stop();
3837733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent        }
3838d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
3839d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    } else {
3840d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<HwAudioOutputDescriptor> hwOutputDesc = sourceDesc->mHwOutput.promote();
3841d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (hwOutputDesc != 0) {
3842d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent          //   release patch between src device and output device
3843d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent          //   close Hwoutput and remove from mHwOutputs
3844d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        } else {
3845d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGW("%s source has neither SW nor HW output", __FUNCTION__);
3846d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3847d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3848d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return NO_ERROR;
3849d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
3850d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3851d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentsp<AudioSourceDescriptor> AudioPolicyManager::getSourceForStrategyOnOutput(
3852d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        audio_io_handle_t output, routing_strategy strategy)
3853d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
3854d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioSourceDescriptor> source;
3855d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (size_t i = 0; i < mAudioSources.size(); i++)  {
3856d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
3857d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        routing_strategy sourceStrategy =
3858d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
3859d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = sourceDesc->mSwOutput.promote();
3860d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (sourceStrategy == strategy && outputDesc != 0 && outputDesc->mIoHandle == output) {
3861d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            source = sourceDesc;
3862d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            break;
3863d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3864d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3865d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return source;
3866554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent}
3867554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent
3868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
3869e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent// AudioPolicyManager
3870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
38716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentuint32_t AudioPolicyManager::nextAudioPortGeneration()
38726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
38732773dd7219e6cdc56471501c90808a1bafc31d39Mikhail Naganov    return mAudioPortGeneration++;
38746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
38756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
38760d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok#ifdef USE_XML_AUDIO_POLICY_CONF
38770d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok// Treblized audio policy xml config will be located in /odm/etc or /vendor/etc.
38780d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seokstatic const char *kConfigLocationList[] =
38790d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok        {"/odm/etc", "/vendor/etc", "/system/etc"};
38800d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seokstatic const int kConfigLocationListSize =
38810d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok        (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
38820d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok
38830d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seokstatic status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
38840d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok    char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];
3885150b9846f846165344910b9211739cdb3054ccf4Petri Gynther    std::vector<const char*> fileNames;
38860d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok    status_t ret;
38870d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok
3888150b9846f846165344910b9211739cdb3054ccf4Petri Gynther    if (property_get_bool("ro.bluetooth.a2dp_offload.supported", false) &&
3889150b9846f846165344910b9211739cdb3054ccf4Petri Gynther        property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {
3890150b9846f846165344910b9211739cdb3054ccf4Petri Gynther        // A2DP offload supported but disabled: try to use special XML file
3891150b9846f846165344910b9211739cdb3054ccf4Petri Gynther        fileNames.push_back(AUDIO_POLICY_A2DP_OFFLOAD_DISABLED_XML_CONFIG_FILE_NAME);
3892150b9846f846165344910b9211739cdb3054ccf4Petri Gynther    }
3893150b9846f846165344910b9211739cdb3054ccf4Petri Gynther    fileNames.push_back(AUDIO_POLICY_XML_CONFIG_FILE_NAME);
3894150b9846f846165344910b9211739cdb3054ccf4Petri Gynther
3895150b9846f846165344910b9211739cdb3054ccf4Petri Gynther    for (const char* fileName : fileNames) {
3896150b9846f846165344910b9211739cdb3054ccf4Petri Gynther        for (int i = 0; i < kConfigLocationListSize; i++) {
3897150b9846f846165344910b9211739cdb3054ccf4Petri Gynther            PolicySerializer serializer;
3898150b9846f846165344910b9211739cdb3054ccf4Petri Gynther            snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
3899150b9846f846165344910b9211739cdb3054ccf4Petri Gynther                     "%s/%s", kConfigLocationList[i], fileName);
3900150b9846f846165344910b9211739cdb3054ccf4Petri Gynther            ret = serializer.deserialize(audioPolicyXmlConfigFile, config);
3901150b9846f846165344910b9211739cdb3054ccf4Petri Gynther            if (ret == NO_ERROR) {
3902150b9846f846165344910b9211739cdb3054ccf4Petri Gynther                return ret;
3903150b9846f846165344910b9211739cdb3054ccf4Petri Gynther            }
39040d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok        }
39050d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok    }
39060d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok    return ret;
39070d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok}
39080d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok#endif
39090d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok
3910ad3f8a1082c101f2c218be64e48ae615676952eaMikhail NaganovAudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface,
3911ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov                                       bool /*forTesting*/)
3912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    :
3913ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    mUidCached(getuid()),
3914ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    mpClientInterface(clientInterface),
3915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
39163a4311c68348f728558e87b5db67d47605783890Eric Laurent    mA2dpSuspended(false),
3917ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov#ifdef USE_XML_AUDIO_POLICY_CONF
3918ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    mVolumeCurves(new VolumeCurvesCollection()),
3919ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
3920bcbcb1bdda4f1970830fa4924e3a5f24171ae005Mikhail Naganov            mDefaultOutputDevice, static_cast<VolumeCurvesCollection*>(mVolumeCurves.get())),
3921ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov#else
3922ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    mVolumeCurves(new StreamDescriptorCollection()),
3923ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
3924ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov            mDefaultOutputDevice),
3925ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov#endif
3926d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    mAudioPortGeneration(1),
3927d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    mBeaconMuteRefCount(0),
3928d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    mBeaconPlayingRefCount(0),
39299459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    mBeaconMuted(false),
39302ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    mTtsOutputAvailable(false),
393136829f97c0c547d9c6c918e248071cc616818616Eric Laurent    mMasterMono(false),
39322b8646482dc74cf1afef50a812691600aa229090Chris Thornton    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE),
39332b8646482dc74cf1afef50a812691600aa229090Chris Thornton    mHasComputedSoundTriggerSupportsConcurrentCapture(false)
3934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3935ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov}
3936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3937ad3f8a1082c101f2c218be64e48ae615676952eaMikhail NaganovAudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
3938ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov        : AudioPolicyManager(clientInterface, false /*forTesting*/)
3939ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov{
3940ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    loadConfig();
3941ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    initialize();
3942ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov}
3943a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
3944ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganovvoid AudioPolicyManager::loadConfig() {
3945f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#ifdef USE_XML_AUDIO_POLICY_CONF
3946ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
3947f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#else
3948ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, getConfig()) != NO_ERROR)
3949ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov           && (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, getConfig()) != NO_ERROR)) {
3950f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#endif
3951a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        ALOGE("could not load audio policy configuration file, setting defaults");
3952ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov        getConfig().setDefault();
3953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3954ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov}
3955ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov
3956ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganovstatus_t AudioPolicyManager::initialize() {
3957ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    mVolumeCurves->initializeVolumeCurves(getConfig().isSpeakerDrcEnabled());
3958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3959d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // Once policy config has been parsed, retrieve an instance of the engine and initialize it.
3960d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
3961d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if (!engineInstance) {
3962d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        ALOGE("%s:  Could not get an instance of policy engine", __FUNCTION__);
3963ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov        return NO_INIT;
3964d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    }
3965d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // Retrieve the Policy Manager Interface
3966d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
3967d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if (mEngine == NULL) {
3968d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
3969ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov        return NO_INIT;
3970d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    }
3971d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mEngine->setObserver(this);
3972d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    status_t status = mEngine->initCheck();
3973ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    if (status != NO_ERROR) {
3974ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov        LOG_FATAL("Policy engine not initialized(err=%d)", status);
3975ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov        return status;
3976ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    }
3977d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie
3978d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
3979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open all output streams needed to access attached devices
39803a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
39813a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
3982d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov    for (const auto& hwModule : mHwModulesAll) {
3983a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov        hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
3984d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov        if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
3985d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov            ALOGW("could not open HW module %s", hwModule->getName());
3986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
3987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3988d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov        mHwModules.push_back(hwModule);
3989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // open all output streams needed to access attached devices
3990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // except for direct output streams that are only opened when they are actually
3991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // required by an app.
39923a4311c68348f728558e87b5db67d47605783890Eric Laurent        // This also validates mAvailableOutputDevices list
3993a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov        for (const auto& outProfile : hwModule->getOutputProfiles()) {
39943974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent            if (!outProfile->canOpenNewIo()) {
39953974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                ALOGE("Invalid Output profile max open count %u for profile %s",
39963974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                      outProfile->maxOpenCount, outProfile->getTagName().c_str());
39973974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                continue;
39983974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent            }
3999a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (!outProfile->hasSupportedDevices()) {
4000d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                ALOGW("Output profile contains no device on module %s", hwModule->getName());
40013a4311c68348f728558e87b5db67d47605783890Eric Laurent                continue;
40023a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
4003a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
40049459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent                mTtsOutputAvailable = true;
40059459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent            }
40063a4311c68348f728558e87b5db67d47605783890Eric Laurent
4007a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
4008d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                continue;
4009d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
4010a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            audio_devices_t profileType = outProfile->getSupportedDevicesType();
401153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
401253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                profileType = mDefaultOutputDevice->type();
401383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            } else {
4014a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                // chose first device present in profile's SupportedDevices also part of
4015d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                // outputDeviceTypes
4016a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
4017d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
4018d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if ((profileType & outputDeviceTypes) == 0) {
4019d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                continue;
4020d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
4021c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
4022c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                                 mpClientInterface);
4023c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
4024c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
4025c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
4026c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                    : String8("");
4027d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
4028fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            status_t status = outputDesc->open(nullptr, profileType, address,
4029fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                           AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
4030d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
4031d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if (status != NO_ERROR) {
4032d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                ALOGW("Cannot open output stream for device %08x on hw module %s",
4033d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                      outputDesc->mDevice,
4034d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                      hwModule->getName());
4035d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            } else {
4036cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                for (const auto& dev : supportedDevices) {
4037cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                    ssize_t index = mAvailableOutputDevices.indexOf(dev);
4038d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                    // give a valid ID to an attached device once confirmed it is reachable
4039e743a47f445f02a0612018fa5640301304844fbfPaul McLean                    if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
4040d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                        mAvailableOutputDevices[index]->attach(hwModule);
4041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
4042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4043d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                if (mPrimaryOutput == 0 &&
4044a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                        outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
4045c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    mPrimaryOutput = outputDesc;
4046d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                }
4047d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                addOutput(output, outputDesc);
4048c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setOutputDevice(outputDesc,
4049fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                profileType,
4050c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                true,
4051c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                0,
4052c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                NULL,
4053fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                address);
4054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
40563a4311c68348f728558e87b5db67d47605783890Eric Laurent        // open input streams needed to access attached devices to validate
40573a4311c68348f728558e87b5db67d47605783890Eric Laurent        // mAvailableInputDevices list
4058a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov        for (const auto& inProfile : hwModule->getInputProfiles()) {
40593974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent            if (!inProfile->canOpenNewIo()) {
40603974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                ALOGE("Invalid Input profile max open count %u for profile %s",
40613974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                      inProfile->maxOpenCount, inProfile->getTagName().c_str());
40623974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                continue;
40633974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent            }
4064a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (!inProfile->hasSupportedDevices()) {
4065d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                ALOGW("Input profile contains no device on module %s", hwModule->getName());
40663a4311c68348f728558e87b5db67d47605783890Eric Laurent                continue;
40673a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
4068a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            // chose first device present in profile's SupportedDevices also part of
4069d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            // inputDeviceTypes
4070a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);
4071a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
4072d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if ((profileType & inputDeviceTypes) == 0) {
4073d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                continue;
4074d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
40752f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi            sp<AudioInputDescriptor> inputDesc =
4076fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    new AudioInputDescriptor(inProfile, mpClientInterface);
4077fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi
407853b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent            DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
407953b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent            //   the inputs vector must be of size >= 1, but we don't want to crash here
408053b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent            String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
408153b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent                    : String8("");
408253b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent            ALOGV("  for input device 0x%x using address %s", profileType, address.string());
408353b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent            ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
408453b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent
4085d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
4086fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            status_t status = inputDesc->open(nullptr,
4087fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                              profileType,
408853b810ead5b726994fe6a28c6fa955e7b8799aaaEric Laurent                                              address,
4089fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                              AUDIO_SOURCE_MIC,
4090fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                              AUDIO_INPUT_FLAG_NONE,
4091fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                              &input);
4092d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
4093d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if (status == NO_ERROR) {
4094cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                for (const auto& dev : inProfile->getSupportedDevices()) {
4095cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                    ssize_t index = mAvailableInputDevices.indexOf(dev);
4096d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                    // give a valid ID to an attached device once confirmed it is reachable
409745aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                    if (index >= 0) {
409845aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                        sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
409945aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                        if (!devDesc->isAttached()) {
4100d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                            devDesc->attach(hwModule);
410183efe1c6bd6fa206560377960358ec95aa6a1c41Eric Laurent                            devDesc->importAudioPort(inProfile, true);
410245aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                        }
41033a4311c68348f728558e87b5db67d47605783890Eric Laurent                    }
41043a4311c68348f728558e87b5db67d47605783890Eric Laurent                }
4105fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                inputDesc->close();
4106d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            } else {
4107d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                ALOGW("Cannot open input stream for device %08x on hw module %s",
4108fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                      profileType,
4109d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                      hwModule->getName());
41103a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
41113a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
41123a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
41133a4311c68348f728558e87b5db67d47605783890Eric Laurent    // make sure all attached devices have been allocated a unique ID
41143a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i  < mAvailableOutputDevices.size();) {
4115e743a47f445f02a0612018fa5640301304844fbfPaul McLean        if (!mAvailableOutputDevices[i]->isAttached()) {
4116a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
41173a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
41183a4311c68348f728558e87b5db67d47605783890Eric Laurent            continue;
41193a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
41202110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        // The device is now validated and can be appended to the available devices of the engine
41212110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
41222110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
41233a4311c68348f728558e87b5db67d47605783890Eric Laurent        i++;
41243a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
41253a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i  < mAvailableInputDevices.size();) {
4126e743a47f445f02a0612018fa5640301304844fbfPaul McLean        if (!mAvailableInputDevices[i]->isAttached()) {
412753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
41283a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.remove(mAvailableInputDevices[i]);
41293a4311c68348f728558e87b5db67d47605783890Eric Laurent            continue;
41303a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
41312110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        // The device is now validated and can be appended to the available devices of the engine
41322110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
41332110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
41343a4311c68348f728558e87b5db67d47605783890Eric Laurent        i++;
41353a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
41363a4311c68348f728558e87b5db67d47605783890Eric Laurent    // make sure default device is reachable
4137a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
413853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
4139ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov        status = NO_INIT;
41403a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
41419ff780e58ff96ff98acaae4166bb218880bf9e73jiabin    // If microphones address is empty, set it according to device type
41429ff780e58ff96ff98acaae4166bb218880bf9e73jiabin    for (size_t i = 0; i  < mAvailableInputDevices.size(); i++) {
41439ff780e58ff96ff98acaae4166bb218880bf9e73jiabin        if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
41449ff780e58ff96ff98acaae4166bb218880bf9e73jiabin            if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
41459ff780e58ff96ff98acaae4166bb218880bf9e73jiabin                mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
41469ff780e58ff96ff98acaae4166bb218880bf9e73jiabin            } else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
41479ff780e58ff96ff98acaae4166bb218880bf9e73jiabin                mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
41489ff780e58ff96ff98acaae4166bb218880bf9e73jiabin            }
41499ff780e58ff96ff98acaae4166bb218880bf9e73jiabin        }
41509ff780e58ff96ff98acaae4166bb218880bf9e73jiabin    }
4151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4152ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    if (mPrimaryOutput == 0) {
4153ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov        ALOGE("Failed to open primary output");
4154ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov        status = NO_INIT;
4155ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    }
4156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
4158ad3f8a1082c101f2c218be64e48ae615676952eaMikhail Naganov    return status;
4159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4161e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::~AudioPolicyManager()
4162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mOutputs.size(); i++) {
4164fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        mOutputs.valueAt(i)->close();
4165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
4166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mInputs.size(); i++) {
4167fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent        mInputs.valueAt(i)->close();
4168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
41693a4311c68348f728558e87b5db67d47605783890Eric Laurent   mAvailableOutputDevices.clear();
41703a4311c68348f728558e87b5db67d47605783890Eric Laurent   mAvailableInputDevices.clear();
41711f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent   mOutputs.clear();
41721f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent   mInputs.clear();
41731f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent   mHwModules.clear();
4174d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov   mHwModulesAll.clear();
4175817729095966c338615a8a791d2dbf774fc034efjiabin   mSurroundFormats.clear();
4176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4178e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::initCheck()
4179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
418087ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    return hasPrimaryOutput() ? NO_ERROR : NO_INIT;
4181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---
4184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
418598e38191c37d3e324b34a6aafeef8e43366003efEric Laurentvoid AudioPolicyManager::addOutput(audio_io_handle_t output,
418698e38191c37d3e324b34a6aafeef8e43366003efEric Laurent                                   const sp<SwAudioOutputDescriptor>& outputDesc)
4187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
41881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mOutputs.add(output, outputDesc);
418998e38191c37d3e324b34a6aafeef8e43366003efEric Laurent    applyStreamVolumes(outputDesc, AUDIO_DEVICE_NONE, 0 /* delayMs */, true /* force */);
41902ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    updateMono(output); // update mono status when adding to output list
419136829f97c0c547d9c6c918e248071cc616818616Eric Laurent    selectOutputForMusicEffects();
41926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
4193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
419553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffievoid AudioPolicyManager::removeOutput(audio_io_handle_t output)
419653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
419753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mOutputs.removeItem(output);
419836829f97c0c547d9c6c918e248071cc616818616Eric Laurent    selectOutputForMusicEffects();
419953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
420053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
420198e38191c37d3e324b34a6aafeef8e43366003efEric Laurentvoid AudioPolicyManager::addInput(audio_io_handle_t input,
420298e38191c37d3e324b34a6aafeef8e43366003efEric Laurent                                  const sp<AudioInputDescriptor>& inputDesc)
4203d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
42041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mInputs.add(input, inputDesc);
42056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
4206d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
4207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4208e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyManager::findIoHandlesByAddress(const sp<SwAudioOutputDescriptor>& desc /*in*/,
42093190e67d5c80c1e39e3be91784110af1180cd182keunyoung        const audio_devices_t device /*in*/,
4210e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh        const String8& address /*in*/,
42110fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi        SortedVector<audio_io_handle_t>& outputs /*out*/) {
42123190e67d5c80c1e39e3be91784110af1180cd182keunyoung    sp<DeviceDescriptor> devDesc =
4213a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        desc->mProfile->getSupportedDeviceByAddress(device, address);
42143190e67d5c80c1e39e3be91784110af1180cd182keunyoung    if (devDesc != 0) {
42153190e67d5c80c1e39e3be91784110af1180cd182keunyoung        ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
42163190e67d5c80c1e39e3be91784110af1180cd182keunyoung              desc->mIoHandle, address.string());
42173190e67d5c80c1e39e3be91784110af1180cd182keunyoung        outputs.add(desc->mIoHandle);
42180fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi    }
42190fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi}
42200fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi
4221e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& devDesc,
422253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                   audio_policy_dev_state_t state,
422353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                   SortedVector<audio_io_handle_t>& outputs,
4224e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh                                                   const String8& address)
4225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
422653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    audio_devices_t device = devDesc->type();
4227c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> desc;
4228cc750d3604b33a92374253b12dd739dc06440aadEric Laurent
4229cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    if (audio_device_is_digital(device)) {
4230cc750d3604b33a92374253b12dd739dc06440aadEric Laurent        // erase all current sample rates, formats and channel masks
423120eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        devDesc->clearAudioProfiles();
4232cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    }
4233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
42343b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
4235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // first list already open outputs that can be routed to this device
4236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
4237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = mOutputs.valueAt(i);
4238c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            if (!desc->isDuplicated() && (desc->supportedDevices() & device)) {
423953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                if (!device_distinguishes_on_address(device)) {
42400fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
42410fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    outputs.add(mOutputs.keyAt(i));
42420fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                } else {
42430fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("  checking address match due to device 0x%x", device);
42443190e67d5c80c1e39e3be91784110af1180cd182keunyoung                    findIoHandlesByAddress(desc, device, address, outputs);
42450fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                }
4246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // then look for output profiles that can be routed to this device
42491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        SortedVector< sp<IOProfile> > profiles;
42507e22e94d0654d7ab4c31aee7f7120542e358a5abMikhail Naganov        for (const auto& hwModule : mHwModules) {
4251a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov            for (size_t j = 0; j < hwModule->getOutputProfiles().size(); j++) {
4252a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov                sp<IOProfile> profile = hwModule->getOutputProfiles()[j];
4253a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
425453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                    if (!device_distinguishes_on_address(device) ||
4255a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                            profile->supportDeviceAddress(address)) {
4256275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        profiles.add(profile);
4257d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                        ALOGV("checkOutputsForDevice(): adding profile %zu from module %s",
4258d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                                j, hwModule->getName());
4259275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                    }
4260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
42647b279bbc24139ee1e01b58055ca94926ec18e2e9Eric Laurent        ALOGV("  found %zu profiles, %zu outputs", profiles.size(), outputs.size());
42650fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi
4266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (profiles.isEmpty() && outputs.isEmpty()) {
4267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
4268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
4269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // open outputs for matching profiles if needed. Direct outputs are also opened to
4272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
4273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
42741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = profiles[profile_index];
4275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // nothing to do if one output is already opened for this profile
4277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            size_t j;
42780fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            for (j = 0; j < outputs.size(); j++) {
42790fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                desc = mOutputs.valueFor(outputs.itemAt(j));
4280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (!desc->isDuplicated() && desc->mProfile == profile) {
4281f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi                    // matching profile: save the sample rates, format and channel masks supported
4282f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi                    // by the profile in our device descriptor
42839080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    if (audio_device_is_digital(device)) {
42849080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                        devDesc->importAudioPort(profile);
42859080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    }
4286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    break;
4287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
42890fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            if (j != outputs.size()) {
4290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
4291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
42933974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent            if (!profile->canOpenNewIo()) {
42943974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                ALOGW("Max Output number %u already opened for this profile %s",
42953974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                      profile->maxOpenCount, profile->getTagName().c_str());
42963974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                continue;
42973974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent            }
42983974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent
429983efe1c6bd6fa206560377960358ec95aa6a1c41Eric Laurent            ALOGV("opening output for device %08x with params %s profile %p name %s",
430083efe1c6bd6fa206560377960358ec95aa6a1c41Eric Laurent                  device, address.string(), profile.get(), profile->getName().string());
4301c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
4302cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
4303fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            status_t status = desc->open(nullptr, device, address,
4304fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                         AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
4305cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent
4306fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            if (status == NO_ERROR) {
4307d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                // Here is where the out_set_parameters() for card & device gets called
43083a4311c68348f728558e87b5db67d47605783890Eric Laurent                if (!address.isEmpty()) {
4309cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    char *param = audio_device_address_to_parameter(device, address);
4310cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    mpClientInterface->setParameters(output, String8(param));
4311cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    free(param);
4312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
431300eeb32846df81288f12fe4c83e61d7db2842226Phil Burk                updateAudioProfiles(device, output, profile->getAudioProfiles());
4314112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                if (!profile->hasValidAudioProfile()) {
43150fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGW("checkOutputsForDevice() missing param");
4316fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    desc->close();
4317cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    output = AUDIO_IO_HANDLE_NONE;
4318112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                } else if (profile->hasDynamicAudioProfile()) {
4319fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    desc->close();
4320702b105b290d9a3c8b23f3c809a79086d784c9bePhil Burk                    output = AUDIO_IO_HANDLE_NONE;
4321fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    audio_config_t config = AUDIO_CONFIG_INITIALIZER;
4322fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    profile->pickAudioProfile(
4323fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                            config.sample_rate, config.channel_mask, config.format);
4324cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    config.offload_info.sample_rate = config.sample_rate;
4325cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    config.offload_info.channel_mask = config.channel_mask;
4326cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    config.offload_info.format = config.format;
4327fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent
4328fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    status_t status = desc->open(&config, device, address, AUDIO_STREAM_DEFAULT,
4329fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                                 AUDIO_OUTPUT_FLAG_NONE, &output);
4330fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    if (status != NO_ERROR) {
4331cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        output = AUDIO_IO_HANDLE_NONE;
4332cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    }
4333d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4334d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4335cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                if (output != AUDIO_IO_HANDLE_NONE) {
4336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    addOutput(output, desc);
433753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                    if (device_distinguishes_on_address(device) && address != "0") {
4338036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie                        sp<AudioPolicyMix> policyMix;
4339036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie                        if (mPolicyMixes.getAudioPolicyMix(address, policyMix) != NO_ERROR) {
4340275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                            ALOGE("checkOutputsForDevice() cannot find policy for address %s",
4341275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                  address.string());
4342275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        }
4343036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie                        policyMix->setOutput(desc);
4344dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi                        desc->mPolicyMix = policyMix->getMix();
4345036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie
434687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                    } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
434787ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                                    hasPrimaryOutput()) {
4348c722f30eef03e77054395ae122470cf8dba93937Eric Laurent                        // no duplicated output for direct outputs and
4349c722f30eef03e77054395ae122470cf8dba93937Eric Laurent                        // outputs used by dynamic policy mixes
4350cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
4351d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4352d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        //TODO: configure audio effect output stage here
4353d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4354d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        // open a duplicating output thread for the new output and the primary output
43555babc4f104885c16a3dcfdfb5d99903c27ff2bd9Eric Laurent                        sp<SwAudioOutputDescriptor> dupOutputDesc =
43565babc4f104885c16a3dcfdfb5d99903c27ff2bd9Eric Laurent                                new SwAudioOutputDescriptor(NULL, mpClientInterface);
43575babc4f104885c16a3dcfdfb5d99903c27ff2bd9Eric Laurent                        status_t status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc,
43585babc4f104885c16a3dcfdfb5d99903c27ff2bd9Eric Laurent                                                                         &duplicatedOutput);
43595babc4f104885c16a3dcfdfb5d99903c27ff2bd9Eric Laurent                        if (status == NO_ERROR) {
4360d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            // add duplicated output descriptor
4361d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            addOutput(duplicatedOutput, dupOutputDesc);
4362d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        } else {
4363d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
4364c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                    mPrimaryOutput->mIoHandle, output);
4365fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                            desc->close();
436653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                            removeOutput(output);
43676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                            nextAudioPortGeneration();
4368cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                            output = AUDIO_IO_HANDLE_NONE;
4369d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        }
4370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
4371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4372cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            } else {
4373cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                output = AUDIO_IO_HANDLE_NONE;
4374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4375cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (output == AUDIO_IO_HANDLE_NONE) {
4376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("checkOutputsForDevice() could not open output for device %x", device);
4377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                profiles.removeAt(profile_index);
4378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                profile_index--;
4379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
4380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputs.add(output);
43819080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                // Load digital format info only for digital devices
43829080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                if (audio_device_is_digital(device)) {
43839080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    devDesc->importAudioPort(profile);
43849080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                }
4385f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi
438653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                if (device_distinguishes_on_address(device)) {
43870fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)",
43880fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                            device, address.string());
4389c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    setOutputDevice(desc, device, true/*force*/, 0/*delay*/,
43900fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                            NULL/*patch handle*/, address.string());
43910fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                }
4392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("checkOutputsForDevice(): adding output %d", output);
4393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (profiles.isEmpty()) {
4397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
4398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
4399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4400d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } else { // Disconnect
4401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // check if one opened output is not needed any more after disconnecting one device
4402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
4403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = mOutputs.valueAt(i);
44040fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            if (!desc->isDuplicated()) {
4405275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                // exact match on device
440653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                if (device_distinguishes_on_address(device) &&
4407c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                        (desc->supportedDevices() == device)) {
44083190e67d5c80c1e39e3be91784110af1180cd182keunyoung                    findIoHandlesByAddress(desc, device, address, outputs);
4409c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                } else if (!(desc->supportedDevices() & mAvailableOutputDevices.types())) {
44100fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
44110fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                            mOutputs.keyAt(i));
44120fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    outputs.add(mOutputs.keyAt(i));
44130fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                }
4414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4416d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Clear any profiles associated with the disconnected device.
44177e22e94d0654d7ab4c31aee7f7120542e358a5abMikhail Naganov        for (const auto& hwModule : mHwModules) {
4418a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov            for (size_t j = 0; j < hwModule->getOutputProfiles().size(); j++) {
4419a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov                sp<IOProfile> profile = hwModule->getOutputProfiles()[j];
4420a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
4421d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice(): "
4422d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                            "clearing direct output profile %zu on module %s",
4423d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                            j, hwModule->getName());
4424112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                    profile->clearAudioProfiles();
4425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
4430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4432e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& devDesc,
443353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  audio_policy_dev_state_t state,
443453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  SortedVector<audio_io_handle_t>& inputs,
4435e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh                                                  const String8& address)
4436d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
44379080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean    audio_devices_t device = devDesc->type();
44381f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> desc;
4439cc750d3604b33a92374253b12dd739dc06440aadEric Laurent
4440cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    if (audio_device_is_digital(device)) {
4441cc750d3604b33a92374253b12dd739dc06440aadEric Laurent        // erase all current sample rates, formats and channel masks
444220eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        devDesc->clearAudioProfiles();
4443cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    }
4444cc750d3604b33a92374253b12dd739dc06440aadEric Laurent
4445d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
4446d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // first list already open inputs that can be routed to this device
4447d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
4448d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = mInputs.valueAt(input_index);
4449a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (desc->mProfile->supportDevice(device)) {
4450d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
4451d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent               inputs.add(mInputs.keyAt(input_index));
4452d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4453d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4454d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4455d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // then look for input profiles that can be routed to this device
44561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        SortedVector< sp<IOProfile> > profiles;
44577e22e94d0654d7ab4c31aee7f7120542e358a5abMikhail Naganov        for (const auto& hwModule : mHwModules) {
4458d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (size_t profile_index = 0;
4459a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov                 profile_index < hwModule->getInputProfiles().size();
44607e22e94d0654d7ab4c31aee7f7120542e358a5abMikhail Naganov                 profile_index++) {
4461a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov                sp<IOProfile> profile = hwModule->getInputProfiles()[profile_index];
4462275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
4463a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
446453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                    if (!device_distinguishes_on_address(device) ||
4465a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                            profile->supportDeviceAddress(address)) {
4466275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        profiles.add(profile);
4467d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                        ALOGV("checkInputsForDevice(): adding profile %zu from module %s",
4468d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                                profile_index, hwModule->getName());
4469275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                    }
4470d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4471d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4472d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4473d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4474d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        if (profiles.isEmpty() && inputs.isEmpty()) {
4475d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
4476d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            return BAD_VALUE;
4477d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4478d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4479d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // open inputs for matching profiles if needed. Direct inputs are also opened to
4480d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
4481d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
4482d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
44831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = profiles[profile_index];
44843974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent
4485d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            // nothing to do if one input is already opened for this profile
4486d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            size_t input_index;
4487d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (input_index = 0; input_index < mInputs.size(); input_index++) {
4488d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                desc = mInputs.valueAt(input_index);
4489d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (desc->mProfile == profile) {
44909080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    if (audio_device_is_digital(device)) {
44919080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                        devDesc->importAudioPort(profile);
44929080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    }
4493d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    break;
4494d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4495d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4496d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (input_index != mInputs.size()) {
4497d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
4498d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4499d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
45003974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent            if (!profile->canOpenNewIo()) {
45013974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                ALOGW("Max Input number %u already opened for this profile %s",
45023974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                      profile->maxOpenCount, profile->getTagName().c_str());
45033974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent                continue;
45043974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent            }
45053974e3b22856ef35dd73760056ff38b7a4062176Eric Laurent
4506fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            desc = new AudioInputDescriptor(profile, mpClientInterface);
4507cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
4508fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent            status_t status = desc->open(nullptr,
4509fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                         device,
4510fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                         address,
4511fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                         AUDIO_SOURCE_MIC,
4512fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                         AUDIO_INPUT_FLAG_NONE,
4513fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                                         &input);
4514d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4515cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (status == NO_ERROR) {
4516d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (!address.isEmpty()) {
4517cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    char *param = audio_device_address_to_parameter(device, address);
4518cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    mpClientInterface->setParameters(input, String8(param));
4519cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    free(param);
4520d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
452100eeb32846df81288f12fe4c83e61d7db2842226Phil Burk                updateAudioProfiles(device, input, profile->getAudioProfiles());
4522112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                if (!profile->hasValidAudioProfile()) {
4523d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGW("checkInputsForDevice() direct input missing param");
4524fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent                    desc->close();
4525cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    input = AUDIO_IO_HANDLE_NONE;
4526d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4527d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4528d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (input != 0) {
4529d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    addInput(input, desc);
4530d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4531d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            } // endif input != 0
4532d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4533cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (input == AUDIO_IO_HANDLE_NONE) {
4534d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
4535d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                profiles.removeAt(profile_index);
4536d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                profile_index--;
4537d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            } else {
4538d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                inputs.add(input);
45399080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                if (audio_device_is_digital(device)) {
45409080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    devDesc->importAudioPort(profile);
45419080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                }
4542d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): adding input %d", input);
4543d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4544d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } // end scan profiles
4545d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4546d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        if (profiles.isEmpty()) {
4547d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
4548d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            return BAD_VALUE;
4549d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4550d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } else {
4551d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Disconnect
4552d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // check if one opened input is not needed any more after disconnecting one device
4553d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
4554d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = mInputs.valueAt(input_index);
4555a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (!(desc->mProfile->supportDevice(mAvailableInputDevices.types()))) {
4556d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): disconnecting adding input %d",
4557d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                      mInputs.keyAt(input_index));
4558d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                inputs.add(mInputs.keyAt(input_index));
4559d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4560d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4561d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Clear any profiles associated with the disconnected device.
4562d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov        for (const auto& hwModule : mHwModules) {
4563d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (size_t profile_index = 0;
4564a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov                 profile_index < hwModule->getInputProfiles().size();
4565d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index++) {
4566a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov                sp<IOProfile> profile = hwModule->getInputProfiles()[profile_index];
4567a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
4568d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                    ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %s",
4569d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov                            profile_index, hwModule->getName());
4570112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                    profile->clearAudioProfiles();
4571d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4572d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4573d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4574d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } // end disconnect
4575d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4576d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    return NO_ERROR;
4577d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
4578d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4579d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4580e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::closeOutput(audio_io_handle_t output)
4581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("closeOutput(%d)", output);
4583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4584c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
4585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc == NULL) {
4586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("closeOutput() unknown output %d", output);
4587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4589036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    mPolicyMixes.closeOutput(outputDesc);
4590275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
4591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // look for duplicated outputs connected to the output being removed.
4592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
4593c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i);
4594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (dupOutputDesc->isDuplicated() &&
4595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                (dupOutputDesc->mOutput1 == outputDesc ||
4596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                dupOutputDesc->mOutput2 == outputDesc)) {
4597733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            sp<SwAudioOutputDescriptor> outputDesc2;
4598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (dupOutputDesc->mOutput1 == outputDesc) {
4599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc2 = dupOutputDesc->mOutput2;
4600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
4601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc2 = dupOutputDesc->mOutput1;
4602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // As all active tracks on duplicated output will be deleted,
4604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // and as they were also referenced on the other output, the reference
4605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // count for their stream type must be adjusted accordingly on
4606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // the other output.
4607733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            bool wasActive = outputDesc2->isActive();
46083b73df74357b33869b39a1d69427673c780bd805Eric Laurent            for (int j = 0; j < AUDIO_STREAM_CNT; j++) {
4609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                int refCount = dupOutputDesc->mRefCount[j];
46103b73df74357b33869b39a1d69427673c780bd805Eric Laurent                outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount);
4611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4612733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            // stop() will be a no op if the output is still active but is needed in case all
4613733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            // active streams refcounts where cleared above
4614733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            if (wasActive) {
4615733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent                outputDesc2->stop();
4616733ce945741b1fc12cee92d8133c3136b4e6e0e0Eric Laurent            }
4617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i);
4618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
4619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->closeOutput(duplicatedOutput);
462153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            removeOutput(duplicatedOutput);
4622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
462505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    nextAudioPortGeneration();
462605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
4627ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
462805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (index >= 0) {
462905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4630fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten        (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
463105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mAudioPatches.removeItemsAt(index);
463205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mpClientInterface->onAudioPatchListUpdate();
463305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
463405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
4635fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    outputDesc->close();
4636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
463753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    removeOutput(output);
4638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPreviousOutputs = mOutputs;
463905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent}
464005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
464105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurentvoid AudioPolicyManager::closeInput(audio_io_handle_t input)
464205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent{
464305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    ALOGV("closeInput(%d)", input);
464405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
464505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
464605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (inputDesc == NULL) {
464705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        ALOGW("closeInput() unknown input %d", input);
464805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        return;
464905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
465005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
46516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
465205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
46538c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
465405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (index >= 0) {
465505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4656fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten        (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
465705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mAudioPatches.removeItemsAt(index);
465805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mpClientInterface->onAudioPatchListUpdate();
465905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
466005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
4661fe23112742eeb6199c3aa1f3dfcf800fc2aa0e26Eric Laurent    inputDesc->close();
466205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    mInputs.removeItem(input);
4663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4665c75307b73d324d590d0dbc05b44bce9aa89b7145Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(
4666c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                audio_devices_t device,
4667e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh                                                                const SwAudioOutputCollection& openOutputs)
4668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> outputs;
4670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("getOutputsForDevice() device %04x", device);
4672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < openOutputs.size(); i++) {
467337ddbb43721947d6cb5246ec2cf2a6bd8fc28bcbEric Laurent        ALOGVV("output %zu isDuplicated=%d device=%04x",
46748c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                i, openOutputs.valueAt(i)->isDuplicated(),
46758c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                openOutputs.valueAt(i)->supportedDevices());
4676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
4677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
4678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputs.add(openOutputs.keyAt(i));
4679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs;
4682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4684e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
468553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                      SortedVector<audio_io_handle_t>& outputs2)
4686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs1.size() != outputs2.size()) {
4688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
4689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs1.size(); i++) {
4691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputs1[i] != outputs2[i]) {
4692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
4693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return true;
4696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4698e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
4699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
4701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
4702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
4703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
4704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4705fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    // also take into account external policy-related changes: add all outputs which are
4706fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    // associated with policies in the "before" and "after" output vectors
4707fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    ALOGVV("checkOutputForStrategy(): policy related outputs");
4708fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
4709c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
4710fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        if (desc != 0 && desc->mPolicyMix != NULL) {
4711fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            srcOutputs.add(desc->mIoHandle);
4712fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            ALOGVV(" previous outputs: adding %d", desc->mIoHandle);
4713fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        }
4714fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    }
4715fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    for (size_t i = 0 ; i < mOutputs.size() ; i++) {
4716c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        const sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
4717fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        if (desc != 0 && desc->mPolicyMix != NULL) {
4718fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            dstOutputs.add(desc->mIoHandle);
4719fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            ALOGVV(" new outputs: adding %d", desc->mIoHandle);
4720fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        }
4721fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    }
4722fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi
4723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!vectorsEqual(srcOutputs,dstOutputs)) {
4724ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent        // get maximum latency of all source outputs to determine the minimum mute time guaranteeing
4725ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent        // audio from invalidated tracks will be rendered when unmuting
4726ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent        uint32_t maxLatency = 0;
4727ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent        for (audio_io_handle_t srcOut : srcOutputs) {
4728ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent            sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueFor(srcOut);
4729ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent            if (desc != 0 && maxLatency < desc->latency()) {
4730ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent                maxLatency = desc->latency();
4731ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent            }
4732ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent        }
4733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
4734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              strategy, srcOutputs[0], dstOutputs[0]);
4735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // mute strategy while moving tracks from one output to another
4736cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        for (audio_io_handle_t srcOut : srcOutputs) {
4737ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent            sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueFor(srcOut);
4738ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent            if (desc != 0 && isStrategyActive(desc, strategy)) {
4739c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setStrategyMute(strategy, true, desc);
4740ac3a690c79467612a12e2c3a216c8ea2c4efbd64Eric Laurent                setStrategyMute(strategy, false, desc, maxLatency * LATENCY_MUTE_FACTOR, newDevice);
4741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4742d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            sp<AudioSourceDescriptor> source =
4743cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov                    getSourceForStrategyOnOutput(srcOut, strategy);
4744d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            if (source != 0){
4745d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                connectAudioSource(source);
4746d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            }
4747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Move effects associated to this strategy from previous output to new output
4750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strategy == STRATEGY_MEDIA) {
475136829f97c0c547d9c6c918e248071cc616818616Eric Laurent            selectOutputForMusicEffects();
4752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Move tracks associated to this strategy from previous output to new output
4754794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int i = 0; i < AUDIO_STREAM_FOR_POLICY_CNT; i++) {
47553b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (getStrategy((audio_stream_type_t)i) == strategy) {
47563b73df74357b33869b39a1d69427673c780bd805Eric Laurent                mpClientInterface->invalidateStream((audio_stream_type_t)i);
4757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4762e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForAllStrategies()
4763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
47642110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
4765966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund        checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
4766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_PHONE);
47672110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
4768966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund        checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
4769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_SONIFICATION);
4770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
4771223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    checkOutputForStrategy(STRATEGY_ACCESSIBILITY);
4772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_MEDIA);
4773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_DTMF);
4774223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    checkOutputForStrategy(STRATEGY_REROUTING);
4775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4777e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkA2dpSuspend()
4778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
477953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    audio_io_handle_t a2dpOutput = mOutputs.getA2dpOutput();
4780a8ee996bc065d6938c0e0a5904df7fff5d946feaAniket Kumar Lata    if (a2dpOutput == 0 || mOutputs.isA2dpOffloadedOnPrimary()) {
47813a4311c68348f728558e87b5db67d47605783890Eric Laurent        mA2dpSuspended = false;
4782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
47853a4311c68348f728558e87b5db67d47605783890Eric Laurent    bool isScoConnected =
4786ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent            ((mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET &
4787ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent                    ~AUDIO_DEVICE_BIT_IN) != 0) ||
4788ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent            ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_ALL_SCO) != 0);
4789f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent
4790f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    // if suspended, restore A2DP output if:
4791f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //      ((SCO device is NOT connected) ||
4792f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //       ((forced usage communication is NOT SCO) && (forced usage for record is NOT SCO) &&
4793f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //        (phone state is NOT in call) && (phone state is NOT ringing)))
4794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //
4795f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    // if not suspended, suspend A2DP output if:
4796f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //      (SCO device is connected) &&
4797f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //       ((forced usage for communication is SCO) || (forced usage for record is SCO) ||
4798f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //       ((phone state is in call) || (phone state is ringing)))
4799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //
4800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mA2dpSuspended) {
4801f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent        if (!isScoConnected ||
4802f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent             ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) !=
4803f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent                     AUDIO_POLICY_FORCE_BT_SCO) &&
4804f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent              (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) !=
4805f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent                      AUDIO_POLICY_FORCE_BT_SCO) &&
4806f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent              (mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) &&
48072110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie              (mEngine->getPhoneState() != AUDIO_MODE_RINGTONE))) {
4808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4809e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->restoreOutput(a2dpOutput);
4810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mA2dpSuspended = false;
4811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
4813f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent        if (isScoConnected &&
4814f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent             ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ==
4815f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent                     AUDIO_POLICY_FORCE_BT_SCO) ||
4816f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent              (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) ==
4817f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent                      AUDIO_POLICY_FORCE_BT_SCO) ||
4818f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent              (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) ||
48192110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie              (mEngine->getPhoneState() == AUDIO_MODE_RINGTONE))) {
4820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->suspendOutput(a2dpOutput);
4822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mA2dpSuspended = true;
4823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4827c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
4828c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                       bool fromCache)
4829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = AUDIO_DEVICE_NONE;
4831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4832ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
48336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index >= 0) {
48346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
48356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid != mUidCached) {
48366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("getNewOutputDevice() device %08x forced by patch %d",
4837ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi                  outputDesc->device(), outputDesc->getPatchHandle());
48386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return outputDesc->device();
48396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
48406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
48416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
4842f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent    // Check if an explicit routing request exists for an active stream on this output and
4843f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent    // use it in priority before any other rule
4844f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
4845f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent        if (outputDesc->isStreamActive((audio_stream_type_t)stream)) {
4846f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent            audio_devices_t forcedDevice =
4847f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent                    mOutputRoutes.getActiveDeviceForStream(
4848f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent                            (audio_stream_type_t)stream, mAvailableOutputDevices);
4849f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent
4850f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent            if (forcedDevice != AUDIO_DEVICE_NONE) {
4851f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent                return forcedDevice;
4852f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent            }
4853f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent        }
4854f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent    }
4855f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent
4856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check the following by order of priority to request a routing change if necessary:
4857966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund    // 1: the strategy enforced audible is active and enforced on the output:
4858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy enforced audible
4859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: we are in call or the strategy phone is active on the output:
4860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy phone
4861178683baaf6fd23d80ce926cee103b3af8f9a9a8Jean-Michel Trivi    // 3: the strategy sonification is active on the output:
4862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy sonification
4863178683baaf6fd23d80ce926cee103b3af8f9a9a8Jean-Michel Trivi    // 4: the strategy for enforced audible is active but not enforced on the output:
4864178683baaf6fd23d80ce926cee103b3af8f9a9a8Jean-Michel Trivi    //      use the device for strategy enforced audible
486528d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    // 5: the strategy accessibility is active on the output:
486628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    //      use device for strategy accessibility
48675de234b29141334c1bb5e40bc19c11836848841bJean-Michel Trivi    // 6: the strategy "respectful" sonification is active on the output:
4868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy "respectful" sonification
4869223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    // 7: the strategy media is active on the output:
4870e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy media
4871223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    // 8: the strategy DTMF is active on the output:
4872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy DTMF
4873223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
4874d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    //      use device for strategy t-t-s
4875ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
48762110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
4877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
4878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (isInCall() ||
4879ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                    isStrategyActive(outputDesc, STRATEGY_PHONE)) {
4880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
4881ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)) {
4882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
4883178683baaf6fd23d80ce926cee103b3af8f9a9a8Jean-Michel Trivi    } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
4884178683baaf6fd23d80ce926cee103b3af8f9a9a8Jean-Michel Trivi        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
488528d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
488628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
4887ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) {
4888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
4889ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
4890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
4891ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_DTMF)) {
4892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
4893ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
4894d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
4895ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_REROUTING)) {
4896223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent        device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache);
4897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
48991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("getNewOutputDevice() selected device %x", device);
49001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return device;
49011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
49021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
4903fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentaudio_devices_t AudioPolicyManager::getNewInputDevice(const sp<AudioInputDescriptor>& inputDesc)
49041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
4905fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    audio_devices_t device = AUDIO_DEVICE_NONE;
49066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
49078c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
49086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index >= 0) {
49096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
49106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid != mUidCached) {
49116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("getNewInputDevice() device %08x forced by patch %d",
49128c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                  inputDesc->mDevice, inputDesc->getPatchHandle());
49136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return inputDesc->mDevice;
49146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
49156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
49166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
4917dc95a25769edbe9c47efd1e25962dbd399056157Eric Laurent    // If we are not in call and no client is active on this input, this methods returns
4918dc95a25769edbe9c47efd1e25962dbd399056157Eric Laurent    // AUDIO_DEVICE_NONE, causing the patch on the input stream to be released.
4919fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    audio_source_t source = inputDesc->getHighestPrioritySource(true /*activeOnly*/);
4920dc95a25769edbe9c47efd1e25962dbd399056157Eric Laurent    if (source == AUDIO_SOURCE_DEFAULT && isInCall()) {
4921dc95a25769edbe9c47efd1e25962dbd399056157Eric Laurent        source = AUDIO_SOURCE_VOICE_COMMUNICATION;
4922dc95a25769edbe9c47efd1e25962dbd399056157Eric Laurent    }
4923dc95a25769edbe9c47efd1e25962dbd399056157Eric Laurent    if (source != AUDIO_SOURCE_DEFAULT) {
4924fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        device = getDeviceAndMixForInputSource(source);
4925fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
49261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
4927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
4928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4930794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurentbool AudioPolicyManager::streamsMatchForvolume(audio_stream_type_t stream1,
4931794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent                                               audio_stream_type_t stream2) {
493299bb2f9afd956174785051827aa96d008b33faeeJean-Michel Trivi    return (stream1 == stream2);
493328d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent}
493428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent
4935e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
4936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return (uint32_t)getStrategy(stream);
4937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4939e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
4940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // By checking the range of stream before calling getStrategy, we avoid
4941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // getStrategy's behavior for invalid streams.  getStrategy would do a ALOGE
4942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and then return STRATEGY_MEDIA, but we want to return the empty set.
4943223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {
49446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return AUDIO_DEVICE_NONE;
49456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
494628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    audio_devices_t devices = AUDIO_DEVICE_NONE;
4947794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
4948794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
494928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
495028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
4951794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
495228d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        audio_devices_t curDevices =
4953447a87bbfe11cc85123ddd94551c3a5ede54ea20Eric Laurent                getDeviceForStrategy((routing_strategy)curStrategy, false /*fromCache*/);
4954cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        for (audio_io_handle_t output : getOutputsForDevice(curDevices, mOutputs)) {
4955cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov            sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
4956794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            if (outputDesc->isStreamActive((audio_stream_type_t)curStream)) {
495728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                curDevices |= outputDesc->device();
495828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            }
49596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
496028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        devices |= curDevices;
4961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
496211c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund
496311c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund    /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it
496411c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund      and doesn't really need to.*/
496511c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund    if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
496611c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund        devices |= AUDIO_DEVICE_OUT_SPEAKER;
496711c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund        devices &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE;
496811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund    }
4969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return devices;
4970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
49722110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffierouting_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
49732110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
4974223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
49752110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return mEngine->getStrategyForStream(stream);
4976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
49785bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviuint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
49795bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // flags to strategy mapping
4980d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
4981d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return (uint32_t) STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
4982d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
49835bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
49845bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return (uint32_t) STRATEGY_ENFORCED_AUDIBLE;
49855bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
49865bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // usage to strategy mapping
49872110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return static_cast<uint32_t>(mEngine->getStrategyForUsage(attr->usage));
49885bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi}
49895bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
4990e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
4991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch(stream) {
49923b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_MUSIC:
4993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
4994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        updateDevicesAndOutputs();
4995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
4996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
4997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
4998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5001d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Triviuint32_t AudioPolicyManager::handleEventForBeacon(int event) {
50029459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent
50039459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    // skip beacon mute management if a dedicated TTS output is available
50049459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    if (mTtsOutputAvailable) {
50059459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent        return 0;
50069459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    }
50079459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent
5008d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    switch(event) {
5009d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STARTING_OUTPUT:
5010d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        mBeaconMuteRefCount++;
5011d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
5012d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STOPPING_OUTPUT:
5013d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        if (mBeaconMuteRefCount > 0) {
5014d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            mBeaconMuteRefCount--;
5015d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
5016d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
5017d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STARTING_BEACON:
5018d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        mBeaconPlayingRefCount++;
5019d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
5020d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STOPPING_BEACON:
5021d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        if (mBeaconPlayingRefCount > 0) {
5022d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            mBeaconPlayingRefCount--;
5023d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
5024d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
5025d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
5026d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
5027d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if (mBeaconMuteRefCount > 0) {
5028d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // any playback causes beacon to be muted
5029d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return setBeaconMute(true);
5030d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    } else {
5031d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // no other playback: unmute when beacon starts playing, mute when it stops
5032d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return setBeaconMute(mBeaconPlayingRefCount == 0);
5033d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
5034d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi}
5035d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
5036d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Triviuint32_t AudioPolicyManager::setBeaconMute(bool mute) {
5037d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    ALOGV("setBeaconMute(%d) mBeaconMuteRefCount=%d mBeaconPlayingRefCount=%d",
5038d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            mute, mBeaconMuteRefCount, mBeaconPlayingRefCount);
5039d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    // keep track of muted state to avoid repeating mute/unmute operations
5040d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if (mBeaconMuted != mute) {
5041d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // mute/unmute AUDIO_STREAM_TTS on all outputs
5042d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        ALOGV("\t muting %d", mute);
5043d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        uint32_t maxLatency = 0;
5044d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        for (size_t i = 0; i < mOutputs.size(); i++) {
5045c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
5046d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            setStreamMute(AUDIO_STREAM_TTS, mute/*on*/,
5047c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    desc,
5048d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                    0 /*delay*/, AUDIO_DEVICE_NONE);
5049d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            const uint32_t latency = desc->latency() * 2;
5050d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            if (latency > maxLatency) {
5051d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                maxLatency = latency;
5052d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            }
5053d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
5054d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        mBeaconMuted = mute;
5055d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return maxLatency;
5056d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
5057d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    return 0;
5058d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi}
5059d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
5060e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
506153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                         bool fromCache)
5062e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5063f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent    // Check if an explicit routing request exists for a stream type corresponding to the
5064f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent    // specified strategy and use it in priority over default routing rules.
5065f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
5066f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent        if (getStrategy((audio_stream_type_t)stream) == strategy) {
5067f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent            audio_devices_t forcedDevice =
5068f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent                    mOutputRoutes.getActiveDeviceForStream(
5069f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent                            (audio_stream_type_t)stream, mAvailableOutputDevices);
5070f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent            if (forcedDevice != AUDIO_DEVICE_NONE) {
5071f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent                return forcedDevice;
5072f3a5a6014a8bf7915bcf9297d536c707c212086dEric Laurent            }
5073aa9811945f575614b3482d09e4d969792701cebbPaul McLean        }
5074aa9811945f575614b3482d09e4d969792701cebbPaul McLean    }
5075aa9811945f575614b3482d09e4d969792701cebbPaul McLean
5076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (fromCache) {
5077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
5078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              strategy, mDeviceForStrategy[strategy]);
5079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mDeviceForStrategy[strategy];
5080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
50812110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return mEngine->getDeviceForStrategy(strategy);
5082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5084e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::updateDevicesAndOutputs()
5085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < NUM_STRATEGIES; i++) {
5087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
5088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPreviousOutputs = mOutputs;
5090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5092e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehuint32_t AudioPolicyManager::checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
5093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       audio_devices_t prevDevice,
5094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       uint32_t delayMs)
5095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // mute/unmute strategies using an incompatible device combination
5097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if muting, wait for the audio in pcm buffer to be drained before proceeding
5098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if unmuting, unmute only after the specified delay
5099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isDuplicated()) {
5100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
5101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t muteWaitMs = 0;
5104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = outputDesc->device();
51053b73df74357b33869b39a1d69427673c780bd805Eric Laurent    bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2);
5106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < NUM_STRATEGIES; i++) {
5108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
5109c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        curDevice = curDevice & outputDesc->supportedDevices();
5110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool mute = shouldMute && (curDevice & device) && (curDevice != device);
5111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool doMute = false;
5112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
5114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            doMute = true;
5115e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStrategyMutedByDevice[i] = true;
5116e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
5117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            doMute = true;
5118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStrategyMutedByDevice[i] = false;
5119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
512099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        if (doMute) {
5121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mOutputs.size(); j++) {
51221f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j);
5123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // skip output if it does not share any device with current output
5124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if ((desc->supportedDevices() & outputDesc->supportedDevices())
5125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        == AUDIO_DEVICE_NONE) {
5126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    continue;
5127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
512837ddbb43721947d6cb5246ec2cf2a6bd8fc28bcbEric Laurent                ALOGVV("checkDeviceMuteStrategies() %s strategy %zu (curDevice %04x)",
5129c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                      mute ? "muting" : "unmuting", i, curDevice);
5130c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setStrategyMute((routing_strategy)i, mute, desc, mute ? 0 : delayMs);
5131ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                if (isStrategyActive(desc, (routing_strategy)i)) {
513299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                    if (mute) {
513399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // FIXME: should not need to double latency if volume could be applied
513499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // immediately by the audioflinger mixer. We must account for the delay
513599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // between now and the next time the audioflinger thread for this output
513699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // will process a buffer (which corresponds to one buffer size,
513799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // usually 1/2 or 1/4 of the latency).
513899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        if (muteWaitMs < desc->latency() * 2) {
513999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                            muteWaitMs = desc->latency() * 2;
5140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        }
5141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
5142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
5143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
5144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
514799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    // temporary mute output if device selection changes to avoid volume bursts due to
514899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    // different per device volumes
514999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    if (outputDesc->isActive() && (device != prevDevice)) {
5150dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        uint32_t tempMuteWaitMs = outputDesc->latency() * 2;
5151dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        // temporary mute duration is conservatively set to 4 times the reported latency
5152dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        uint32_t tempMuteDurationMs = outputDesc->latency() * 4;
5153dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        if (muteWaitMs < tempMuteWaitMs) {
5154dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            muteWaitMs = tempMuteWaitMs;
515599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        }
5156dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
515799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        for (size_t i = 0; i < NUM_STRATEGIES; i++) {
5158ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie            if (isStrategyActive(outputDesc, (routing_strategy)i)) {
5159dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // make sure that we do not start the temporary mute period too early in case of
5160dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // delayed device change
5161dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                setStrategyMute((routing_strategy)i, true, outputDesc, delayMs);
5162c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setStrategyMute((routing_strategy)i, false, outputDesc,
5163dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                                delayMs + tempMuteDurationMs, device);
516499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent            }
516599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        }
516699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    }
516799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent
5168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // wait for the PCM output buffers to empty before proceeding with the rest of the command
5169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (muteWaitMs > delayMs) {
5170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        muteWaitMs -= delayMs;
5171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        usleep(muteWaitMs * 1000);
5172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
5173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
5175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5177c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentuint32_t AudioPolicyManager::setOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
5178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             audio_devices_t device,
5179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             bool force,
51806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                             int delayMs,
51810fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                                             audio_patch_handle_t *patchHandle,
5182b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                                             const char *address,
5183b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                                             bool requiresMuteCheck)
5184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5185c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOGV("setOutputDevice() device %04x delayMs %d", device, delayMs);
5186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioParameter param;
5187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t muteWaitMs;
5188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isDuplicated()) {
5190b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        muteWaitMs = setOutputDevice(outputDesc->subOutput1(), device, force, delayMs,
5191b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                nullptr /* patchHandle */, nullptr /* address */, requiresMuteCheck);
5192b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        muteWaitMs += setOutputDevice(outputDesc->subOutput2(), device, force, delayMs,
5193b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi                nullptr /* patchHandle */, nullptr /* address */, requiresMuteCheck);
5194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
5195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
5197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // output profile
5198c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if ((device != AUDIO_DEVICE_NONE) &&
5199b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi            ((device & outputDesc->supportedDevices()) == AUDIO_DEVICE_NONE)) {
5200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
5201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // filter devices according to output selected
5204c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    device = (audio_devices_t)(device & outputDesc->supportedDevices());
5205e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5206e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t prevDevice = outputDesc->mDevice;
5207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5208aa9811945f575614b3482d09e4d969792701cebbPaul McLean    ALOGV("setOutputDevice() prevDevice 0x%04x", prevDevice);
5209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device != AUDIO_DEVICE_NONE) {
5211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mDevice = device;
5212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5213b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi
5214b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi    // if the outputs are not materially active, there is no need to mute.
5215b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi    if (requiresMuteCheck) {
5216b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
5217b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi    } else {
5218b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        ALOGV("%s: suppressing checkDeviceMuteStrategies", __func__);
5219b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi        muteWaitMs = 0;
5220b3733cf0932256c57c74fc6670bd0e5bdd0edb4dJean-Michel Trivi    }
5221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not change the routing if:
5223b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //      the requested device is AUDIO_DEVICE_NONE
5224b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //      OR the requested device is the same as current device
5225b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //  AND force is not specified
5226b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //  AND the output is connected by a valid audio patch.
5227e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Doing this check here allows the caller to call setOutputDevice() without conditions
5228aa9811945f575614b3482d09e4d969792701cebbPaul McLean    if ((device == AUDIO_DEVICE_NONE || device == prevDevice) &&
5229aa9811945f575614b3482d09e4d969792701cebbPaul McLean        !force &&
5230ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi        outputDesc->getPatchHandle() != 0) {
5231c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        ALOGV("setOutputDevice() setting same device 0x%04x or null device", device);
5232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
5233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setOutputDevice() changing device");
52361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
5237e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do the routing
52381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (device == AUDIO_DEVICE_NONE) {
5239c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        resetOutputDevice(outputDesc, delayMs, NULL);
52401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    } else {
5241c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        DeviceVector deviceList;
5242c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        if ((address == NULL) || (strlen(address) == 0)) {
5243c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            deviceList = mAvailableOutputDevices.getDevicesFromType(device);
5244c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        } else {
5245c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            deviceList = mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address));
5246c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        }
5247c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent
52481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (!deviceList.isEmpty()) {
52491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            struct audio_patch patch;
52501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            outputDesc->toAudioPortConfig(&patch.sources[0]);
52511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sources = 1;
52521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sinks = 0;
52531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
52541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]);
52551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                patch.num_sinks++;
52561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
52576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ssize_t index;
52586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
52596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                index = mAudioPatches.indexOfKey(*patchHandle);
52606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
5261ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi                index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
52626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
52636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp< AudioPatch> patchDesc;
52646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
52656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
52666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc = mAudioPatches.valueAt(index);
52676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                afPatchHandle = patchDesc->mAfPatchHandle;
52686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
52696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
52701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            status_t status = mpClientInterface->createAudioPatch(&patch,
52716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                   &afPatchHandle,
52726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                   delayMs);
52731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d"
52741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                    "num_sources %d num_sinks %d",
52756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                       status, afPatchHandle, patch.num_sources, patch.num_sinks);
52761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            if (status == NO_ERROR) {
52776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (index < 0) {
527898cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie                    patchDesc = new AudioPatch(&patch, mUidCached);
52796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    addAudioPatch(patchDesc->mHandle, patchDesc);
52806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                } else {
52816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    patchDesc->mPatch = patch;
52826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
52836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mAfPatchHandle = afPatchHandle;
52846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchHandle) {
52856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    *patchHandle = patchDesc->mHandle;
52866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
5287ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi                outputDesc->setPatchHandle(patchDesc->mHandle);
52886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                nextAudioPortGeneration();
5289b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                mpClientInterface->onAudioPatchListUpdate();
52901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
52911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
5292f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu
5293f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu        // inform all input as well
5294f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu        for (size_t i = 0; i < mInputs.size(); i++) {
5295f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu            const sp<AudioInputDescriptor>  inputDescriptor = mInputs.valueAt(i);
529653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if (!is_virtual_input_device(inputDescriptor->mDevice)) {
5297f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                AudioParameter inputCmd = AudioParameter();
5298f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                ALOGV("%s: inform input %d of device:%d", __func__,
5299f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                      inputDescriptor->mIoHandle, device);
5300f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                inputCmd.addInt(String8(AudioParameter::keyRouting),device);
5301f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                mpClientInterface->setParameters(inputDescriptor->mIoHandle,
5302f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                                                 inputCmd.toString(),
5303f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                                                 delayMs);
5304f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu            }
5305f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu        }
53061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
5307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // update stream volumes according to new device
5309c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    applyStreamVolumes(outputDesc, device, delayMs);
5310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return muteWaitMs;
5312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5314c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t AudioPolicyManager::resetOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
53156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               int delayMs,
53166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               audio_patch_handle_t *patchHandle)
53171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
53186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index;
53196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patchHandle) {
53206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        index = mAudioPatches.indexOfKey(*patchHandle);
53216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
5322ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi        index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
53236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
53246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index < 0) {
53251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return INVALID_OPERATION;
53261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
53276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
53286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, delayMs);
53291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status);
5330a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten    outputDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);
53316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    removeAudioPatch(patchDesc->mHandle);
53326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
5333b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPatchListUpdate();
53341c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
53351c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
53361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
53371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::setInputDevice(audio_io_handle_t input,
53381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                            audio_devices_t device,
53396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            bool force,
53406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            audio_patch_handle_t *patchHandle)
53411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
53421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    status_t status = NO_ERROR;
53431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
53441f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
53451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) {
53461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        inputDesc->mDevice = device;
53471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
53481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device);
53491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (!deviceList.isEmpty()) {
53501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            struct audio_patch patch;
53511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            inputDesc->toAudioPortConfig(&patch.sinks[0]);
5352daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent            // AUDIO_SOURCE_HOTWORD is for internal use only:
5353daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent            // handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL
5354df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent            if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD &&
5355599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                    !inputDesc->isSoundTrigger()) {
5356daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent                patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION;
5357daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent            }
53581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sinks = 1;
53591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            //only one input device for now
53601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
53611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sources = 1;
53626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ssize_t index;
53636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
53646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                index = mAudioPatches.indexOfKey(*patchHandle);
53656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
53668c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
53676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
53686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp< AudioPatch> patchDesc;
53696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
53706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
53716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc = mAudioPatches.valueAt(index);
53726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                afPatchHandle = patchDesc->mAfPatchHandle;
53736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
53746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
53751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            status_t status = mpClientInterface->createAudioPatch(&patch,
53766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  &afPatchHandle,
53771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                                  0);
53781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d",
53796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                          status, afPatchHandle);
53801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            if (status == NO_ERROR) {
53816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (index < 0) {
538298cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie                    patchDesc = new AudioPatch(&patch, mUidCached);
53836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    addAudioPatch(patchDesc->mHandle, patchDesc);
53846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                } else {
53856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    patchDesc->mPatch = patch;
53866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
53876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mAfPatchHandle = afPatchHandle;
53886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchHandle) {
53896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    *patchHandle = patchDesc->mHandle;
53906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
53918c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                inputDesc->setPatchHandle(patchDesc->mHandle);
53926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                nextAudioPortGeneration();
5393b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                mpClientInterface->onAudioPatchListUpdate();
53941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
53951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
53961c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
53971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
53981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
53991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
54006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input,
54016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                              audio_patch_handle_t *patchHandle)
54021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
54031f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
54046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index;
54056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patchHandle) {
54066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        index = mAudioPatches.indexOfKey(*patchHandle);
54076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
54088c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
54096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
54106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index < 0) {
54111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return INVALID_OPERATION;
54121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
54136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
54146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
54151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("resetInputDevice() releaseAudioPatch returned %d", status);
5416a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten    inputDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);
54176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    removeAudioPatch(patchDesc->mHandle);
54186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
5419b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPatchListUpdate();
54201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
54211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
54221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
542356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivisp<IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
5424e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh                                                  const String8& address,
542553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  uint32_t& samplingRate,
5426f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                  audio_format_t& format,
5427f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                  audio_channel_mask_t& channelMask,
542853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  audio_input_flags_t flags)
5429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Choose an input profile based on the requested capture parameters: select the first available
5431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // profile supporting all requested parameters.
5432f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    //
5433f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    // TODO: perhaps isCompatibleProfile should return a "matching" score so we can return
5434f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    // the best matching profile, not the first one.
5435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5436730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten    sp<IOProfile> firstInexact;
5437730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten    uint32_t updatedSamplingRate = 0;
5438730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten    audio_format_t updatedFormat = AUDIO_FORMAT_INVALID;
5439730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten    audio_channel_mask_t updatedChannelMask = AUDIO_CHANNEL_INVALID;
54407e22e94d0654d7ab4c31aee7f7120542e358a5abMikhail Naganov    for (const auto& hwModule : mHwModules) {
5441a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov        for (const auto& profile : hwModule->getInputProfiles()) {
5442d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            // profile->log();
5443730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten            //updatedFormat = format;
5444275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            if (profile->isCompatibleProfile(device, address, samplingRate,
5445730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             &samplingRate  /*updatedSamplingRate*/,
5446f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             format,
5447730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             &format,       /*updatedFormat*/
5448f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             channelMask,
5449730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             &channelMask   /*updatedChannelMask*/,
5450730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             // FIXME ugly cast
5451730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             (audio_output_flags_t) flags,
5452730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             true /*exactMatchRequiredForInputFlags*/)) {
5453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return profile;
5454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
5455730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten            if (firstInexact == nullptr && profile->isCompatibleProfile(device, address,
5456730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             samplingRate,
5457730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             &updatedSamplingRate,
5458730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             format,
5459730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             &updatedFormat,
5460730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             channelMask,
5461730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             &updatedChannelMask,
5462730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             // FIXME ugly cast
5463730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             (audio_output_flags_t) flags,
5464730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                                             false /*exactMatchRequiredForInputFlags*/)) {
5465730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten                firstInexact = profile;
5466730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten            }
5467730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten
5468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5470730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten    if (firstInexact != nullptr) {
5471730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten        samplingRate = updatedSamplingRate;
5472730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten        format = updatedFormat;
5473730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten        channelMask = updatedChannelMask;
5474730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten        return firstInexact;
5475730b926555ccb9ad5f7d4c47bf01ade526cceef0Glenn Kasten    }
5476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NULL;
5477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5479c73ca6ef04136f28306784ad35f444538f081957Eric Laurent
5480c73ca6ef04136f28306784ad35f444538f081957Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource,
548153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                                  AudioMix **policyMix)
5482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5483036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
5484036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    audio_devices_t selectedDeviceFromMix =
5485036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie           mPolicyMixes.getDeviceAndMixForInputSource(inputSource, availableDeviceTypes, policyMix);
5486275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
5487036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    if (selectedDeviceFromMix != AUDIO_DEVICE_NONE) {
5488036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        return selectedDeviceFromMix;
5489275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
5490c73ca6ef04136f28306784ad35f444538f081957Eric Laurent    return getDeviceForInputSource(inputSource);
5491c73ca6ef04136f28306784ad35f444538f081957Eric Laurent}
5492c73ca6ef04136f28306784ad35f444538f081957Eric Laurent
5493c73ca6ef04136f28306784ad35f444538f081957Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
5494c73ca6ef04136f28306784ad35f444538f081957Eric Laurent{
5495ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    // Routing
5496ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    // Scan the whole RouteMap to see if we have an explicit route:
5497ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    // if the input source in the RouteMap is the same as the argument above,
5498ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    // and activity count is non-zero and the device in the route descriptor is available
5499ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent    // then select this device.
5500466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    for (size_t routeIndex = 0; routeIndex < mInputRoutes.size(); routeIndex++) {
5501466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean         sp<SessionRoute> route = mInputRoutes.valueAt(routeIndex);
55022157f5bc0c54a77318e75076365eff739e07056fEric Laurent         if ((inputSource == route->mSource) && route->isActiveOrChanged() &&
5503ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent                 (mAvailableInputDevices.indexOf(route->mDeviceDescriptor) >= 0)) {
5504466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean             return route->mDeviceDescriptor->type();
5505466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean         }
5506466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean     }
5507466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
5508466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean     return mEngine->getDeviceForInputSource(inputSource);
5509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5511e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::computeVolume(audio_stream_type_t stream,
5512d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                        int index,
5513d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                        audio_devices_t device)
5514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
551500a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi    float volumeDB = mVolumeCurves->volIndexToDb(stream, Volume::getDeviceCategory(device), index);
55163d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi
55173d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // handle the case of accessibility active while a ringtone is playing: if the ringtone is much
55183d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // louder than the accessibility prompt, the prompt cannot be heard, thus masking the touch
55193d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // exploration of the dialer UI. In this situation, bring the accessibility volume closer to
55203d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // the ringtone volume
55213d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    if ((stream == AUDIO_STREAM_ACCESSIBILITY)
55223d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi            && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState())
55233d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi            && isStreamActive(AUDIO_STREAM_RING, 0)) {
55243d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi        const float ringVolumeDB = computeVolume(AUDIO_STREAM_RING, index, device);
55253d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi        return ringVolumeDB - 4 > volumeDB ? ringVolumeDB - 4 : volumeDB;
55263d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    }
55273d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi
5528719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi    // in-call: always cap earpiece volume by voice volume + some low headroom
55297731b5add3a8ba0f57d8f4b299ba7a432ecc7119Eric Laurent    if ((stream != AUDIO_STREAM_VOICE_CALL) && (device & AUDIO_DEVICE_OUT_EARPIECE) &&
55307731b5add3a8ba0f57d8f4b299ba7a432ecc7119Eric Laurent            (isInCall() || mOutputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL))) {
5531719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi        switch (stream) {
5532719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi        case AUDIO_STREAM_SYSTEM:
5533719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi        case AUDIO_STREAM_RING:
5534719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi        case AUDIO_STREAM_MUSIC:
5535719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi        case AUDIO_STREAM_ALARM:
5536719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi        case AUDIO_STREAM_NOTIFICATION:
5537719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi        case AUDIO_STREAM_ENFORCED_AUDIBLE:
5538719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi        case AUDIO_STREAM_DTMF:
5539719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi        case AUDIO_STREAM_ACCESSIBILITY: {
55407731b5add3a8ba0f57d8f4b299ba7a432ecc7119Eric Laurent            int voiceVolumeIndex =
55417731b5add3a8ba0f57d8f4b299ba7a432ecc7119Eric Laurent                mVolumeCurves->getVolumeIndex(AUDIO_STREAM_VOICE_CALL, AUDIO_DEVICE_OUT_EARPIECE);
55427731b5add3a8ba0f57d8f4b299ba7a432ecc7119Eric Laurent            const float maxVoiceVolDb =
55437731b5add3a8ba0f57d8f4b299ba7a432ecc7119Eric Laurent                computeVolume(AUDIO_STREAM_VOICE_CALL, voiceVolumeIndex, AUDIO_DEVICE_OUT_EARPIECE)
55447731b5add3a8ba0f57d8f4b299ba7a432ecc7119Eric Laurent                + IN_CALL_EARPIECE_HEADROOM_DB;
5545719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi            if (volumeDB > maxVoiceVolDb) {
5546719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi                ALOGV("computeVolume() stream %d at vol=%f overriden by stream %d at vol=%f",
5547719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi                        stream, volumeDB, AUDIO_STREAM_VOICE_CALL, maxVoiceVolDb);
5548719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi                volumeDB = maxVoiceVolDb;
5549719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi            }
5550719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi            } break;
5551719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi        default:
5552719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi            break;
5553719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi        }
5554719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi    }
5555719a987e9d8cb54bc7da74941a8bfacbc844900dJean-Michel Trivi
5556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if a headset is connected, apply the following rules to ring tones and notifications
5557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // to avoid sound level bursts in user's ears:
55586af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent    // - always attenuate notifications volume by 6dB
55596af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent    // - attenuate ring tones volume by 6dB unless music is not playing and
55606af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent    // speaker is part of the select devices
5561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // - if music is playing, always limit the volume to current music volume,
5562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // with a minimum threshold at -36dB so that notification is always perceived.
55633b73df74357b33869b39a1d69427673c780bd805Eric Laurent    const routing_strategy stream_strategy = getStrategy(stream);
5564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
5565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
5566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_WIRED_HEADSET |
5567904d632a24db8f94de83e44f7179d1c0af022b03Eric Laurent            AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
556800f928c514fd5e2ea4004cb6e0ca665e337b57c4Jakub Pawlowski            AUDIO_DEVICE_OUT_USB_HEADSET |
556900f928c514fd5e2ea4004cb6e0ca665e337b57c4Jakub Pawlowski            AUDIO_DEVICE_OUT_HEARING_AID)) &&
5570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ((stream_strategy == STRATEGY_SONIFICATION)
5571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
55723b73df74357b33869b39a1d69427673c780bd805Eric Laurent                || (stream == AUDIO_STREAM_SYSTEM)
5573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
55742110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                    (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
5575d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            mVolumeCurves->canBeMuted(stream)) {
5576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // when the phone is ringing we must consider that music could have been paused just before
5577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // by the music application and behave as if music was active if the last music track was
5578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // just stopped
55793b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
5580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mLimitRingtoneVolume) {
558100a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
5582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
5583ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent            float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
5584d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                             mVolumeCurves->getVolumeIndex(AUDIO_STREAM_MUSIC,
5585d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                                                              musicDevice),
5586d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                             musicDevice);
5587ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent            float minVolDB = (musicVolDB > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
5588ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent                    musicVolDB : SONIFICATION_HEADSET_VOLUME_MIN_DB;
558900a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            if (volumeDB > minVolDB) {
559000a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                volumeDB = minVolDB;
5591ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent                ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDB, musicVolDB);
5592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
559300a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            if (device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
559400a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES)) {
559500a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                // on A2DP, also ensure notification volume is not too low compared to media when
559600a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                // intended to be played
559700a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                if ((volumeDB > -96.0f) &&
559800a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                        (musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB > volumeDB)) {
559900a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                    ALOGV("computeVolume increasing volume for stream=%d device=0x%X from %f to %f",
560000a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                            stream, device,
560100a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                            volumeDB, musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB);
560200a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                    volumeDB = musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB;
560300a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                }
560400a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            }
56056af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent        } else if ((Volume::getDeviceForVolume(device) != AUDIO_DEVICE_OUT_SPEAKER) ||
56066af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent                stream_strategy != STRATEGY_SONIFICATION) {
560700a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
5608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
561100a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi    return volumeDB;
5612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5614e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
5615c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   int index,
5616c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   const sp<AudioOutputDescriptor>& outputDesc,
5617c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   audio_devices_t device,
5618c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   int delayMs,
5619c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   bool force)
5620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do not change actual stream volume if the stream is muted
5622c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mMuteCount[stream] != 0) {
5623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("checkAndSetVolume() stream %d muted count %d",
5624c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent              stream, outputDesc->mMuteCount[stream]);
5625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
5626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
56272110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    audio_policy_forced_cfg_t forceUseForComm =
56282110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION);
5629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do not change in call volume if bluetooth is connected and vice versa
56302110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if ((stream == AUDIO_STREAM_VOICE_CALL && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
56312110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        (stream == AUDIO_STREAM_BLUETOOTH_SCO && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO)) {
5632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
56332110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie             stream, forceUseForComm);
5634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
5635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5637c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
5638c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        device = outputDesc->device();
5639275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
5640c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
5641ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent    float volumeDb = computeVolume(stream, index, device);
5642da7581eca3523a21142a3d259531c938f8dc717cHW Lee    if (outputDesc->isFixedVolume(device) ||
5643da7581eca3523a21142a3d259531c938f8dc717cHW Lee            // Force VoIP volume to max for bluetooth SCO
5644da7581eca3523a21142a3d259531c938f8dc717cHW Lee            ((stream == AUDIO_STREAM_VOICE_CALL || stream == AUDIO_STREAM_BLUETOOTH_SCO) &&
5645da7581eca3523a21142a3d259531c938f8dc717cHW Lee             (device & AUDIO_DEVICE_OUT_ALL_SCO) != 0)) {
5646ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent        volumeDb = 0.0f;
5647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5649ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent    outputDesc->setVolume(volumeDb, stream, device, delayMs, force);
5650c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
56513b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (stream == AUDIO_STREAM_VOICE_CALL ||
56523b73df74357b33869b39a1d69427673c780bd805Eric Laurent        stream == AUDIO_STREAM_BLUETOOTH_SCO) {
5653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        float voiceVolume;
5654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Force voice volume to max for bluetooth SCO as volume is managed by the headset
56553b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (stream == AUDIO_STREAM_VOICE_CALL) {
5656d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            voiceVolume = (float)index/(float)mVolumeCurves->getVolumeIndexMax(stream);
5657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else {
5658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            voiceVolume = 1.0;
5659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5660e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
566118fba84019d778b3c20875d93f9f36c2410ecf33Eric Laurent        if (voiceVolume != mLastVoiceVolume) {
5662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
5663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mLastVoiceVolume = voiceVolume;
5664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5667e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
5668e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5670c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid AudioPolicyManager::applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
5671c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                audio_devices_t device,
5672c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                int delayMs,
5673c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                bool force)
5674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5675c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOGVV("applyStreamVolumes() for device %08x", device);
5676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5677794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
56783b73df74357b33869b39a1d69427673c780bd805Eric Laurent        checkAndSetVolume((audio_stream_type_t)stream,
5679d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                          mVolumeCurves->getVolumeIndex((audio_stream_type_t)stream, device),
5680c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                          outputDesc,
5681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          device,
5682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          delayMs,
5683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          force);
5684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5687e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStrategyMute(routing_strategy strategy,
5688c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             bool on,
5689c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             const sp<AudioOutputDescriptor>& outputDesc,
5690c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             int delayMs,
5691c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             audio_devices_t device)
5692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
569372249d5b2f9f42a96c0e0825431e8f3f49b82644Eric Laurent    ALOGVV("setStrategyMute() strategy %d, mute %d, output ID %d",
569472249d5b2f9f42a96c0e0825431e8f3f49b82644Eric Laurent           strategy, on, outputDesc->getId());
5695794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
56963b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (getStrategy((audio_stream_type_t)stream) == strategy) {
5697c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStreamMute((audio_stream_type_t)stream, on, outputDesc, delayMs, device);
5698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5702e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
5703c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           bool on,
5704c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           const sp<AudioOutputDescriptor>& outputDesc,
5705c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           int delayMs,
5706c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           audio_devices_t device)
5707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
5709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = outputDesc->device();
5710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5712c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOGVV("setStreamMute() stream %d, mute %d, mMuteCount %d device %04x",
5713c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent          stream, on, outputDesc->mMuteCount[stream], device);
5714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (on) {
5716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mMuteCount[stream] == 0) {
5717d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            if (mVolumeCurves->canBeMuted(stream) &&
57183b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
57192110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                     (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) {
5720c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                checkAndSetVolume(stream, 0, outputDesc, device, delayMs);
5721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
5722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
5724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mMuteCount[stream]++;
5725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
5726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mMuteCount[stream] == 0) {
5727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setStreamMute() unmuting non muted stream!");
5728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
5729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (--outputDesc->mMuteCount[stream] == 0) {
5731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            checkAndSetVolume(stream,
5732d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                              mVolumeCurves->getVolumeIndex(stream, device),
5733c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                              outputDesc,
5734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              device,
5735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              delayMs);
5736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5737e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5740e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
57413b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                      bool starting, bool stateChange)
5742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
574387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    if(!hasPrimaryOutput()) {
574487ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        return;
574587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    }
574687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent
5747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if the stream pertains to sonification strategy and we are in call we must
5748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // mute the stream if it is low visibility. If it is high visibility, we must play a tone
5749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the device used for phone strategy and play the tone if the selected device does not
5750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // interfere with the device used for phone strategy
5751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
5752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // many times as there are active tracks on the output
57533b73df74357b33869b39a1d69427673c780bd805Eric Laurent    const routing_strategy stream_strategy = getStrategy(stream);
5754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((stream_strategy == STRATEGY_SONIFICATION) ||
5755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
5756c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mPrimaryOutput;
5757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
5758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                stream, starting, outputDesc->mDevice, stateChange);
5759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mRefCount[stream]) {
5760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            int muteCount = 1;
5761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (stateChange) {
5762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                muteCount = outputDesc->mRefCount[stream];
5763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
57643b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (audio_is_low_visibility(stream)) {
5765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
5766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                for (int i = 0; i < muteCount; i++) {
5767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    setStreamMute(stream, starting, mPrimaryOutput);
5768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
5769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
5770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("handleIncallSonification() high visibility");
5771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (outputDesc->device() &
5772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
5773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
5774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    for (int i = 0; i < muteCount; i++) {
5775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        setStreamMute(stream, starting, mPrimaryOutput);
5776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
5777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
5778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (starting) {
57793b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
57803b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                 AUDIO_STREAM_VOICE_CALL);
5781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else {
5782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mpClientInterface->stopTone();
5783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
5784e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
5785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5786e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5788e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
57895bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr)
57905bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{
57915bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // flags to stream type mapping
57925bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
57935bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_ENFORCED_AUDIBLE;
57945bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
57955bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
57965bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_BLUETOOTH_SCO;
57975bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
579879ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
579979ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi        return AUDIO_STREAM_TTS;
580079ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi    }
58015bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
58025bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // usage to stream type mapping
58035bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    switch (attr->usage) {
58045bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_MEDIA:
58055bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_GAME:
580636867767ba86244b0d942255b9d241b092151309Jean-Michel Trivi    case AUDIO_USAGE_ASSISTANT:
58075bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
58085bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_MUSIC;
5809223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
5810223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent        return AUDIO_STREAM_ACCESSIBILITY;
58115bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
58125bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_SYSTEM;
58135bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_VOICE_COMMUNICATION:
58145bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_VOICE_CALL;
58155bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
58165bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
58175bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_DTMF;
58185bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
58195bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_ALARM:
58205bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_ALARM;
58215bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
58225bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_RING;
58235bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
58245bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION:
58255bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
58265bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
58275bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
58285bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_EVENT:
58295bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_NOTIFICATION;
58305bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
58315bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_UNKNOWN:
58325bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    default:
58335bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_MUSIC;
58345bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
58355bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi}
5836e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
583753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiebool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa)
583853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
5839e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    // has flags that map to a strategy?
5840e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) {
5841e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        return true;
5842e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
5843e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
5844e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    // has known usage?
5845e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    switch (paa->usage) {
5846e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_UNKNOWN:
5847e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_MEDIA:
5848e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_VOICE_COMMUNICATION:
5849e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
5850e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ALARM:
5851e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION:
5852e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
5853e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
5854e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
5855e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
5856e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_EVENT:
5857e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
5858e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
5859e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
5860e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_GAME:
5861275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    case AUDIO_USAGE_VIRTUAL_SOURCE:
586236867767ba86244b0d942255b9d241b092151309Jean-Michel Trivi    case AUDIO_USAGE_ASSISTANT:
5863e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        break;
5864e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    default:
5865e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        return false;
5866e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
5867e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    return true;
5868e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent}
5869e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
5870e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehbool AudioPolicyManager::isStrategyActive(const sp<AudioOutputDescriptor>& outputDesc,
5871ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                          routing_strategy strategy, uint32_t inPastMs,
5872ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                          nsecs_t sysTime) const
5873ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie{
5874ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    if ((sysTime == 0) && (inPastMs != 0)) {
5875ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie        sysTime = systemTime();
5876ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    }
5877794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int i = 0; i < (int)AUDIO_STREAM_FOR_POLICY_CNT; i++) {
5878ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie        if (((getStrategy((audio_stream_type_t)i) == strategy) ||
5879ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                (NUM_STRATEGIES == strategy)) &&
5880ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                outputDesc->isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
5881ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie            return true;
5882ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie        }
5883ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    }
5884ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    return false;
5885ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie}
5886ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie
58872110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffieaudio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
58882110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
58892110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return mEngine->getForceUse(usage);
58902110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie}
58912110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
58922110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffiebool AudioPolicyManager::isInCall()
58932110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
58942110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return isStateInCall(mEngine->getPhoneState());
58952110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie}
58962110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
58972110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffiebool AudioPolicyManager::isStateInCall(int state)
58982110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
58992110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return is_state_in_call(state);
59002110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie}
59012110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
5902d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentvoid AudioPolicyManager::cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc)
5903d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
5904d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--)  {
5905d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
5906d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (sourceDesc->mDevice->equals(deviceDesc)) {
5907d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s releasing audio source %d", __FUNCTION__, sourceDesc->getHandle());
5908d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            stopAudioSource(sourceDesc->getHandle());
5909d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5910d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
5911d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
5912d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--)  {
5913d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
5914d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        bool release = false;
5915d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        for (size_t j = 0; j < patchDesc->mPatch.num_sources && !release; j++)  {
5916d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            const struct audio_port_config *source = &patchDesc->mPatch.sources[j];
5917d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            if (source->type == AUDIO_PORT_TYPE_DEVICE &&
5918d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                    source->ext.device.type == deviceDesc->type()) {
5919d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                release = true;
5920d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            }
5921d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5922d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        for (size_t j = 0; j < patchDesc->mPatch.num_sinks && !release; j++)  {
5923d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            const struct audio_port_config *sink = &patchDesc->mPatch.sinks[j];
5924d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            if (sink->type == AUDIO_PORT_TYPE_DEVICE &&
5925d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                    sink->ext.device.type == deviceDesc->type()) {
5926d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                release = true;
5927d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            }
5928d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5929d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (release) {
5930d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s releasing patch %u", __FUNCTION__, patchDesc->mHandle);
5931d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            releaseAudioPatch(patchDesc->mHandle, patchDesc->mUid);
5932d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5933d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
5934d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
5935d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
593609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk// Modify the list of surround sound formats supported.
59370709b0aba2adb719d347341ff58441347a1c1582Phil Burkvoid AudioPolicyManager::filterSurroundFormats(FormatVector *formatsPtr) {
59380709b0aba2adb719d347341ff58441347a1c1582Phil Burk    FormatVector &formats = *formatsPtr;
593907ac114c3965e16fe523f88c913e701602604589Phil Burk    // TODO Set this based on Config properties.
594007ac114c3965e16fe523f88c913e701602604589Phil Burk    const bool alwaysForceAC3 = true;
594109bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
594209bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
594309bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
59440709b0aba2adb719d347341ff58441347a1c1582Phil Burk    ALOGD("%s: forced use = %d", __FUNCTION__, forceUse);
594509bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
5946817729095966c338615a8a791d2dbf774fc034efjiabin    // If MANUAL, keep the supported surround sound formats as current enabled ones.
5947817729095966c338615a8a791d2dbf774fc034efjiabin    if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
5948817729095966c338615a8a791d2dbf774fc034efjiabin        formats.clear();
5949817729095966c338615a8a791d2dbf774fc034efjiabin        for (auto it = mSurroundFormats.begin(); it != mSurroundFormats.end(); it++) {
5950817729095966c338615a8a791d2dbf774fc034efjiabin            formats.add(*it);
5951817729095966c338615a8a791d2dbf774fc034efjiabin        }
5952817729095966c338615a8a791d2dbf774fc034efjiabin        // Always enable IEC61937 when in MANUAL mode.
5953817729095966c338615a8a791d2dbf774fc034efjiabin        formats.add(AUDIO_FORMAT_IEC61937);
5954817729095966c338615a8a791d2dbf774fc034efjiabin    } else { // NEVER, AUTO or ALWAYS
5955817729095966c338615a8a791d2dbf774fc034efjiabin        // Analyze original support for various formats.
5956817729095966c338615a8a791d2dbf774fc034efjiabin        bool supportsAC3 = false;
5957817729095966c338615a8a791d2dbf774fc034efjiabin        bool supportsOtherSurround = false;
5958817729095966c338615a8a791d2dbf774fc034efjiabin        bool supportsIEC61937 = false;
5959817729095966c338615a8a791d2dbf774fc034efjiabin        mSurroundFormats.clear();
5960817729095966c338615a8a791d2dbf774fc034efjiabin        for (ssize_t formatIndex = 0; formatIndex < (ssize_t)formats.size(); formatIndex++) {
5961817729095966c338615a8a791d2dbf774fc034efjiabin            audio_format_t format = formats[formatIndex];
5962817729095966c338615a8a791d2dbf774fc034efjiabin            switch (format) {
5963817729095966c338615a8a791d2dbf774fc034efjiabin                case AUDIO_FORMAT_AC3:
5964817729095966c338615a8a791d2dbf774fc034efjiabin                    supportsAC3 = true;
5965817729095966c338615a8a791d2dbf774fc034efjiabin                    break;
5966817729095966c338615a8a791d2dbf774fc034efjiabin                case AUDIO_FORMAT_E_AC3:
5967817729095966c338615a8a791d2dbf774fc034efjiabin                case AUDIO_FORMAT_DTS:
5968817729095966c338615a8a791d2dbf774fc034efjiabin                case AUDIO_FORMAT_DTS_HD:
5969817729095966c338615a8a791d2dbf774fc034efjiabin                    // If ALWAYS, remove all other surround formats here
5970817729095966c338615a8a791d2dbf774fc034efjiabin                    // since we will add them later.
5971817729095966c338615a8a791d2dbf774fc034efjiabin                    if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
5972817729095966c338615a8a791d2dbf774fc034efjiabin                        formats.removeAt(formatIndex);
5973817729095966c338615a8a791d2dbf774fc034efjiabin                        formatIndex--;
5974817729095966c338615a8a791d2dbf774fc034efjiabin                    }
5975817729095966c338615a8a791d2dbf774fc034efjiabin                    supportsOtherSurround = true;
5976817729095966c338615a8a791d2dbf774fc034efjiabin                    break;
5977817729095966c338615a8a791d2dbf774fc034efjiabin                case AUDIO_FORMAT_IEC61937:
5978817729095966c338615a8a791d2dbf774fc034efjiabin                    supportsIEC61937 = true;
5979817729095966c338615a8a791d2dbf774fc034efjiabin                    break;
5980817729095966c338615a8a791d2dbf774fc034efjiabin                default:
5981817729095966c338615a8a791d2dbf774fc034efjiabin                    break;
5982817729095966c338615a8a791d2dbf774fc034efjiabin            }
5983817729095966c338615a8a791d2dbf774fc034efjiabin        }
5984817729095966c338615a8a791d2dbf774fc034efjiabin
5985817729095966c338615a8a791d2dbf774fc034efjiabin        // Modify formats based on surround preferences.
5986817729095966c338615a8a791d2dbf774fc034efjiabin        // If NEVER, remove support for surround formats.
5987817729095966c338615a8a791d2dbf774fc034efjiabin        if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
5988817729095966c338615a8a791d2dbf774fc034efjiabin            if (supportsAC3 || supportsOtherSurround || supportsIEC61937) {
5989817729095966c338615a8a791d2dbf774fc034efjiabin                // Remove surround sound related formats.
5990817729095966c338615a8a791d2dbf774fc034efjiabin                for (size_t formatIndex = 0; formatIndex < formats.size(); ) {
5991817729095966c338615a8a791d2dbf774fc034efjiabin                    audio_format_t format = formats[formatIndex];
5992817729095966c338615a8a791d2dbf774fc034efjiabin                    switch(format) {
5993817729095966c338615a8a791d2dbf774fc034efjiabin                        case AUDIO_FORMAT_AC3:
5994817729095966c338615a8a791d2dbf774fc034efjiabin                        case AUDIO_FORMAT_E_AC3:
5995817729095966c338615a8a791d2dbf774fc034efjiabin                        case AUDIO_FORMAT_DTS:
5996817729095966c338615a8a791d2dbf774fc034efjiabin                        case AUDIO_FORMAT_DTS_HD:
5997817729095966c338615a8a791d2dbf774fc034efjiabin                        case AUDIO_FORMAT_IEC61937:
5998817729095966c338615a8a791d2dbf774fc034efjiabin                            formats.removeAt(formatIndex);
5999817729095966c338615a8a791d2dbf774fc034efjiabin                            break;
6000817729095966c338615a8a791d2dbf774fc034efjiabin                        default:
6001817729095966c338615a8a791d2dbf774fc034efjiabin                            formatIndex++; // keep it
6002817729095966c338615a8a791d2dbf774fc034efjiabin                            break;
6003817729095966c338615a8a791d2dbf774fc034efjiabin                    }
6004dd60115699e42811289432dddfecaf4ab8d187fejiabin                }
6005817729095966c338615a8a791d2dbf774fc034efjiabin                supportsAC3 = false;
6006817729095966c338615a8a791d2dbf774fc034efjiabin                supportsOtherSurround = false;
6007817729095966c338615a8a791d2dbf774fc034efjiabin                supportsIEC61937 = false;
6008817729095966c338615a8a791d2dbf774fc034efjiabin            }
6009817729095966c338615a8a791d2dbf774fc034efjiabin        } else { // AUTO or ALWAYS
6010817729095966c338615a8a791d2dbf774fc034efjiabin            // Most TVs support AC3 even if they do not report it in the EDID.
6011817729095966c338615a8a791d2dbf774fc034efjiabin            if ((alwaysForceAC3 || (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS))
6012817729095966c338615a8a791d2dbf774fc034efjiabin                    && !supportsAC3) {
6013817729095966c338615a8a791d2dbf774fc034efjiabin                formats.add(AUDIO_FORMAT_AC3);
6014817729095966c338615a8a791d2dbf774fc034efjiabin                supportsAC3 = true;
6015817729095966c338615a8a791d2dbf774fc034efjiabin            }
6016817729095966c338615a8a791d2dbf774fc034efjiabin
6017817729095966c338615a8a791d2dbf774fc034efjiabin            // If ALWAYS, add support for raw surround formats if all are missing.
6018817729095966c338615a8a791d2dbf774fc034efjiabin            // This assumes that if any of these formats are reported by the HAL
6019817729095966c338615a8a791d2dbf774fc034efjiabin            // then the report is valid and should not be modified.
6020817729095966c338615a8a791d2dbf774fc034efjiabin            if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
6021817729095966c338615a8a791d2dbf774fc034efjiabin                formats.add(AUDIO_FORMAT_E_AC3);
6022817729095966c338615a8a791d2dbf774fc034efjiabin                formats.add(AUDIO_FORMAT_DTS);
6023817729095966c338615a8a791d2dbf774fc034efjiabin                formats.add(AUDIO_FORMAT_DTS_HD);
602407ac114c3965e16fe523f88c913e701602604589Phil Burk                supportsOtherSurround = true;
6025817729095966c338615a8a791d2dbf774fc034efjiabin            }
6026817729095966c338615a8a791d2dbf774fc034efjiabin
6027817729095966c338615a8a791d2dbf774fc034efjiabin            // Add support for IEC61937 if any raw surround supported.
6028817729095966c338615a8a791d2dbf774fc034efjiabin            // The HAL could do this but add it here, just in case.
6029817729095966c338615a8a791d2dbf774fc034efjiabin            if ((supportsAC3 || supportsOtherSurround) && !supportsIEC61937) {
6030817729095966c338615a8a791d2dbf774fc034efjiabin                formats.add(AUDIO_FORMAT_IEC61937);
603109bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk                supportsIEC61937 = true;
6032817729095966c338615a8a791d2dbf774fc034efjiabin            }
603309bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
6034817729095966c338615a8a791d2dbf774fc034efjiabin            // Add reported surround sound formats to enabled surround formats.
6035817729095966c338615a8a791d2dbf774fc034efjiabin            for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
603607ac114c3965e16fe523f88c913e701602604589Phil Burk                audio_format_t format = formats[formatIndex];
603707ac114c3965e16fe523f88c913e701602604589Phil Burk                switch(format) {
603807ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_AC3:
603907ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_E_AC3:
604007ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_DTS:
604107ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_DTS_HD:
6042817729095966c338615a8a791d2dbf774fc034efjiabin                    case AUDIO_FORMAT_AAC_LC:
6043817729095966c338615a8a791d2dbf774fc034efjiabin                    case AUDIO_FORMAT_DOLBY_TRUEHD:
6044817729095966c338615a8a791d2dbf774fc034efjiabin                    case AUDIO_FORMAT_E_AC3_JOC:
6045817729095966c338615a8a791d2dbf774fc034efjiabin                        mSurroundFormats.insert(format);
604607ac114c3965e16fe523f88c913e701602604589Phil Burk                    default:
604707ac114c3965e16fe523f88c913e701602604589Phil Burk                        break;
604807ac114c3965e16fe523f88c913e701602604589Phil Burk                }
604909bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            }
605009bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        }
605109bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    }
60520709b0aba2adb719d347341ff58441347a1c1582Phil Burk}
60530709b0aba2adb719d347341ff58441347a1c1582Phil Burk
60540709b0aba2adb719d347341ff58441347a1c1582Phil Burk// Modify the list of channel masks supported.
60550709b0aba2adb719d347341ff58441347a1c1582Phil Burkvoid AudioPolicyManager::filterSurroundChannelMasks(ChannelsVector *channelMasksPtr) {
60560709b0aba2adb719d347341ff58441347a1c1582Phil Burk    ChannelsVector &channelMasks = *channelMasksPtr;
60570709b0aba2adb719d347341ff58441347a1c1582Phil Burk    audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
60580709b0aba2adb719d347341ff58441347a1c1582Phil Burk            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
60590709b0aba2adb719d347341ff58441347a1c1582Phil Burk
60600709b0aba2adb719d347341ff58441347a1c1582Phil Burk    // If NEVER, then remove support for channelMasks > stereo.
60610709b0aba2adb719d347341ff58441347a1c1582Phil Burk    if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
60620709b0aba2adb719d347341ff58441347a1c1582Phil Burk        for (size_t maskIndex = 0; maskIndex < channelMasks.size(); ) {
60630709b0aba2adb719d347341ff58441347a1c1582Phil Burk            audio_channel_mask_t channelMask = channelMasks[maskIndex];
60640709b0aba2adb719d347341ff58441347a1c1582Phil Burk            if (channelMask & ~AUDIO_CHANNEL_OUT_STEREO) {
60650709b0aba2adb719d347341ff58441347a1c1582Phil Burk                ALOGI("%s: force NEVER, so remove channelMask 0x%08x", __FUNCTION__, channelMask);
60660709b0aba2adb719d347341ff58441347a1c1582Phil Burk                channelMasks.removeAt(maskIndex);
60670709b0aba2adb719d347341ff58441347a1c1582Phil Burk            } else {
60680709b0aba2adb719d347341ff58441347a1c1582Phil Burk                maskIndex++;
60690709b0aba2adb719d347341ff58441347a1c1582Phil Burk            }
60700709b0aba2adb719d347341ff58441347a1c1582Phil Burk        }
6071817729095966c338615a8a791d2dbf774fc034efjiabin    // If ALWAYS or MANUAL, then make sure we at least support 5.1
6072817729095966c338615a8a791d2dbf774fc034efjiabin    } else if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS
6073817729095966c338615a8a791d2dbf774fc034efjiabin            || forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
60740709b0aba2adb719d347341ff58441347a1c1582Phil Burk        bool supports5dot1 = false;
60750709b0aba2adb719d347341ff58441347a1c1582Phil Burk        // Are there any channel masks that can be considered "surround"?
6076cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov        for (audio_channel_mask_t channelMask : channelMasks) {
60770709b0aba2adb719d347341ff58441347a1c1582Phil Burk            if ((channelMask & AUDIO_CHANNEL_OUT_5POINT1) == AUDIO_CHANNEL_OUT_5POINT1) {
60780709b0aba2adb719d347341ff58441347a1c1582Phil Burk                supports5dot1 = true;
60790709b0aba2adb719d347341ff58441347a1c1582Phil Burk                break;
60800709b0aba2adb719d347341ff58441347a1c1582Phil Burk            }
60810709b0aba2adb719d347341ff58441347a1c1582Phil Burk        }
60820709b0aba2adb719d347341ff58441347a1c1582Phil Burk        // If not then add 5.1 support.
60830709b0aba2adb719d347341ff58441347a1c1582Phil Burk        if (!supports5dot1) {
60840709b0aba2adb719d347341ff58441347a1c1582Phil Burk            channelMasks.add(AUDIO_CHANNEL_OUT_5POINT1);
60850709b0aba2adb719d347341ff58441347a1c1582Phil Burk            ALOGI("%s: force ALWAYS, so adding channelMask for 5.1 surround", __FUNCTION__);
60860709b0aba2adb719d347341ff58441347a1c1582Phil Burk        }
608709bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    }
608809bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk}
608909bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
609000eeb32846df81288f12fe4c83e61d7db2842226Phil Burkvoid AudioPolicyManager::updateAudioProfiles(audio_devices_t device,
609100eeb32846df81288f12fe4c83e61d7db2842226Phil Burk                                             audio_io_handle_t ioHandle,
6092112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                             AudioProfileVector &profiles)
6093112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie{
6094112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    String8 reply;
60950709b0aba2adb719d347341ff58441347a1c1582Phil Burk
6096112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    // Format MUST be checked first to update the list of AudioProfile
6097112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    if (profiles.hasDynamicFormat()) {
6098388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov        reply = mpClientInterface->getParameters(
6099388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                ioHandle, String8(AudioParameter::keyStreamSupportedFormats));
6100817729095966c338615a8a791d2dbf774fc034efjiabin        ALOGV("%s: supported formats %d, %s", __FUNCTION__, ioHandle, reply.string());
610162e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent        AudioParameter repliedParameters(reply);
610262e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent        if (repliedParameters.get(
6103388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                String8(AudioParameter::keyStreamSupportedFormats), reply) != NO_ERROR) {
6104112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            ALOGE("%s: failed to retrieve format, bailing out", __FUNCTION__);
6105112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            return;
6106112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        }
610709bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        FormatVector formats = formatsFromString(reply.string());
610800eeb32846df81288f12fe4c83e61d7db2842226Phil Burk        if (device == AUDIO_DEVICE_OUT_HDMI) {
61090709b0aba2adb719d347341ff58441347a1c1582Phil Burk            filterSurroundFormats(&formats);
611000eeb32846df81288f12fe4c83e61d7db2842226Phil Burk        }
611109bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        profiles.setFormats(formats);
6112112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    }
6113112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
6114cf84e596c53d5f85b64665a66ed2ec212ecff618Mikhail Naganov    for (audio_format_t format : profiles.getSupportedFormats()) {
611520eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        ChannelsVector channelMasks;
611620eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        SampleRateVector samplingRates;
6117112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        AudioParameter requestedParameters;
6118388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov        requestedParameters.addInt(String8(AudioParameter::keyFormat), format);
6119112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
6120112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        if (profiles.hasDynamicRateFor(format)) {
6121388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov            reply = mpClientInterface->getParameters(
6122388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                    ioHandle,
6123388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                    requestedParameters.toString() + ";" +
6124388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                    AudioParameter::keyStreamSupportedSamplingRates);
6125112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            ALOGV("%s: supported sampling rates %s", __FUNCTION__, reply.string());
612662e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            AudioParameter repliedParameters(reply);
612762e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            if (repliedParameters.get(
6128388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                    String8(AudioParameter::keyStreamSupportedSamplingRates), reply) == NO_ERROR) {
612962e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent                samplingRates = samplingRatesFromString(reply.string());
6130112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            }
6131112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        }
6132112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        if (profiles.hasDynamicChannelsFor(format)) {
6133112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            reply = mpClientInterface->getParameters(ioHandle,
6134112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                                     requestedParameters.toString() + ";" +
6135388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                                                     AudioParameter::keyStreamSupportedChannels);
6136112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            ALOGV("%s: supported channel masks %s", __FUNCTION__, reply.string());
613762e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            AudioParameter repliedParameters(reply);
613862e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            if (repliedParameters.get(
6139388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                    String8(AudioParameter::keyStreamSupportedChannels), reply) == NO_ERROR) {
614062e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent                channelMasks = channelMasksFromString(reply.string());
61410709b0aba2adb719d347341ff58441347a1c1582Phil Burk                if (device == AUDIO_DEVICE_OUT_HDMI) {
61420709b0aba2adb719d347341ff58441347a1c1582Phil Burk                    filterSurroundChannelMasks(&channelMasks);
61430709b0aba2adb719d347341ff58441347a1c1582Phil Burk                }
6144112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            }
6145112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        }
614620eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        profiles.addProfileFromHal(new AudioProfile(format, channelMasks, samplingRates));
6147112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    }
6148112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie}
6149d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
61501b2a794a27caab3a1320d22b872b04ef73e96555Mikhail Naganov} // namespace android
6151